Proper exit handling

Wonderly gregg at ihlpb.ATT.COM
Tue Mar 28 14:14:00 AEST 1989


>From article <18832 at adm.BRL.MIL>, by Kemp at DOCKMASTER.NCSC.MIL:
>    Does anyone know of a bulletproof method of installing an exit
> handling routine that is guaranteed to be called when a process
> terminates?
> ... 
>    The handler just sets a global flag and returns; the main program
> checks the flag and takes appropriate action:
> 
>  void onterm(sig)
>  int sig;
>  {
>           done = 1;
>           if (sig == SIGINT) done++;

You might add

            signal (sig, SIG_IGN);

here in case the user bangs on the INTR/QUIT keys several times when the
system is busy.

>  }
> 
> p.s.  Can anyone tell me where in TFM to find documentation on SIGTERM
> (the software termination signal)?  It would be nice if this were sent
> by exit() TO the terminating process, but I assume that it is just
> another of the signals that causes the process to terminate.  SIGNAL(3)
> doesn't say anything about it except to list its value.

SIGTERM is the default signal for kill(1) and, more interestingly, it is
the signal sent to all processes, by the kernal, when a shutdown is
requested.  It means what it says, TERMinate.  The SIGTERM handler in
daemon processes like cron(1), uucp(1), and other behind the scenes
programs cleans up everything that should not be present for the program
to start back up normally.  This is typically lock files like the tty
lock files that uucp(1) creates.  SIGHUP of course is delivered to processes
when the terminal that they are associated with 'loses carrier'.  This
differentiation while not necessary in most cases may be and since these
are two distinct events, it is convienent to convey them as such.

I typically cover the kinds of problems that you are talking about with
a segment of code such as this

	{
		int i;
		extern int handler();

		for (i=1; i < NSIG; ++i)
			signal (i, handler);

	#ifdef	SIGCLD
		signal (SIGCLD, SIG_DFL);
	#endif

	#ifndef	SIGCHLD
		signal (SIGCHLD, SIG_DFL);
	#endif

	}

For the other special signals which are in BSD (SIGTTIN etc) you may or may
not need special settings for those.

If you have problems with an application core dumping because of coding
errors, those are usually the times when you would like to use a handler
such as

	handler(sig)
		int sig;
	{
		int pid;

		switch (sig) {
			case SIGBUS:
			case SIGSEGV:
			case SIGFPE:
			case SIGEMT:
			case SIGILL:
				if ((pid = fork()) == 0) {
					chdir ("/tmp");
					setuid (getuid());
					setgid (getgid());
					return;
				}
				wait (0);
				/*  FALL THROUGH to clean up code.  */

			default:
				/*  Do something to clean up terminal settings and such */

		}
	}

Which will (if instructions can be restarted) drop a core in /tmp which
might help to debug your problem, while still cleaning up the terminal
and other things.  I use this frequently and find it very useful.

-- 
Gregg Wonderly                             DOMAIN: gregg at ihlpb.att.com
AT&T Bell Laboratories                     UUCP:   att!ihlpb!gregg



More information about the Comp.unix.questions mailing list