[net.unix] Zombies, SMC BASIC, and SIGCLD?

sewilco@mecc.UUCP (Scot E. Wilcoxon) (02/02/86)

Anyone know any tricks to prevent zombies from the child's end?

SMC BASIC seems to use a pipe to the print spooling program to
send to the printers.  But each printout is leaving a zombie
process afterward.  I've tried the attached program to stop
zombies from being created, but SMC BASIC must be blindly
resetting all signals, as zombies still appear.  The problem
was appearing both with the XENIX lpr and continues with the
spooler which I've replaced lpr with.

The gory details follow, followed by nochild.c (I resisted the
temptation of justly naming it eunuch.c):

I'm running SMC BASIC (now supported by Concept Omega Corp?)
under XENIX 3.0 (Lisa Priam version).  It is being executed
with the command
	/usr/osi/manager/nochild /usr/lib/basic/basic $tty /tmp/ipl$tty
While the lpr is running, it shows in "ps -ef" as 'lpr'.
After the lpr ends, it shows in "ps -ef" as '<defunct>'.
One <defunct> (zombie process) appears for each call to lpr, with
same process number as lpr, and correct tty as controlling terminal.
Eventually, of course, the tty's process limit is reached.  Sometimes
the entire system's limit is reached (Nope, I can't change the size
of the table..that's not a solution anyway).

The "nochild" program sets "signal(SIGCLD,SIG_IGN)", which according
to the manual causes ignoring of chils status and will not cause
zombies.  Exec page says signal should propagate across exec.
I must assume SMC BASIC is blindly resetting the signal.  Concept
Omega says they no longer have any versions for Lisa, and I probably
have the only version (can anyone help me find signal() calls in
binary?).  Open Systems, the distributor, can't help either.

The only bright spot I've found is from BASIC's "SYSTEM" statement.
If I execute any UNIX program (ie, 1000 SYSTEM "sleep 1"), all the
zombies disappear.  I can't do SYSTEM routinely because printouts
are done by programs under many situations and keyboard input goes
out to the sh(1) used by SYSTEM while SYSTEM is running.

Yes, I do know the zombies are probably caused by SMC BASIC not doing
a wait() to get the status of the lpr child.  That's the only reason
(which I know of) for zombies to appear.  I don't know why SMC didn't
do it the right way.

For completeness, here's nochild.c:

/*	nochild - execute while ignoring signal "Death of a child"
 *	Author:	Scot E. Wilcoxon, MECC	86/01/30 mecc!sewilco
 *
 *	Program is dependent upon XENIX 3.0, as SIGCLD may disappear
 *	in future versions of XENIX.
 *
 *	Format of Call:
 *
 *	nochild command [args]
 *
 *		command - command to execute
 *		[args] - optional arguments
 *
*/

#include <stdio.h>
#include <signal.h>

extern	errno;

#ifndef	void
typedef	int	void;	/* XENIX 3.0 void definition not usable */
#endif

main(argc, argv)
int	argc;
char	**argv;
{

	if ( argc < 2 ) {
		(void)printf("Usage: %s command [args]\n",argv[0]);
		(void)exit(1);
	}

	(void)signal(SIGCLD,SIG_IGN);	/* ignore status of children */
	
	(void)execvp( argv[1], &argv[1] ); /* execute desired command */
	(void)exit(1);
}
-- 

Scot E. Wilcoxon  Minn. Ed. Comp. Corp.            quest!mecc!sewilco
45 03 N / 93 15 W   (612)481-3507 {ihnp4,mgnetp}!dicomed!mecc!sewilco