[comp.os.minix] Minix 1.5.10 signal bug

brucee@runxtsa.runx.oz.au (Bruce Evans) (06/04/90)

In article <90151.170153SA44@LIVERPOOL.AC.UK> SA44@LIVERPOOL.AC.UK (Kevin Maguire) writes:
> - pressed INT no joy
> - pressed INT again... no joy
> - banged INT a few times and waited????? no joy
> - CTRL-ALT-F10 to SIGKILL all processes (I don't use half measures ;-))
> - still no joy even SIGKILL didn't work!!!!!!
> - just kept banging the INT key... after a few seconds the ST just reset??

This happens when a process leader has exited but some of its children are
still alive. New shells do not get a process group. The bug used to be
exercised by cron. Enclosed is a simple program to demonstrate the bug, and
relevant extracts from my old bug reports. The program must be run with
"exec ./sigbug" and not "./sigbug" so it becomes the process group leader.

#! /bin/sh
# Contents:  sigbug.c cron.notes
# Wrapped by src@besplex on Mon Jun  4 22:44:56 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sigbug.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sigbug.c'\"
else
echo shar: Extracting \"'sigbug.c'\" \(824 characters\)
sed "s/^X//" >'sigbug.c' <<'END_OF_FILE'
X#include <stdio.h>
X
Xmain()
X{
X    int pid;
X
X    switch (pid = fork())
X    {
X    case -1:
X	perror("cannot fork");
X	exit(1);
X    case 0:
X	break;
X    default:
X	printf("Parent closing stdio and exiting.\n");
X	printf("Use kill -1 %d to kill the child.\n\n", pid);
X	fclose(stdin);
X	fclose(stdout);
X	fclose(stderr);
X	exit(0);
X    }
X    sleep(2);
X    printf("\n\nChild sleeping for 1 hour.\n");
X    printf("If the parent was a process group leader, the child has lost\n");
X    printf("its process group, so is immune to signals from the keyboard.\n");
X    printf("Is this right?\n\n");
X    printf("While the child holds the tty open, new processes opening it\n");
X    printf("are not given a process group, so are immune to signals from\n");
X    printf("the keyboard.\n");
X    printf("This cannot be right!\n\n");
X    sleep(3600);
X}
END_OF_FILE
if test 824 -ne `wc -c <'sigbug.c'`; then
    echo shar: \"'sigbug.c'\" unpacked with wrong size!
fi
# end of 'sigbug.c'
fi
if test -f 'cron.notes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cron.notes'\"
else
echo shar: Extracting \"'cron.notes'\" \(2969 characters\)
sed "s/^X//" >'cron.notes' <<'END_OF_FILE'
Xcommands/cron.c, fs/device.c: (A TANGLED WEB)
X	I changed cron around 1.4.5 to fclose the standard streams
X	instead of closing their fileno()s, except fclose(stdout) is
X	commented out because later code does a printf. The fcloses
X	were correct for the old cron but don't do what is wanted now.
X	The code appears to be re-plumbing stdio so children get
X	/dev/null for input and LOGFILE for output and error output.
X	Stdio should not be trusted to do this. It would be safest for
X	cron not to use stdio at all. It doesn't use it for much and a
X	lot of space would be saved (but watch out for the new ctime -
X	apart from being big itself, it uses sprintf which drags in
X	stdio). Another way (which also saves space) is to require cron
X	to be started with
X
X		cron < /dev/null > LOGFILE 2>&1
X
X	The printf I was worried about may actually be OK. It should
X	print to LOGFILE if stdout is fclosed at the start. So why do
X	other printfs go to cronlog?  Cronlog is likely to be identical
X	to stdout but that is hard to guarantee.
X
X	The killer bug in this web was that signal chars stopped
X	working when the version of cron without fclose(stdout) was
X	run. The process group handling has been broken by the line at
X	the start of dev_open(). Now the dmap open routine is not
X	called if the device is already open. Without the fclose,
X	/dev/tty0 stayed open. When the process group leader (the shell
X	interpreting /etc/rc I think) exits, the process group
X	variables in FS and TTY are cleared.  New process groups are
X	supposed to be attached by the dmap open (tty_open()), but that
X	never gets called.
X
X	I don't know what the correct behaviour for process groups is.
X	It is strange to disconnect the cron attached to /dev/tty0 just
X	because the leader dies.  This cuts it off from signal chars to
X	start with. Then the next process to open the device becomes
X	the leader. This is a race. Maybe signal characters should not
X	be related to process groups, and cause signals to all
X	processes which have the tty open.
X
Xcommands/cron.c, version 1.5.6:
X	There are too many changes for me to understand quickly, but
X	the unportable combination of closes, fopens and opens is
X	back in full (it wasn't quite gone in 1.5.6). Why not open
X	everything on the command line in /etc/rc? Cron will probably
X	still tickle the pgrp bug in FS. I put in a hack around 1.5.2
X	(of not closing everything) to try to get around this.  If the
X	files are opened in /etc/rc, there will be no ttys involved and
X	the bug is sure to be avoided. It may also be worth putting the
X	"&" on the command line, if this avoids memory fragmentation.
X	BTW init might do update to save some more room (and avoid
X	update getting killed by Ctrl-F9 :-) and init might be taken
X	out of the system by doing an execl("/etc/init", ...)
X	somewhere. Alternatively, the system init might be tiny and do
X	little more that execl("/etc/init").  This saves people who
X	want complicated login handling from having to change the
X	system.
END_OF_FILE
if test 2969 -ne `wc -c <'cron.notes'`; then
    echo shar: \"'cron.notes'\" unpacked with wrong size!
fi
# end of 'cron.notes'
fi
echo shar: End of shell archive.
exit 0