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
) {
43 memcpy(&last_sigterm_info
, si
, sizeof(*si
));
45 /** forward the sig to the child */
48 case SIGHUP
: /** do a graceful restart */
50 memcpy(&last_sighup_info
, si
, sizeof(*si
));
52 /** do a graceful shutdown on the main process and start a new child */
55 usleep(5 * 1000); /** wait 5 microsec */
60 /** a child died, de-combie it */
66 int main(int argc
, char **argv
) {
71 *(const char **)&argv
[0] = BINPATH
;
73 __coverity_tainted_data_sanitize__(argv
);
77 * we are running as root BEWARE
80 memset(&act
, 0, sizeof(act
));
81 act
.sa_handler
= SIG_IGN
;
82 sigaction(SIGPIPE
, &act
, NULL
);
83 sigaction(SIGUSR1
, &act
, NULL
);
85 act
.sa_sigaction
= sigaction_handler
;
86 sigemptyset(&act
.sa_mask
);
87 act
.sa_flags
= SA_SIGINFO
;
89 sigaction(SIGINT
, &act
, NULL
);
90 sigaction(SIGTERM
, &act
, NULL
);
91 sigaction(SIGUSR1
, &act
, NULL
);
92 sigaction(SIGHUP
, &act
, NULL
);
93 sigaction(SIGALRM
, &act
, NULL
);
94 sigaction(SIGCHLD
, &act
, NULL
);
96 /* check that the compiled in path has the right user,
98 * BEWARE: there is a race between the check here and the exec later
101 while (!is_shutdown
) {
110 /* intentionally pass argv params */
111 /* coverity[tainted_string : FALSE] */
112 execvp(argv
[0], argv
);
114 } else if (-1 == pid
) {
124 if ((pid_t
)-1 == waitpid(pid
, &exitcode
, 0)) {
127 /* someone sent a signal ...
128 * do we have to shutdown or restart the process */
132 * make sure we are not in a race between the signal handler
133 * and the process restart */
134 if (!start_process
) is_shutdown
= 1;
140 /** process went away */
142 if (WIFEXITED(exitcode
)) {
147 fprintf(stderr
, "%s.%d: child (pid=%d) exited normally with exitcode: %d\n",
150 WEXITSTATUS(exitcode
));
152 } else if (WIFSIGNALED(exitcode
)) {
155 fprintf(stderr
, "%s.%d: child (pid=%d) exited unexpectedly with signal %d, restarting\n",