bug in 4.2 ptys stuff. Weird results when programs are swapped.
Keith Packard
keithp at azure.UUCP
Fri Oct 19 06:35:31 AEST 1984
I found an interesting bug in the pty controller driver. A program
hanging on a read from the controlling side of a pty gets swapped out.
When this program is swapped back in, it continues the wait *but* when
it successfully reads from the pty, processes the data and reads
again, read returns -1 instead of hanging on the read. Note that
the data is being fed to this program from a sequence of other
programs which write out a small amount of text to the other end
of the pty and close the pty. (Actually my cd is aliased to:
'cd \!*; echo $cwd > /dev/ttypf' but the problem even occurs if
the process writing to the device exits as in cp)
Here is the source text for the faulty program:
/*
* pty.c read from pty, write to stdout.
* good for fixed pipes. writes name of
* pty to file specified by first argument, stdin default.
*/
# include <sys/file.h>
# include <sgtty.h>
# include <signal.h>
char buffer[4096];
int named = 2;
int off = 0;
char pname[] = "/dev/ptypf";
char tname[] = "/dev/ttypf\n";
char devName[] = "0123456789abcdef";
main (argc, argv)
char **argv;
{
register int fd, len, count;
char nbuf[15];
if (argc == 2) {
named = open (argv[1], O_WRONLY|O_TRUNC|O_CREAT, 0600);
if (named == -1) {
write (2, "could not access file\n", 22);
_exit (1);
}
} else {
write (2, "usage: pty file\n");
_exit (2);
}
fd = openPty();
if (fd < 0)
_exit (1);
if (fork())
_exit (0);
ioctl (fd, FIONBIO, &off);
close (named);
close (0);
close (2);
for (;;) {
len = read (fd, buffer, 4096);
if (len > 0) {
if (buffer[0] == '#')
_exit();
if (write (1, buffer, len) == -1)
_exit();
} else {
extern int errno;
printf ("len was: %d\n", len);
printf ("error was: %d\n", errno);
perror ("error name on write");
exit (1);
}
}
}
# define DEVINDEX 9
openPty ()
{
register int fd;
register int dev;
dev = 16;
do {
if (dev == 0)
return -1;
pname [DEVINDEX] = devName [--dev];
} while ((fd = open (pname, 2)) == -1);
tname [DEVINDEX] = devName [dev];
write (named, tname, sizeof (tname) - 1);
return fd;
}
To repeat:
cc -o pty pty.c
pty foo > outputfile
set pty=`cat foo`
cp /etc/motd $pty
wait until pty is swapped
cp /etc/motd $pty
and cat the outputfile.
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list