*/
-
+#ifndef HAVE_WIN32
#include "bacula.h"
#ifndef _NSIG
*/
static void signal_handler(int sig)
{
- static int already_dead = FALSE;
- struct sigaction sigdefault;
+ static int already_dead = 0;
- if (already_dead) {
+ /* If we come back more than once, get out fast! */
+ if (already_dead > 1) {
_exit(1);
}
- already_dead = sig;
+ /* If we come back once, take normal exit */
+ if (already_dead) {
+ exit(1);
+ }
+ Dmsg1(200, "sig=%d\n", sig);
+ /* Ignore certain signals */
+ if (sig == SIGCHLD || sig == SIGUSR2) {
+ return;
+ }
+ already_dead++;
if (sig == SIGTERM) {
Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
} else {
#ifdef TRACEBACK
if (sig != SIGTERM) {
+ struct sigaction sigdefault;
static char *argv[4];
static char pid_buf[20];
static char btpath[400];
pid_t pid;
+ int exelen = strlen(exepath);
fprintf(stderr, "Kaboom! %s, %s got signal %d. Attempting traceback.\n",
- NPRT(exename), NPRT(my_name), sig);
+ exename, my_name, sig);
- if (strlen(exepath) + 12 > (int)sizeof(btpath)) {
+ if (exelen + 12 > (int)sizeof(btpath)) {
strcpy(btpath, "btraceback");
} else {
strcpy(btpath, exepath);
- strcat(btpath, "/btraceback");
+ if (btpath[exelen-1] != '/') {
+ strcat(btpath, "/btraceback");
+ } else {
+ strcat(btpath, "btraceback");
+ }
+ }
+ if (btpath[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));
+ Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory, strerror(errno));
}
unlink("./core"); /* get rid of any old core file */
sprintf(pid_buf, "%d", (int)main_pid);
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));
}
default: /* parent */
break;
}
+ /* Parent continue here, waiting for child */
sigdefault.sa_flags = 0;
sigdefault.sa_handler = SIG_DFL;
sigfillset(&sigdefault.sa_mask);
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);
}
/*
sigaction(SIGPIPE, &sigignore, NULL);
- sigaction(SIGCHLD, &sigignore, NULL);
+ sigaction(SIGCHLD, &sighandle, NULL);
sigaction(SIGCONT, &sigignore, NULL);
sigaction(SIGPROF, &sigignore, NULL);
sigaction(SIGWINCH, &sigignore, NULL);
sigaction(SIGXCPU, &sigdefault, NULL);
sigaction(SIGXFSZ, &sigdefault, NULL);
- sigaction(SIGHUP, &sighandle, NULL);
+ sigaction(SIGHUP, &sigignore, NULL);
sigaction(SIGQUIT, &sighandle, NULL);
sigaction(SIGILL, &sighandle, NULL);
sigaction(SIGTRAP, &sighandle, NULL);
sigaction(SIGLOST, &sighandle, NULL);
#endif
}
+#endif