patch-2.1.8 linux/drivers/char/tty_ioctl.c

Next file: linux/drivers/net/3c501.c
Previous file: linux/drivers/char/serial.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.7/linux/drivers/char/tty_ioctl.c linux/drivers/char/tty_ioctl.c
@@ -62,11 +62,19 @@
 #endif
 		current->state = TASK_INTERRUPTIBLE;
 		if (current->signal & ~current->blocked)
-			break;
+			goto stop_waiting;
 		if (!tty->driver.chars_in_buffer(tty))
 			break;
 		schedule();
 	} while (current->timeout);
+	if (tty->driver.wait_until_sent) {
+		if (current->timeout == -1)
+			timeout = 0;
+		else
+			timeout = current->timeout - jiffies;
+		tty->driver.wait_until_sent(tty, timeout);
+	}
+stop_waiting:
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&tty->write_wait, &wait);
 }
@@ -169,8 +177,11 @@
 	if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer)
 		tty->ldisc.flush_buffer(tty);
 
-	if (opt & TERMIOS_WAIT)
+	if (opt & TERMIOS_WAIT) {
 		tty_wait_until_sent(tty, 0);
+		if (current->signal & ~current->blocked)
+			return -EINTR;
+	}
 
 	change_termios(tty, &tmp_termios);
 	return 0;
@@ -371,6 +382,24 @@
 }
 #endif
 
+/*
+ * Send a high priority character to the tty.
+ */
+void send_prio_char(struct tty_struct *tty, char ch)
+{
+	int	was_stopped = tty->stopped;
+
+	if (tty->driver.send_xchar) {
+		tty->driver.send_xchar(tty, ch);
+		return;
+	}
+	if (was_stopped)
+		start_tty(tty);
+	tty->driver.write(tty, 0, &ch, 1);
+	if (was_stopped)
+		stop_tty(tty);
+}
+
 int n_tty_ioctl(struct tty_struct * tty, struct file * file,
 		       unsigned int cmd, unsigned long arg)
 {
@@ -440,13 +469,11 @@
 				break;
 			case TCIOFF:
 				if (STOP_CHAR(tty) != __DISABLED_CHAR)
-					tty->driver.write(tty, 0,
-							  &STOP_CHAR(tty), 1);
+					send_prio_char(tty, STOP_CHAR(tty));
 				break;
 			case TCION:
 				if (START_CHAR(tty) != __DISABLED_CHAR)
-					tty->driver.write(tty, 0,
-							  &START_CHAR(tty), 1);
+					send_prio_char(tty, START_CHAR(tty));
 				break;
 			default:
 				return -EINVAL;
@@ -538,6 +565,8 @@
 			if (retval)
 				return retval;
 			tty_wait_until_sent(tty, 0);
+			if (current->signal & ~current->blocked)
+				return -EINTR;
 			if (!tty->driver.ioctl)
 				return 0;
 			tty->driver.ioctl(tty, file, cmd, arg);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov