Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

366 Signals Chapter 10


4.3BSD generated theSIGILLsignal. Beforedoing this, the 4.3BSD function unblocked the
signal and reset its disposition toSIG_DFL(terminate withcorefile). This prevented a
process from either ignoring the signal or catching it.
Historically,implementations ofaborthave differed in how they deal with standardI/O
streams. For defensive programming and improved portability, if we want standardI/O
streams to be flushed, we specifically do it beforecallingabort.We do this in theerr_dump
function (Appendix B).
Since most UNIX System implementations oftmpfilecallunlinkimmediately after creating
the file, the ISO C warning about temporary files does not usually concern us.

Example


Figure10.25 shows an implementation of theabortfunction as specified by POSIX.1.
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void
abort(void) /* POSIX-style abort() function */
{
sigset_t mask;
struct sigaction action;

/* Caller can’t ignore SIGABRT, if so reset to default */
sigaction(SIGABRT, NULL, &action);
if (action.sa_handler == SIG_IGN) {
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL);
}
if (action.sa_handler == SIG_DFL)
fflush(NULL); /* flush all open stdio streams */

/* Caller can’t block SIGABRT; make sure it’s unblocked */
sigfillset(&mask);
sigdelset(&mask, SIGABRT); /* mask has only SIGABRT turned off */
sigprocmask(SIG_SETMASK, &mask, NULL);
kill(getpid(), SIGABRT); /* send the signal */

/* If we’re here, process caught SIGABRT and returned */
fflush(NULL); /* flush all open stdio streams */
action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &action, NULL); /* reset to default */
sigprocmask(SIG_SETMASK, &mask, NULL); /* just in case ... */
kill(getpid(), SIGABRT); /* and one more time */
exit(1); /* this should never be executed ... */
}

Figure 10.25 Implementation of POSIX.1abort
Free download pdf