Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: Add EXTPROC support for LINEMODE

This patch is against the 2.6.34 source.

Paraphrased from the 1989 BSD patch by David Borman @ cray.com:

These are the changes needed for the kernel to support
LINEMODE in the server.

There is a new bit in the termios local flag word, EXTPROC.
When this bit is set, several aspects of the terminal driver
are disabled. Input line editing, character echo, and mapping
of signals are all disabled. This allows the telnetd to turn
off these functions when in linemode, but still keep track of
what state the user wants the terminal to be in.

New ioctl:
TIOCSIG Generate a signal to processes in the
current process group of the pty.

There is a new mode for packet driver, the TIOCPKT_IOCTL bit.
When packet mode is turned on in the pty, and the EXTPROC bit
is set, then whenever the state of the pty is changed, the
next read on the master side of the pty will have the TIOCPKT_IOCTL
bit set. This allows the process on the server side of the pty
to know when the state of the terminal has changed; it can then
issue the appropriate ioctl to retrieve the new state.

Since the original BSD patches accompanied the source code for telnet
I've left that reference here, but obviously the feature is useful for
any remote terminal protocol, including ssh.

The corresponding feature has existed in the BSD tty driver since 1989.
For historical reference, a good copy of the relevant files can be found
here:

http://anonsvn.mit.edu/viewvc/krb5/trunk/src/appl/telnet/?pathrev=17741

Signed-off-by: Howard Chu <hyc@symas.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>


authored by

hyc@symas.com and committed by
Greg Kroah-Hartman
26df6d13 a3c8ed69

+101 -10
+2
arch/alpha/include/asm/ioctls.h
··· 80 80 # define TIOCPKT_START 8 81 81 # define TIOCPKT_NOSTOP 16 82 82 # define TIOCPKT_DOSTOP 32 83 + # define TIOCPKT_IOCTL 64 83 84 84 85 85 86 #define TIOCNOTTY 0x5422 ··· 92 91 #define TIOCGSID 0x5429 /* Return the session ID of FD */ 93 92 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 94 93 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 94 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 95 95 96 96 #define TIOCSERCONFIG 0x5453 97 97 #define TIOCSERGWILD 0x5454
+1
arch/alpha/include/asm/termbits.h
··· 180 180 #define FLUSHO 0x00800000 181 181 #define PENDIN 0x20000000 182 182 #define IEXTEN 0x00000400 183 + #define EXTPROC 0x10000000 183 184 184 185 /* Values for the ACTION argument to `tcflow'. */ 185 186 #define TCOOFF 0
+2
arch/arm/include/asm/ioctls.h
··· 52 52 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 53 53 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 54 54 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 55 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 55 56 56 57 #define TIOCGRS485 0x542E 57 58 #define TIOCSRS485 0x542F ··· 82 81 #define TIOCPKT_START 8 83 82 #define TIOCPKT_NOSTOP 16 84 83 #define TIOCPKT_DOSTOP 32 84 + #define TIOCPKT_IOCTL 64 85 85 86 86 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 87 87
+1
arch/arm/include/asm/termbits.h
··· 177 177 #define FLUSHO 0010000 178 178 #define PENDIN 0040000 179 179 #define IEXTEN 0100000 180 + #define EXTPROC 0200000 180 181 181 182 /* tcflow() and TCXONC use these */ 182 183 #define TCOOFF 0
+2
arch/avr32/include/asm/ioctls.h
··· 53 53 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 54 54 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 55 55 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 56 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 56 57 57 58 #define TIOCGRS485 0x542E 58 59 #define TIOCSRS485 0x542F ··· 83 82 #define TIOCPKT_START 8 84 83 #define TIOCPKT_NOSTOP 16 85 84 #define TIOCPKT_DOSTOP 32 85 + #define TIOCPKT_IOCTL 64 86 86 87 87 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 88 88
+1
arch/avr32/include/asm/termbits.h
··· 175 175 #define FLUSHO 0010000 176 176 #define PENDIN 0040000 177 177 #define IEXTEN 0100000 178 + #define EXTPROC 0200000 178 179 179 180 /* tcflow() and TCXONC use these */ 180 181 #define TCOOFF 0
+2
arch/cris/include/asm/ioctls.h
··· 54 54 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 55 55 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 56 56 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 57 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 57 58 58 59 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 59 60 #define FIOCLEX 0x5451 ··· 86 85 #define TIOCPKT_START 8 87 86 #define TIOCPKT_NOSTOP 16 88 87 #define TIOCPKT_DOSTOP 32 88 + #define TIOCPKT_IOCTL 64 89 89 90 90 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 91 91
+1
arch/cris/include/asm/termbits.h
··· 214 214 #define FLUSHO 0010000 215 215 #define PENDIN 0040000 216 216 #define IEXTEN 0100000 217 + #define EXTPROC 0200000 217 218 218 219 /* tcflow() and TCXONC use these */ 219 220 #define TCOOFF 0
+2
arch/frv/include/asm/ioctls.h
··· 53 53 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 54 54 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 55 55 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 56 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 56 57 57 58 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 58 59 #define FIOCLEX 0x5451 ··· 80 79 #define TIOCPKT_START 8 81 80 #define TIOCPKT_NOSTOP 16 82 81 #define TIOCPKT_DOSTOP 32 82 + #define TIOCPKT_IOCTL 64 83 83 84 84 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 85 85
+1
arch/frv/include/asm/termbits.h
··· 180 180 #define FLUSHO 0010000 181 181 #define PENDIN 0040000 182 182 #define IEXTEN 0100000 183 + #define EXTPROC 0200000 183 184 184 185 185 186 /* tcflow() and TCXONC use these */
+2
arch/h8300/include/asm/ioctls.h
··· 53 53 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 54 54 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 55 55 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 56 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 56 57 57 58 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 58 59 #define FIOCLEX 0x5451 ··· 80 79 #define TIOCPKT_START 8 81 80 #define TIOCPKT_NOSTOP 16 82 81 #define TIOCPKT_DOSTOP 32 82 + #define TIOCPKT_IOCTL 64 83 83 84 84 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 85 85
+1
arch/h8300/include/asm/termbits.h
··· 179 179 #define FLUSHO 0010000 180 180 #define PENDIN 0040000 181 181 #define IEXTEN 0100000 182 + #define EXTPROC 0200000 182 183 183 184 184 185 /* tcflow() and TCXONC use these */
+2
arch/ia64/include/asm/ioctls.h
··· 59 59 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 60 60 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 61 61 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 62 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 62 63 63 64 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 64 65 #define FIOCLEX 0x5451 ··· 86 85 #define TIOCPKT_START 8 87 86 #define TIOCPKT_NOSTOP 16 88 87 #define TIOCPKT_DOSTOP 32 88 + #define TIOCPKT_IOCTL 64 89 89 90 90 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 91 91
+1
arch/ia64/include/asm/termbits.h
··· 187 187 #define FLUSHO 0010000 188 188 #define PENDIN 0040000 189 189 #define IEXTEN 0100000 190 + #define EXTPROC 0200000 190 191 191 192 /* tcflow() and TCXONC use these */ 192 193 #define TCOOFF 0
+2
arch/m32r/include/asm/ioctls.h
··· 53 53 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 54 54 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 55 55 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 56 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 56 57 57 58 #define FIONCLEX 0x5450 58 59 #define FIOCLEX 0x5451 ··· 80 79 #define TIOCPKT_START 8 81 80 #define TIOCPKT_NOSTOP 16 82 81 #define TIOCPKT_DOSTOP 32 82 + #define TIOCPKT_IOCTL 64 83 83 84 84 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 85 85
+1
arch/m32r/include/asm/termbits.h
··· 179 179 #define FLUSHO 0010000 180 180 #define PENDIN 0040000 181 181 #define IEXTEN 0100000 182 + #define EXTPROC 0200000 182 183 183 184 /* tcflow() and TCXONC use these */ 184 185 #define TCOOFF 0
+2
arch/m68k/include/asm/ioctls.h
··· 52 52 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 53 53 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 54 54 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 55 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 55 56 56 57 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 57 58 #define FIOCLEX 0x5451 ··· 79 78 #define TIOCPKT_START 8 80 79 #define TIOCPKT_NOSTOP 16 81 80 #define TIOCPKT_DOSTOP 32 81 + #define TIOCPKT_IOCTL 64 82 82 83 83 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 84 84
+1
arch/m68k/include/asm/termbits.h
··· 179 179 #define FLUSHO 0010000 180 180 #define PENDIN 0040000 181 181 #define IEXTEN 0100000 182 + #define EXTPROC 0200000 182 183 183 184 184 185 /* tcflow() and TCXONC use these */
+2 -1
arch/mips/include/asm/ioctls.h
··· 41 41 #define TIOCPKT_START 0x08 /* start output */ 42 42 #define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ 43 43 #define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ 44 - /* #define TIOCPKT_IOCTL 0x40 state change of pty driver */ 44 + #define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ 45 45 #define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ 46 46 #define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ 47 47 #define TIOCNOTTY 0x5471 /* void tty association */ ··· 83 83 #define TCSETSF2 _IOW('T', 0x2D, struct termios2) 84 84 #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 85 85 #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ 86 + #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ 86 87 87 88 /* I hope the range from 0x5480 on is free ... */ 88 89 #define TIOCSCTTY 0x5480 /* become controlling tty */
+1
arch/mips/include/asm/termbits.h
··· 203 203 #define PENDIN 0040000 /* Retype pending input (state). */ 204 204 #define TOSTOP 0100000 /* Send SIGTTOU for background output. */ 205 205 #define ITOSTOP TOSTOP 206 + #define EXTPROC 0200000 /* External processing on pty */ 206 207 207 208 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ 208 209 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+2
arch/mn10300/include/asm/ioctls.h
··· 54 54 #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number 55 55 * (of pty-mux device) */ 56 56 #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ 57 + #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ 57 58 58 59 #define FIONCLEX 0x5450 59 60 #define FIOCLEX 0x5451 ··· 81 80 #define TIOCPKT_START 8 82 81 #define TIOCPKT_NOSTOP 16 83 82 #define TIOCPKT_DOSTOP 32 83 + #define TIOCPKT_IOCTL 64 84 84 85 85 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 86 86
+1
arch/mn10300/include/asm/termbits.h
··· 180 180 #define FLUSHO 0010000 181 181 #define PENDIN 0040000 182 182 #define IEXTEN 0100000 183 + #define EXTPROC 0200000 183 184 184 185 /* tcflow() and TCXONC use these */ 185 186 #define TCOOFF 0
+2
arch/parisc/include/asm/ioctls.h
··· 52 52 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 53 53 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 54 54 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 55 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 55 56 56 57 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 57 58 #define FIOCLEX 0x5451 ··· 83 82 #define TIOCPKT_START 8 84 83 #define TIOCPKT_NOSTOP 16 85 84 #define TIOCPKT_DOSTOP 32 85 + #define TIOCPKT_IOCTL 64 86 86 87 87 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 88 88
+1
arch/parisc/include/asm/termbits.h
··· 180 180 #define FLUSHO 0010000 181 181 #define PENDIN 0040000 182 182 #define IEXTEN 0100000 183 + #define EXTPROC 0200000 183 184 184 185 /* tcflow() and TCXONC use these */ 185 186 #define TCOOFF 0
+2
arch/powerpc/include/asm/ioctls.h
··· 80 80 # define TIOCPKT_START 8 81 81 # define TIOCPKT_NOSTOP 16 82 82 # define TIOCPKT_DOSTOP 32 83 + # define TIOCPKT_IOCTL 64 83 84 84 85 85 86 #define TIOCNOTTY 0x5422 ··· 94 93 #define TIOCSRS485 0x542f 95 94 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 96 95 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 96 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 97 97 98 98 #define TIOCSERCONFIG 0x5453 99 99 #define TIOCSERGWILD 0x5454
+1
arch/powerpc/include/asm/termbits.h
··· 189 189 #define FLUSHO 0x00800000 190 190 #define PENDIN 0x20000000 191 191 #define IEXTEN 0x00000400 192 + #define EXTPROC 0x10000000 192 193 193 194 /* Values for the ACTION argument to `tcflow'. */ 194 195 #define TCOOFF 0
+2
arch/s390/include/asm/ioctls.h
··· 60 60 #define TCSETSF2 _IOW('T',0x2D, struct termios2) 61 61 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 62 62 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 63 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 63 64 64 65 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ 65 66 #define FIOCLEX 0x5451 ··· 87 86 #define TIOCPKT_START 8 88 87 #define TIOCPKT_NOSTOP 16 89 88 #define TIOCPKT_DOSTOP 32 89 + #define TIOCPKT_IOCTL 64 90 90 91 91 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 92 92
+2
arch/sh/include/asm/ioctls.h
··· 69 69 # define TIOCPKT_START 8 70 70 # define TIOCPKT_NOSTOP 16 71 71 # define TIOCPKT_DOSTOP 32 72 + # define TIOCPKT_IOCTL 64 72 73 73 74 74 75 #define TIOCNOTTY _IO('T', 34) /* 0x5422 */ ··· 85 84 #define TCSETSF2 _IOW('T', 45, struct termios2) 86 85 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 87 86 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 87 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 88 88 89 89 #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ 90 90 #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
+2
arch/sparc/include/asm/ioctls.h
··· 80 80 /* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ 81 81 #define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */ 82 82 #define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */ 83 + #define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */ 83 84 84 85 /* Little f */ 85 86 #define FIOCLEX _IO('f', 1) ··· 133 132 #define TIOCPKT_START 8 134 133 #define TIOCPKT_NOSTOP 16 135 134 #define TIOCPKT_DOSTOP 32 135 + #define TIOCPKT_IOCTL 64 136 136 137 137 #endif /* !(_ASM_SPARC_IOCTLS_H) */
+1
arch/sparc/include/asm/termbits.h
··· 225 225 #define FLUSHO 0x00002000 226 226 #define PENDIN 0x00004000 227 227 #define IEXTEN 0x00008000 228 + #define EXTPROC 0x00010000 228 229 229 230 /* modem lines */ 230 231 #define TIOCM_LE 0x001
+2
arch/xtensa/include/asm/ioctls.h
··· 81 81 # define TIOCPKT_START 8 82 82 # define TIOCPKT_NOSTOP 16 83 83 # define TIOCPKT_DOSTOP 32 84 + # define TIOCPKT_IOCTL 64 84 85 85 86 86 87 #define TIOCNOTTY _IO('T', 34) ··· 98 97 #define TCSETSF2 _IOW('T', 45, struct termios2) 99 98 #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ 100 99 #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ 100 + #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ 101 101 102 102 #define TIOCSERCONFIG _IO('T', 83) 103 103 #define TIOCSERGWILD _IOR('T', 84, int)
+1
arch/xtensa/include/asm/termbits.h
··· 196 196 #define FLUSHO 0010000 197 197 #define PENDIN 0040000 198 198 #define IEXTEN 0100000 199 + #define EXTPROC 0200000 199 200 200 201 /* tcflow() and TCXONC use these */ 201 202
+14 -3
drivers/char/n_tty.c
··· 1102 1102 if (I_IUCLC(tty) && L_IEXTEN(tty)) 1103 1103 c = tolower(c); 1104 1104 1105 + if (L_EXTPROC(tty)) { 1106 + put_tty_queue(c, tty); 1107 + return; 1108 + } 1109 + 1105 1110 if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && 1106 1111 I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && 1107 1112 c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { ··· 1414 1409 1415 1410 n_tty_set_room(tty); 1416 1411 1417 - if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { 1412 + if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || 1413 + L_EXTPROC(tty)) { 1418 1414 kill_fasync(&tty->fasync, SIGIO, POLL_IN); 1419 1415 if (waitqueue_active(&tty->read_wait)) 1420 1416 wake_up_interruptible(&tty->read_wait); ··· 1591 1585 static inline int input_available_p(struct tty_struct *tty, int amt) 1592 1586 { 1593 1587 tty_flush_to_ldisc(tty); 1594 - if (tty->icanon) { 1588 + if (tty->icanon && !L_EXTPROC(tty)) { 1595 1589 if (tty->canon_data) 1596 1590 return 1; 1597 1591 } else if (tty->read_cnt >= (amt ? amt : 1)) ··· 1638 1632 spin_lock_irqsave(&tty->read_lock, flags); 1639 1633 tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); 1640 1634 tty->read_cnt -= n; 1635 + /* Turn single EOF into zero-length read */ 1636 + if (L_EXTPROC(tty) && tty->icanon && n == 1) { 1637 + if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty)) 1638 + n--; 1639 + } 1641 1640 spin_unlock_irqrestore(&tty->read_lock, flags); 1642 1641 *b += n; 1643 1642 *nr -= n; ··· 1823 1812 nr--; 1824 1813 } 1825 1814 1826 - if (tty->icanon) { 1815 + if (tty->icanon && !L_EXTPROC(tty)) { 1827 1816 /* N.B. avoid overrun if nr == 0 */ 1828 1817 while (nr && tty->read_cnt) { 1829 1818 int eol;
+21
drivers/char/pty.c
··· 171 171 return 0; 172 172 } 173 173 174 + /* Send a signal to the slave */ 175 + static int pty_signal(struct tty_struct *tty, int sig) 176 + { 177 + unsigned long flags; 178 + struct pid *pgrp; 179 + 180 + if (tty->link) { 181 + spin_lock_irqsave(&tty->link->ctrl_lock, flags); 182 + pgrp = get_pid(tty->link->pgrp); 183 + spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); 184 + 185 + kill_pgrp(pgrp, sig, 1); 186 + put_pid(pgrp); 187 + } 188 + return 0; 189 + } 190 + 174 191 static void pty_flush_buffer(struct tty_struct *tty) 175 192 { 176 193 struct tty_struct *to = tty->link; ··· 338 321 switch (cmd) { 339 322 case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ 340 323 return pty_set_lock(tty, (int __user *) arg); 324 + case TIOCSIG: /* Send signal to other side of pty */ 325 + return pty_signal(tty, (int) arg); 341 326 } 342 327 return -ENOIOCTLCMD; 343 328 } ··· 495 476 return pty_set_lock(tty, (int __user *)arg); 496 477 case TIOCGPTN: /* Get PT Number */ 497 478 return put_user(tty->index, (unsigned int __user *)arg); 479 + case TIOCSIG: /* Send signal to other side of pty */ 480 + return pty_signal(tty, (int) arg); 498 481 } 499 482 500 483 return -ENOIOCTLCMD;
+12 -6
drivers/char/tty_ioctl.c
··· 517 517 518 518 /* See if packet mode change of state. */ 519 519 if (tty->link && tty->link->packet) { 520 + int extproc = (old_termios.c_lflag & EXTPROC) | 521 + (tty->termios->c_lflag & EXTPROC); 520 522 int old_flow = ((old_termios.c_iflag & IXON) && 521 523 (old_termios.c_cc[VSTOP] == '\023') && 522 524 (old_termios.c_cc[VSTART] == '\021')); 523 525 int new_flow = (I_IXON(tty) && 524 526 STOP_CHAR(tty) == '\023' && 525 527 START_CHAR(tty) == '\021'); 526 - if (old_flow != new_flow) { 528 + if ((old_flow != new_flow) || extproc) { 527 529 spin_lock_irqsave(&tty->ctrl_lock, flags); 528 - tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); 529 - if (new_flow) 530 - tty->ctrl_status |= TIOCPKT_DOSTOP; 531 - else 532 - tty->ctrl_status |= TIOCPKT_NOSTOP; 530 + if (old_flow != new_flow) { 531 + tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); 532 + if (new_flow) 533 + tty->ctrl_status |= TIOCPKT_DOSTOP; 534 + else 535 + tty->ctrl_status |= TIOCPKT_NOSTOP; 536 + } 537 + if (extproc) 538 + tty->ctrl_status |= TIOCPKT_IOCTL; 533 539 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 534 540 wake_up_interruptible(&tty->link->read_wait); 535 541 }
+1
fs/compat_ioctl.c
··· 969 969 COMPATIBLE_IOCTL(TIOCGPTN) 970 970 COMPATIBLE_IOCTL(TIOCSPTLCK) 971 971 COMPATIBLE_IOCTL(TIOCSERGETLSR) 972 + COMPATIBLE_IOCTL(TIOCSIG) 972 973 #ifdef TCGETS2 973 974 COMPATIBLE_IOCTL(TCGETS2) 974 975 COMPATIBLE_IOCTL(TCSETS2)
+2
include/asm-generic/ioctls.h
··· 69 69 #define TCSETX 0x5433 70 70 #define TCSETXF 0x5434 71 71 #define TCSETXW 0x5435 72 + #define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ 72 73 73 74 #define FIONCLEX 0x5450 74 75 #define FIOCLEX 0x5451 ··· 103 102 #define TIOCPKT_START 8 104 103 #define TIOCPKT_NOSTOP 16 105 104 #define TIOCPKT_DOSTOP 32 105 + #define TIOCPKT_IOCTL 64 106 106 107 107 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 108 108
+1
include/asm-generic/termbits.h
··· 178 178 #define FLUSHO 0010000 179 179 #define PENDIN 0040000 180 180 #define IEXTEN 0100000 181 + #define EXTPROC 0200000 181 182 182 183 /* tcflow() and TCXONC use these */ 183 184 #define TCOOFF 0
+1
include/linux/tty.h
··· 179 179 #define L_FLUSHO(tty) _L_FLAG((tty), FLUSHO) 180 180 #define L_PENDIN(tty) _L_FLAG((tty), PENDIN) 181 181 #define L_IEXTEN(tty) _L_FLAG((tty), IEXTEN) 182 + #define L_EXTPROC(tty) _L_FLAG((tty), EXTPROC) 182 183 183 184 struct device; 184 185 struct signal_struct;