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
) {
73 * we are running as root BEWARE
76 memset(&act
, 0, sizeof(act
));
77 act
.sa_handler
= SIG_IGN
;
78 sigaction(SIGPIPE
, &act
, NULL
);
79 sigaction(SIGUSR1
, &act
, NULL
);
81 act
.sa_sigaction
= sigaction_handler
;
82 sigemptyset(&act
.sa_mask
);
83 act
.sa_flags
= SA_SIGINFO
;
85 sigaction(SIGINT
, &act
, NULL
);
86 sigaction(SIGTERM
, &act
, NULL
);
87 sigaction(SIGUSR1
, &act
, NULL
);
88 sigaction(SIGHUP
, &act
, NULL
);
89 sigaction(SIGALRM
, &act
, NULL
);
90 sigaction(SIGCHLD
, &act
, NULL
);
92 /* check that the compiled in path has the right user,
94 * BEWARE: there is a race between the check here and the exec later
97 while (!is_shutdown
) {
108 execvp(BINPATH
, argv
);
111 } else if (-1 == pid
) {
121 if ((pid_t
)-1 == waitpid(pid
, &exitcode
, 0)) {
124 /* someone sent a signal ...
125 * do we have to shutdown or restart the process */
129 * make sure we are not in a race between the signal handler
130 * and the process restart */
131 if (!start_process
) is_shutdown
= 1;
137 /** process went away */
139 if (WIFEXITED(exitcode
)) {
144 fprintf(stderr
, "%s.%d: child (pid=%d) exited normally with exitcode: %d\n",
147 WEXITSTATUS(exitcode
));
149 } else if (WIFSIGNALED(exitcode
)) {
152 fprintf(stderr
, "%s.%d: child (pid=%d) exited unexpectedly with signal %d, restarting\n",