Browse Source

trap sigterm and shut down child.

David Rose 23 years ago
parent
commit
fdded6a238
1 changed files with 48 additions and 5 deletions
  1. 48 5
      direct/src/autorestart/autorestart.c

+ 48 - 5
direct/src/autorestart/autorestart.c

@@ -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);