1 /* $NetBSD: killme_after.c,v 1.2 2020/03/18 19:05:21 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* killme_after 3 6 /* SUMMARY 7 /* programmed death 8 /* SYNOPSIS 9 /* #include <killme_after.h> 10 /* 11 /* void killme_after(seconds) 12 /* unsigned int seconds; 13 /* DESCRIPTION 14 /* The killme_after() function does a best effort to terminate 15 /* the process after the specified time, should it still exist. 16 /* It is meant to be used in a signal handler, as an insurance 17 /* against getting stuck somewhere while preparing for exit. 18 /* DIAGNOSTICS 19 /* None. This routine does a best effort, damn the torpedoes. 20 /* LICENSE 21 /* .ad 22 /* .fi 23 /* The Secure Mailer license must be distributed with this software. 24 /* AUTHOR(S) 25 /* Wietse Venema 26 /* IBM T.J. Watson Research 27 /* P.O. Box 704 28 /* Yorktown Heights, NY 10598, USA 29 /* 30 /* Wietse Venema 31 /* Google, Inc. 32 /* 111 8th Avenue 33 /* New York, NY 10011, USA 34 /*--*/ 35 36 /* System library. */ 37 38 #include <sys_defs.h> 39 #include <signal.h> 40 #include <unistd.h> 41 42 /* Utility library. */ 43 44 #include <killme_after.h> 45 46 /* killme_after - self-assured death */ 47 48 void killme_after(unsigned int seconds) 49 { 50 struct sigaction sig_action; 51 52 /* 53 * Schedule an ALARM signal, and make sure the signal will be delivered 54 * even if we are being called from a signal handler and SIGALRM delivery 55 * is blocked. 56 * 57 * Undocumented: when a process runs with PID 1, Linux won't deliver a 58 * signal unless the process specifies a handler (i.e. SIG_DFL is treated 59 * as SIG_IGN). Conveniently, _exit() can be used directly as a signal 60 * handler. This changes the wait status that a parent would see, but in 61 * the case of "init" mode on Linux, no-one would care. 62 */ 63 alarm(0); 64 sigemptyset(&sig_action.sa_mask); 65 sig_action.sa_flags = 0; 66 sig_action.sa_handler = (getpid() == 1 ? _exit : SIG_DFL); 67 sigaction(SIGALRM, &sig_action, (struct sigaction *) 0); 68 alarm(seconds); 69 sigaddset(&sig_action.sa_mask, SIGALRM); 70 sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, (sigset_t *) 0); 71 } 72