4 * angel process for lighttpd
6 * the purpose is the run as root all the time and handle:
8 * - spawn on HUP to allow graceful restart
11 * it has to stay safe and small to be trustable
24 #define BINPATH SBIN_DIR"/lighttpd"
26 static siginfo_t last_sigterm_info
;
27 static siginfo_t last_sighup_info
;
29 static volatile sig_atomic_t start_process
= 1;
30 static volatile pid_t pid
= -1;
32 #define UNUSED(x) ( (void)(x) )
34 static void sigaction_handler(int sig
, siginfo_t
*si
, void *context
) {
41 memcpy(&last_sigterm_info
, si
, sizeof(*si
));
43 /** forward the sig to the child */
46 case SIGHUP
: /** do a graceful restart */
47 memcpy(&last_sighup_info
, si
, sizeof(*si
));
49 /** do a graceful shutdown on the main process and start a new child */
52 usleep(5 * 1000); /** wait 5 microsec */
57 /** a child died, de-combie it */
63 int main(int argc
, char **argv
) {
70 * we are running as root BEWARE
73 memset(&act
, 0, sizeof(act
));
74 act
.sa_handler
= SIG_IGN
;
75 sigaction(SIGPIPE
, &act
, NULL
);
76 sigaction(SIGUSR1
, &act
, NULL
);
78 act
.sa_sigaction
= sigaction_handler
;
79 sigemptyset(&act
.sa_mask
);
80 act
.sa_flags
= SA_SIGINFO
;
82 sigaction(SIGINT
, &act
, NULL
);
83 sigaction(SIGTERM
, &act
, NULL
);
84 sigaction(SIGHUP
, &act
, NULL
);
85 sigaction(SIGALRM
, &act
, NULL
);
86 sigaction(SIGCHLD
, &act
, NULL
);
88 /* check that the compiled in path has the right user,
90 * BEWARE: there is a race between the check here and the exec later
93 while (!is_shutdown
) {
104 execvp(BINPATH
, argv
);
107 } else if (-1 == pid
) {
117 if ((pid_t
)-1 == waitpid(pid
, &exitcode
, 0)) {
120 /* someone sent a signal ...
121 * do we have to shutdown or restart the process */
125 * make sure we are not in a race between the signal handler
126 * and the process restart */
127 if (!start_process
) is_shutdown
= 1;
133 /** process went away */
135 if (WIFEXITED(exitcode
)) {
140 fprintf(stderr
, "%s.%d: child (pid=%d) exited normally with exitcode: %d\n",
143 WEXITSTATUS(exitcode
));
145 } else if (WIFSIGNALED(exitcode
)) {
148 fprintf(stderr
, "%s.%d: child (pid=%d) exited unexpectedly with signal %d, restarting\n",