|
@@ -38,6 +38,8 @@ char **params = NULL;
|
|
|
char *logfile_name = NULL;
|
|
char *logfile_name = NULL;
|
|
|
int logfile_fd = -1;
|
|
int logfile_fd = -1;
|
|
|
|
|
|
|
|
|
|
+pid_t child_pid = 0;
|
|
|
|
|
+
|
|
|
#define TIME_BUFFER_SIZE 128
|
|
#define TIME_BUFFER_SIZE 128
|
|
|
|
|
|
|
|
/* We shouldn't respawn more than (COUNT_RESPAWN - 1) times over
|
|
/* We shouldn't respawn more than (COUNT_RESPAWN - 1) times over
|
|
@@ -67,17 +69,17 @@ spawn_process() {
|
|
|
by itself and should be respawned, false if it was explicitly
|
|
by itself and should be respawned, false if it was explicitly
|
|
|
killed (or some other error condition exists), and it should not
|
|
killed (or some other error condition exists), and it should not
|
|
|
respawn any more. */
|
|
respawn any more. */
|
|
|
- pid_t child, wresult;
|
|
|
|
|
|
|
+ pid_t wresult;
|
|
|
int status;
|
|
int status;
|
|
|
|
|
|
|
|
- child = fork();
|
|
|
|
|
- if (child < 0) {
|
|
|
|
|
|
|
+ child_pid = fork();
|
|
|
|
|
+ if (child_pid < 0) {
|
|
|
/* Fork error. */
|
|
/* Fork error. */
|
|
|
perror("fork");
|
|
perror("fork");
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (child == 0) {
|
|
|
|
|
|
|
+ if (child_pid == 0) {
|
|
|
/* Child. Exec the process. */
|
|
/* Child. Exec the process. */
|
|
|
fprintf(stderr, "Child pid is %d.\n", getpid());
|
|
fprintf(stderr, "Child pid is %d.\n", getpid());
|
|
|
exec_process();
|
|
exec_process();
|
|
@@ -86,12 +88,16 @@ spawn_process() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Parent. Wait for the child to terminate, then diagnose the reason. */
|
|
/* Parent. Wait for the child to terminate, then diagnose the reason. */
|
|
|
- wresult = waitpid(child, &status, 0);
|
|
|
|
|
|
|
+ wresult = waitpid(child_pid, &status, 0);
|
|
|
if (wresult < 0) {
|
|
if (wresult < 0) {
|
|
|
perror("waitpid");
|
|
perror("waitpid");
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /* Now that we've returned from waitpid, clear the child pid number
|
|
|
|
|
+ so our signal handler doesn't get too confused. */
|
|
|
|
|
+ child_pid = 0;
|
|
|
|
|
+
|
|
|
if (WIFSIGNALED(status)) {
|
|
if (WIFSIGNALED(status)) {
|
|
|
int signal = WTERMSIG(status);
|
|
int signal = WTERMSIG(status);
|
|
|
fprintf(stderr, "\nprocess caught signal %d.\n\n", signal);
|
|
fprintf(stderr, "\nprocess caught signal %d.\n\n", signal);
|
|
@@ -107,16 +113,53 @@ spawn_process() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void
|
|
|
|
|
+sigterm_handler() {
|
|
|
|
|
+ pid_t wresult;
|
|
|
|
|
+ int status;
|
|
|
|
|
+ time_t now;
|
|
|
|
|
+ char time_buffer[TIME_BUFFER_SIZE];
|
|
|
|
|
+
|
|
|
|
|
+ now = time(NULL);
|
|
|
|
|
+ strftime(time_buffer, TIME_BUFFER_SIZE, "%T on %A, %d %b %Y", localtime(&now));
|
|
|
|
|
+
|
|
|
|
|
+ fprintf(stderr, "\nsigterm caught at %s; shutting down.\n", time_buffer);
|
|
|
|
|
+ if (child_pid == 0) {
|
|
|
|
|
+ fprintf(stderr, "no child process.\n\n");
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ kill(child_pid, SIGTERM);
|
|
|
|
|
+
|
|
|
|
|
+ wresult = waitpid(child_pid, &status, 0);
|
|
|
|
|
+ if (wresult < 0) {
|
|
|
|
|
+ perror("waitpid");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ fprintf(stderr, "child process terminated.\n\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ exit(1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void
|
|
void
|
|
|
do_autorestart() {
|
|
do_autorestart() {
|
|
|
char time_buffer[TIME_BUFFER_SIZE];
|
|
char time_buffer[TIME_BUFFER_SIZE];
|
|
|
time_t now;
|
|
time_t now;
|
|
|
time_t count_respawn[COUNT_RESPAWN];
|
|
time_t count_respawn[COUNT_RESPAWN];
|
|
|
int cri, num_cri;
|
|
int cri, num_cri;
|
|
|
|
|
+ struct sigaction sa;
|
|
|
|
|
|
|
|
/* Make our process its own process group. */
|
|
/* Make our process its own process group. */
|
|
|
setpgid(0, 0);
|
|
setpgid(0, 0);
|
|
|
|
|
|
|
|
|
|
+ /* Set up a signal handler to trap SIGTERM. */
|
|
|
|
|
+ sa.sa_handler = sigterm_handler;
|
|
|
|
|
+ sigemptyset(&sa.sa_mask);
|
|
|
|
|
+ sa.sa_flags = 0;
|
|
|
|
|
+ if (sigaction(SIGTERM, &sa, NULL) < 0) {
|
|
|
|
|
+ perror("sigaction");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/* If we have a logfile, dup it onto stdout and stderr. */
|
|
/* If we have a logfile, dup it onto stdout and stderr. */
|
|
|
if (logfile_fd >= 0) {
|
|
if (logfile_fd >= 0) {
|
|
|
dup2(logfile_fd, STDOUT_FILENO);
|
|
dup2(logfile_fd, STDOUT_FILENO);
|