Re: Bug in pty re-usage

Thorsten Kuehnemann (thorsten@actis.de)
Wed, 25 Sep 1996 01:41:27 +0200


In linux.dev.kernel Olaf Titz <olaf@bigred.inka.de> wrote:
>If a master pty is closed and then re-opened while the client side
>remains open, the second open of the master side will succeed. I think
>this is incorrect behaviour. It can lead to a situation where a new
>master allocates the same pty and ends up with two slaves on the same
>slave device.

noone answered to that problem in the last five weeks, but at least
Thomas Roessler <roessler@sobolev.rhein.de> and i have problems with
linux-2.0.X pty's too:

We found that Linux 2 breaks some pty-programs, e.g. xconsole, script, screen,
old X11R6 xterms, some pty-programs work (in.telnetd).

The difference: If you read from the master while there is no slave
opened waiting for him you get EIO (I/O Error).

1. start xterm
2. start "xclock &" in that xterm
3. exit that xterm
4. start "script"

script returns immediately!

This program shows the problem:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

void main (int ac, char *av[])
{
int fd;
int rc;
char ch;

if (ac != 2)
return;

if ((fd = open (av[1], O_RDWR)) < 0) {
perror ("open");
return;
}

rc = read (fd, &ch, 1);

if (rc == -1)
perror ("read");
else
printf ("read: rc=%d\n", rc);
}

Run it with the name of a really free master pty, it works (it sleeps in
read). With a pty having only an old slave running the open succeeds(!)
and the read returns EIO. This is a serious error.

With Linux 1.2.13 the open succeeds(bad) but the read sleeps(acceptable for
the user).

The bad hack would be to ensure in all applications that the slave is
opened before the master is read (i "repaired" the program script for
testing with a "sleep (2);" right before the first read from the master).

The real solution (i agree with olaf) would be to forbid an open of a
master-pty while anyone has an open filedescriptor at the slave-side.

I think this would be a change in pty_open() of
/usr/src/linux/drivers/char/pty.c (check link count of corresponding
slave-pty and return EBUSY if != 0) but i am not a kernel guru :-(

Thorsten

PS: Are there any POSIX hints about that?