brucee@runx.ips.oz (Bruce Evans) (10/27/88)
In fs/pipe.c/unpause() there are 2 unrelated bugs with similar symptoms. (1) The open mode is used for canceling i/o and not the mode of the currently suspended operation. This only matters when the open mode is read + write, resulting in both reads and writes on the suspended device being canceled, and another process has i/o suspended on the same device. I cannot think of a good way to duplicate this at the moment. The bug showed up while I was running my version of "term" with the ttys open in mode 2 (from 1.3c init.c but not 1.2). (2) The device switch is bypassed. This results in i/o on the wrong device being canceled when the device is /dev/tty corresponding to /dev/tty1 (/dev/tty0 gets canceled). Repeat by: cat /dev/tty # while logged onto /dev/tty1 and hit SIGINT. This freezes tty0 as well as messing up tty1. Then SIGINT on tty0 unfreezes tty0 and freezes tty1. Finally, killing the login on tty1 freezes the system. #! /bin/sh # Contents: pipe.c.cdif # Wrapped by sys@besplex on Thu Oct 27 05:09:26 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'pipe.c.cdif' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pipe.c.cdif'\" else echo shar: Extracting \"'pipe.c.cdif'\" \(736 characters\) sed "s/^X//" >'pipe.c.cdif' <<'END_OF_FILE' X*** /user/sys/fs/pipe.c Wed Aug 3 21:05:15 1988 X--- pipe.c Wed Oct 26 21:08:12 1988 X*************** X*** 23,24 **** X--- 23,25 ---- X #include "type.h" X+ #include "dev.h" X #include "file.h" X*************** X*** 247,251 **** X mess.PROC_NR = proc_nr; X! mess.COUNT = f->filp_mode; /* tell kernel whether R or W */ X! mess.m_type = CANCEL; X! rw_dev(task, &mess); X revive(proc_nr, EINTR); /* signal interrupted call */ X--- 248,253 ---- X mess.PROC_NR = proc_nr; X! /* Tell kernel whether R or W. Mode is from current call, not open. */ X! mess.COUNT = (rfp->fp_fd & BYTE) == READ ? R_BIT : W_BIT; X! mess.m_type = CANCEL; X! (*dmap[(dev >> MAJOR) & BYTE].dmap_rw)(task, &mess); X revive(proc_nr, EINTR); /* signal interrupted call */ END_OF_FILE if test 736 -ne `wc -c <'pipe.c.cdif'`; then echo shar: \"'pipe.c.cdif'\" unpacked with wrong size! fi # end of 'pipe.c.cdif' fi echo shar: End of shell archive. exit 0 Bruce Evans Internet: brucee@runx.ips.oz.au UUCP: uunet!runx.ips.oz.au!brucee