]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/signal.c
- Add Version, ConfigDir, and WorkingDir as Python attributes
[bacula/bacula] / bacula / src / lib / signal.c
index 50a0a46f6e6886853a3cff18008f7d3384e110c9..83333deb58490d740b48e6dcff782a40ee70acce 100644 (file)
@@ -4,18 +4,18 @@
  *   Kern Sibbald, April 2000
  *
  *   Version $Id$
- * 
+ *
  * Note, we probably should do a core dump for the serious
- * signals such as SIGBUS, SIGPFE, ... 
- * Also, for SIGHUP and SIGUSR1, we should re-read the 
- * configuration file.  However, since this is a "general"  
+ * signals such as SIGBUS, SIGPFE, ...
+ * Also, for SIGHUP and SIGUSR1, we should re-read the
+ * configuration file.  However, since this is a "general"
  * routine, we leave it to the individual daemons to
  * tweek their signals after calling this routine.
  *
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -34,7 +34,7 @@
 
  */
 
-
+#ifndef HAVE_WIN32
 #include "bacula.h"
 
 #ifndef _NSIG
@@ -55,44 +55,76 @@ static SIG_HANDLER *exit_handler;
 /* main process id */
 static pid_t main_pid = 0;
 
-/* 
+const char *get_signal_name(int sig)
+{
+   if (sig < 0 || sig > BA_NSIG || !sig_names[sig]) {
+      return "Invalid signal number";
+   } else {
+      return sig_names[sig];
+   }
+}
+
+/*
  * Handle signals here
  */
-static void signal_handler(int sig)
+extern "C" void signal_handler(int sig)
 {
-   static int already_dead = FALSE;
-   struct sigaction sigdefault;
+   static int already_dead = 0;
 
+   /* If we come back more than once, get out fast! */
    if (already_dead) {
-      _exit(1);
+      exit(1);
    }
-   already_dead = sig;
+   Dmsg2(900, "sig=%d %s\n", sig, sig_names[sig]);
+   /* Ignore certain signals -- SIGUSR2 used to interrupt threads */
+   if (sig == SIGCHLD || sig == SIGUSR2) {
+      return;
+   }
+   already_dead++;
    if (sig == SIGTERM) {
-      Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
+//    Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
    } else {
       Emsg2(M_FATAL, -1, "Bacula interrupted by signal %d: %s\n", sig, sig_names[sig]);
    }
 
 #ifdef TRACEBACK
    if (sig != SIGTERM) {
+      struct sigaction sigdefault;
       static char *argv[4];
       static char pid_buf[20];
       static char btpath[400];
+      char buf[100];
       pid_t pid;
+      int exelen = strlen(exepath);
 
-      fprintf(stderr, "Kaboom! %s, %s got signal %d. Attempting traceback.\n", 
-             exename, my_name, sig);
+      fprintf(stderr, "Kaboom! %s, %s got signal %d. Attempting traceback.\n",
+              exename, my_name, sig);
+      fprintf(stderr, "Kaboom! exepath=%s\n", exepath);
 
-      if (strlen(exepath) + 12 > (int)sizeof(btpath)) {
-         strcpy(btpath, "btraceback");
+      if (exelen + 12 > (int)sizeof(btpath)) {
+         bstrncpy(btpath, "btraceback", sizeof(btpath));
       } else {
-        strcpy(btpath, exepath);
-         strcat(btpath, "/btraceback");
+         bstrncpy(btpath, exepath, sizeof(btpath));
+         if (btpath[exelen-1] == '/') {
+            btpath[exelen-1] = 0;
+         }
+         bstrncat(btpath, "/btraceback", sizeof(btpath));
+      }
+      if (exepath[exelen-1] != '/') {
+         strcat(exepath, "/");
       }
-      strcat(exepath, "/");
       strcat(exepath, exename);
-      if (chdir(working_directory) !=0) {  /* dump in working directory */
-         Dmsg1(000, "chdir failed. ERR=%s\n", strerror(errno));
+      if (!working_directory) {
+         working_directory = buf;
+         *buf = 0;
+      }
+      if (*working_directory == 0) {
+         strcpy((char *)working_directory, "/tmp/");
+      }
+      if (chdir(working_directory) != 0) {  /* dump in working directory */
+         berrno be;
+         Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory,  be.strerror());
+         strcpy((char *)working_directory, "/tmp/");
       }
       unlink("./core");               /* get rid of any old core file */
       sprintf(pid_buf, "%d", (int)main_pid);
@@ -100,21 +132,23 @@ static void signal_handler(int sig)
       Dmsg1(300, "btpath=%s\n", btpath);
       Dmsg1(300, "exepath=%s\n", exepath);
       switch (pid = fork()) {
-      case -1:                       /* error */
+      case -1:                        /* error */
          fprintf(stderr, "Fork error: ERR=%s\n", strerror(errno));
-        break;
-      case 0:                        /* child */
-        argv[0] = btpath;            /* path to btraceback */
-        argv[1] = exepath;           /* path to exe */
-        argv[2] = pid_buf;
-        argv[3] = (char *)NULL;
-        if (execv(btpath, argv) != 0) {
+         break;
+      case 0:                         /* child */
+         argv[0] = btpath;            /* path to btraceback */
+         argv[1] = exepath;           /* path to exe */
+         argv[2] = pid_buf;
+         argv[3] = (char *)NULL;
+         fprintf(stderr, "Calling: %s %s %s\n", btpath, exepath, pid_buf);
+         if (execv(btpath, argv) != 0) {
             printf("execv: %s failed: ERR=%s\n", btpath, strerror(errno));
-        }
-        exit(-1);
-      default:                       /* parent */
-        break;
+         }
+         exit(-1);
+      default:                        /* parent */
+         break;
       }
+      /* Parent continue here, waiting for child */
       sigdefault.sa_flags = 0;
       sigdefault.sa_handler = SIG_DFL;
       sigfillset(&sigdefault.sa_mask);
@@ -122,20 +156,20 @@ static void signal_handler(int sig)
       sigaction(sig,  &sigdefault, NULL);
       if (pid > 0) {
          Dmsg0(500, "Doing waitpid\n");
-        waitpid(pid, NULL, 0);       /* wait for child to produce dump */
+         waitpid(pid, NULL, 0);       /* wait for child to produce dump */
          fprintf(stderr, "Traceback complete, attempting cleanup ...\n");
          Dmsg0(500, "Done waitpid\n");
-        exit_handler(1);             /* clean up if possible */
+         exit_handler(sig);           /* clean up if possible */
          Dmsg0(500, "Done exit_handler\n");
       } else {
          Dmsg0(500, "Doing sleep\n");
-        sleep(30);
+         bmicrosleep(30, 0);
       }
       fprintf(stderr, "It looks like the traceback worked ...\n");
    }
 #endif
 
-   exit_handler(1);
+   exit_handler(sig);
 }
 
 /*
@@ -233,71 +267,72 @@ void init_signals(void terminate(int sig))
    sighandle.sa_handler = signal_handler;
    sigfillset(&sighandle.sa_mask);
    sigignore.sa_flags = 0;
-   sigignore.sa_handler = SIG_IGN;      
+   sigignore.sa_handler = SIG_IGN;
    sigfillset(&sigignore.sa_mask);
    sigdefault.sa_flags = 0;
    sigdefault.sa_handler = SIG_DFL;
    sigfillset(&sigdefault.sa_mask);
 
 
-   sigaction(SIGPIPE,  &sigignore, NULL);
-   sigaction(SIGCHLD,  &sigignore, NULL);
-   sigaction(SIGCONT,  &sigignore, NULL);
-   sigaction(SIGPROF,  &sigignore, NULL);
-   sigaction(SIGWINCH, &sigignore, NULL);
-   sigaction(SIGIO,    &sighandle, NULL);     
+   sigaction(SIGPIPE,   &sigignore, NULL);
+   sigaction(SIGCHLD,   &sighandle, NULL);
+   sigaction(SIGCONT,   &sigignore, NULL);
+   sigaction(SIGPROF,   &sigignore, NULL);
+   sigaction(SIGWINCH,  &sigignore, NULL);
+   sigaction(SIGIO,     &sighandle, NULL);
 
-   sigaction(SIGINT,   &sigdefault, NULL);    
-   sigaction(SIGXCPU,  &sigdefault, NULL);
-   sigaction(SIGXFSZ,  &sigdefault, NULL);
+   sigaction(SIGINT,    &sigdefault, NULL);
+   sigaction(SIGXCPU,   &sigdefault, NULL);
+   sigaction(SIGXFSZ,   &sigdefault, NULL);
 
-   sigaction(SIGHUP,   &sighandle, NULL);
-   sigaction(SIGQUIT,  &sighandle, NULL);   
-   sigaction(SIGILL,   &sighandle, NULL);    
-   sigaction(SIGTRAP,  &sighandle, NULL);   
-/* sigaction(SIGABRT,  &sighandle, NULL);   */
+   sigaction(SIGHUP,    &sigignore, NULL);
+   sigaction(SIGQUIT,   &sighandle, NULL);
+   sigaction(SIGILL,    &sighandle, NULL);
+   sigaction(SIGTRAP,   &sighandle, NULL);
+/* sigaction(SIGABRT,   &sighandle, NULL);   */
 #ifdef SIGEMT
-   sigaction(SIGEMT,   &sighandle, NULL);
+   sigaction(SIGEMT,    &sighandle, NULL);
 #endif
 #ifdef SIGIOT
-/* sigaction(SIGIOT,   &sighandle, NULL);  used by debugger */
+/* sigaction(SIGIOT,    &sighandle, NULL);  used by debugger */
 #endif
-   sigaction(SIGBUS,   &sighandle, NULL);    
-   sigaction(SIGFPE,   &sighandle, NULL);    
-   sigaction(SIGKILL,  &sighandle, NULL);   
-   sigaction(SIGUSR1,  &sighandle, NULL);   
-   sigaction(SIGSEGV,  &sighandle, NULL);   
-   sigaction(SIGUSR2,  &sighandle, NULL);
-   sigaction(SIGALRM,  &sighandle, NULL);   
-   sigaction(SIGTERM,  &sighandle, NULL);   
+   sigaction(SIGBUS,    &sighandle, NULL);
+   sigaction(SIGFPE,    &sighandle, NULL);
+   sigaction(SIGKILL,   &sighandle, NULL);
+   sigaction(SIGUSR1,   &sighandle, NULL);
+   sigaction(SIGSEGV,   &sighandle, NULL);
+   sigaction(SIGUSR2,   &sighandle, NULL);
+   sigaction(SIGALRM,   &sighandle, NULL);
+   sigaction(SIGTERM,   &sighandle, NULL);
 #ifdef SIGSTKFLT
-   sigaction(SIGSTKFLT, &sighandle, NULL); 
+   sigaction(SIGSTKFLT, &sighandle, NULL);
 #endif
-   sigaction(SIGSTOP,  &sighandle, NULL);   
-   sigaction(SIGTSTP,  &sighandle, NULL);   
-   sigaction(SIGTTIN,  &sighandle, NULL);   
-   sigaction(SIGTTOU,  &sighandle, NULL);   
-   sigaction(SIGURG,   &sighandle, NULL);    
-   sigaction(SIGVTALRM, &sighandle, NULL); 
+   sigaction(SIGSTOP,   &sighandle, NULL);
+   sigaction(SIGTSTP,   &sighandle, NULL);
+   sigaction(SIGTTIN,   &sighandle, NULL);
+   sigaction(SIGTTOU,   &sighandle, NULL);
+   sigaction(SIGURG,    &sighandle, NULL);
+   sigaction(SIGVTALRM, &sighandle, NULL);
 #ifdef SIGPWR
-   sigaction(SIGPWR,   &sighandle, NULL);    
+   sigaction(SIGPWR,    &sighandle, NULL);
 #endif
 #ifdef SIGWAITING
    sigaction(SIGWAITING,&sighandle, NULL);
 #endif
 #ifdef SIGLWP
-   sigaction(SIGLWP,   &sighandle, NULL);
+   sigaction(SIGLWP,    &sighandle, NULL);
 #endif
 #ifdef SIGFREEZE
    sigaction(SIGFREEZE, &sighandle, NULL);
 #endif
 #ifdef SIGTHAW
-   sigaction(SIGTHAW,  &sighandle, NULL);
+   sigaction(SIGTHAW,   &sighandle, NULL);
 #endif
 #ifdef SIGCANCEL
    sigaction(SIGCANCEL, &sighandle, NULL);
 #endif
 #ifdef SIGLOST
-   sigaction(SIGLOST,  &sighandle, NULL);
+   sigaction(SIGLOST,   &sighandle, NULL);
 #endif
 }
+#endif