1*33881f77Schristos /* $NetBSD: killme_after.c,v 1.2 2020/03/18 19:05:21 christos Exp $ */
241fbaed0Stron
341fbaed0Stron /*++
441fbaed0Stron /* NAME
541fbaed0Stron /* killme_after 3
641fbaed0Stron /* SUMMARY
741fbaed0Stron /* programmed death
841fbaed0Stron /* SYNOPSIS
941fbaed0Stron /* #include <killme_after.h>
1041fbaed0Stron /*
1141fbaed0Stron /* void killme_after(seconds)
1241fbaed0Stron /* unsigned int seconds;
1341fbaed0Stron /* DESCRIPTION
1441fbaed0Stron /* The killme_after() function does a best effort to terminate
1541fbaed0Stron /* the process after the specified time, should it still exist.
1641fbaed0Stron /* It is meant to be used in a signal handler, as an insurance
1741fbaed0Stron /* against getting stuck somewhere while preparing for exit.
1841fbaed0Stron /* DIAGNOSTICS
1941fbaed0Stron /* None. This routine does a best effort, damn the torpedoes.
2041fbaed0Stron /* LICENSE
2141fbaed0Stron /* .ad
2241fbaed0Stron /* .fi
2341fbaed0Stron /* The Secure Mailer license must be distributed with this software.
2441fbaed0Stron /* AUTHOR(S)
2541fbaed0Stron /* Wietse Venema
2641fbaed0Stron /* IBM T.J. Watson Research
2741fbaed0Stron /* P.O. Box 704
2841fbaed0Stron /* Yorktown Heights, NY 10598, USA
29f3bc92a4Schristos /*
30f3bc92a4Schristos /* Wietse Venema
31f3bc92a4Schristos /* Google, Inc.
32f3bc92a4Schristos /* 111 8th Avenue
33f3bc92a4Schristos /* New York, NY 10011, USA
3441fbaed0Stron /*--*/
3541fbaed0Stron
3641fbaed0Stron /* System library. */
3741fbaed0Stron
3841fbaed0Stron #include <sys_defs.h>
3941fbaed0Stron #include <signal.h>
4041fbaed0Stron #include <unistd.h>
4141fbaed0Stron
4241fbaed0Stron /* Utility library. */
4341fbaed0Stron
4441fbaed0Stron #include <killme_after.h>
4541fbaed0Stron
4641fbaed0Stron /* killme_after - self-assured death */
4741fbaed0Stron
killme_after(unsigned int seconds)4841fbaed0Stron void killme_after(unsigned int seconds)
4941fbaed0Stron {
5041fbaed0Stron struct sigaction sig_action;
5141fbaed0Stron
5241fbaed0Stron /*
5341fbaed0Stron * Schedule an ALARM signal, and make sure the signal will be delivered
5441fbaed0Stron * even if we are being called from a signal handler and SIGALRM delivery
5541fbaed0Stron * is blocked.
56f3bc92a4Schristos *
57f3bc92a4Schristos * Undocumented: when a process runs with PID 1, Linux won't deliver a
58f3bc92a4Schristos * signal unless the process specifies a handler (i.e. SIG_DFL is treated
59f3bc92a4Schristos * as SIG_IGN). Conveniently, _exit() can be used directly as a signal
60f3bc92a4Schristos * handler. This changes the wait status that a parent would see, but in
61f3bc92a4Schristos * the case of "init" mode on Linux, no-one would care.
6241fbaed0Stron */
6341fbaed0Stron alarm(0);
6441fbaed0Stron sigemptyset(&sig_action.sa_mask);
6541fbaed0Stron sig_action.sa_flags = 0;
66f3bc92a4Schristos sig_action.sa_handler = (getpid() == 1 ? _exit : SIG_DFL);
6741fbaed0Stron sigaction(SIGALRM, &sig_action, (struct sigaction *) 0);
6841fbaed0Stron alarm(seconds);
6941fbaed0Stron sigaddset(&sig_action.sa_mask, SIGALRM);
7041fbaed0Stron sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, (sigset_t *) 0);
7141fbaed0Stron }
72