[net.bugs.4bsd] Strange behaviour of select

brett@wjvax.UUCP (Brett Galloway) (09/27/85)

The following program illustrates what may be a bug in the select() call
(and the underlying kernel code):

----------- Start of file -----------------
#include	<stdio.h>

main(argc,argv)
{
	char	buf[32];
	int	readfds;
	int	i;

	while(1) {

		printf("Type something: ");
		fflush(stdout);

		readfds=1;
		if(select(1,&readfds,0,0,0) > 0) {
			gets(buf);
			printf("'%s' typed.\n",buf);
			if(buf[0] == '~')
				break;
		}
	}
}

------------ End of file -------------

When this is executed, and ^Z is typed at the prompt (i.e. while the
program is sitting in the select()), the program does stop, but then
its status changes.  The csh detects a stopped state, but the program's
process in fact exits.  This bug is (seemingly) intermittent.  I have
other programs which sit on select()'s for input which may or may not
die when a SIGTSTP signal is sent to them.

Sending SIGTSTP instead of typing ^Z may also cause the process to die.
Sending SIGTSTP to a process on a pipe, however, never caused it to
die, so I assume that this problem involves some interaction with the
(new) tty driver.

Does anyone out there know what is happening?  If so, I would appreciate
hearing about it.

chris@umcp-cs.UUCP (Chris Torek) (09/30/85)

This was fixed long ago; here once again is the correct code from
/sys/sys/sys_generic.c$selwakeup():

selwakeup(p, coll)
	register struct proc *p;
	int coll;
{

	if (coll) {
		nselcoll++;
		wakeup((caddr_t)&selwait);
	}
	if (p) {
		int s = spl6();
		if (p->p_wchan == (caddr_t)&selwait) {
			if (p->p_stat == SSLEEP)
				setrun(p);
			else
				unsleep(p);
		}
		else if (p->p_flag & SSEL)
			p->p_flag &= ~SSEL;
		splx(s);
	}
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

shannon@sun.uucp (Bill Shannon) (10/01/85)

> When this [sample program] is executed, and ^Z is typed at the prompt (i.e. while the
> program is sitting in the select()), the program does stop, but then
> its status changes.  The csh detects a stopped state, but the program's
> process in fact exits.  This bug is (seemingly) intermittent.  I have
> other programs which sit on select()'s for input which may or may not
> die when a SIGTSTP signal is sent to them.
> 
> Does anyone out there know what is happening?  If so, I would appreciate
> hearing about it.

In sys_generic.c/selwakeup(), change the call to setrun(p) to unselect(p).
selwakeup() should not have started the process running without checking
to see if it was stopped.  By starting the process running, it ended up
actually getting the SIGTSTP signal and dieing, something that can not
normally happen.

					Bill Shannon
					Sun Microsystems, Inc.