jim@haring.UUCP (04/07/84)
Subject: Two fixes for pseudo-ttys
Index: sys/sys/tty_pty.c 4.2BSD
Description:
1) When the slave end of a pseudo-tty closes, the controlling
side is not informed if it is already trying to read from
the device.
2) As it says in the manual, it should be but isn't possible to
send an end-of-file to the slave side by the controlling side
doing a 0-length write in TIOCREMOTE mode.
Repeat-By:
1) The following short program may or may not cause the parent to
wait forever in the read(), depending on whether it gets there
before the child exits. It is always possible to put a sleep()
in the child process before the exit to ensure the parent gets
to read.
main()
{
switch(fork()){
case -1:
perror("fork");
break;
case 0:
child();
/*NOTREACHED*/
default:
parent();
/*NOTREACHED*/
}
exit(1);
}
child()
{
register int fd;
if((fd = open("/dev/ttyp4", 1)) == -1){
perror("/dev/ttyp4");
exit(1);
}
(void) write(fd, "Hello world\n", 12);
exit(0);
}
parent()
{
register int fd, n;
char buf[100];
if((fd = open("/dev/ptyp4", 2)) == -1){
perror("/dev/ptyp4");
exit(1);
}
while((n = read(fd, buf, sizeof(buf))) > 0)
(void) write(1, buf, n);
if(n == -1)
perror("read");
else
printf("EOF");
exit(0);
}
2) Typing EOF to a process expecting input from a shell window in
EMACS - the process is undisturbed.
Fix:
The following is a diff -c of the original 4.2BSD module with the
current one.
The EOF fix comes from David Rosenthal, David.Rosenthal@CMU-CS-A.ARPA
*** sys.gen/sys/tty_pty.c Tue Mar 27 15:12:08 1984
--- sys/sys/tty_pty.c Sun Apr 1 20:42:26 1984
***************
*** 78,83
tp = &pt_tty[minor(dev)];
(*linesw[tp->t_line].l_close)(tp);
ttyclose(tp);
}
ptsread(dev, uio)
--- 78,84 -----
tp = &pt_tty[minor(dev)];
(*linesw[tp->t_line].l_close)(tp);
ttyclose(tp);
+ ptcwakeup(tp);
}
ptsread(dev, uio)
***************
*** 236,242
error = ureadc(0, uio);
}
while (tp->t_outq.c_cc == 0 || (tp->t_state&TS_TTSTOP)) {
! if (pti->pt_flags&PF_NBIO)
return (EWOULDBLOCK);
sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI);
}
--- 237,243 -----
error = ureadc(0, uio);
}
while (tp->t_outq.c_cc == 0 || (tp->t_state&TS_TTSTOP)) {
! if (((tp->t_state&TS_CARR_ON) == 0) || (pti->pt_flags&PF_NBIO))
return (EWOULDBLOCK);
sleep((caddr_t)&tp->t_outq.c_cf, TTIPRI);
}
***************
*** 337,342
break;
iov = uio->uio_iov;
if (iov->iov_len == 0) {
uio->uio_iovcnt--;
uio->uio_iov++;
if (uio->uio_iovcnt < 0)
--- 338,349 -----
break;
iov = uio->uio_iov;
if (iov->iov_len == 0) {
+ while((pti->pt_flags&PF_REMOTE) && tp->t_rawq.c_cc != 0)
+ sleep((caddr_t)&tp->t_rawq.c_cf, TTIPRI);
+ if(pti->pt_flags&PF_REMOTE){
+ (void) putc(0, &tp->t_rawq);
+ wakeup((caddr_t)&tp->t_rawq);
+ }
uio->uio_iovcnt--;
uio->uio_iov++;
if (uio->uio_iovcnt < 0)ellis@flairvax.UUCP (Michael Ellis) (07/17/84)
In april, jim@haring sent out a fix to tty_pty.c (article 235@haring) to
correct slave-end tty close snafus, as well as the awful EOF problem.
I finally got around to installing his fixes to tty_pty.c, but was
suspicious that his original article had been truncated when I noticed how
abruptly it ended, as below:
--- 338,349 -----
break;
iov = uio->uio_iov;
if (iov->iov_len == 0) {
+ while((pti->pt_flags&PF_REMOTE) && tp->t_rawq.c_cc != 0)
+ sleep((caddr_t)&tp->t_rawq.c_cf, TTIPRI);
+ if(pti->pt_flags&PF_REMOTE){
+ (void) putc(0, &tp->t_rawq);
+ wakeup((caddr_t)&tp->t_rawq);
+ }
uio->uio_iovcnt--;
uio->uio_iov++;
if (uio->uio_iovcnt < 0)
<-end of article "235@haring"
Furthermore, installing the fix as received resulted in awful screwups
to most programs that depend on pty's, though the EOF problem indeed
was cured.
Can anybody verify that we have indeed lost a portion of Jim's article?
If so, can anybody supply the correct fix?
-michael