diff options
Diffstat (limited to 'daemon.c')
| -rw-r--r-- | daemon.c | 79 | 
1 files changed, 35 insertions, 44 deletions
@@ -82,36 +82,54 @@ sigchld_handler (int sig)      lastsig = SIGCHLD;  } +RETSIGTYPE null_signal_handler(int sig) { } + +SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler)  /*    * This function is called by other parts of the program to - * setup the sigchld handler after a change to the signal context. + * setup the signal handler after a change to the signal context.   * This is done to improve robustness of the signal handling code. + * It has the same prototype as signal(2).   */ -void deal_with_sigchld(void)  { -  RETSIGTYPE sigchld_handler(int); +  SIGHANDLERTYPE rethandler;  #ifdef HAVE_SIGACTION -  struct sigaction sa_new; +  struct sigaction sa_new, sa_old;    memset (&sa_new, 0, sizeof sa_new);    sigemptyset (&sa_new.sa_mask); -  /* sa_new.sa_handler = SIG_IGN;     pointless */ - -  /* set up to catch child process termination signals */  -  sa_new.sa_handler = sigchld_handler; +  sa_new.sa_handler = handler; +  sa_new.sa_flags = 0;  #ifdef SA_RESTART	/* SunOS 4.1 portability hack */ -  sa_new.sa_flags = SA_RESTART | SA_NOCLDSTOP; +  /* system call should restart on all signals except SIGALRM */ +  if (sig != SIGALRM) +      sa_new.sa_flags |= SA_RESTART;  #endif -  sigaction (SIGCHLD, &sa_new, NULL); +#ifdef SA_NOCLDSTOP	/* SunOS 4.1 portability hack */ +  if (sig == SIGCHLD) +      sa_new.sa_flags |= SA_NOCLDSTOP; +#endif +  sigaction(sig, &sa_new, &sa_old); +  rethandler = sa_old.sa_handler;  #if defined(SIGPWR) -  sigaction (SIGPWR, &sa_new, NULL); +  if (sig == SIGCHLD) +     sigaction(SIGPWR, &sa_new, NULL);  #endif  #else /* HAVE_SIGACTION */ -  signal(SIGCHLD, sigchld_handler);  +  rethandler = signal(sig, handler);  #if defined(SIGPWR) -  signal(SIGPWR, sigchld_handler);  +  if (sig == SIGCHLD) +      signal(SIGPWR, handler);  #endif +  /* system call should restart on all signals except SIGALRM */ +  siginterrupt(sig, sig == SIGALRM);  #endif /* HAVE_SIGACTION */ +  return rethandler; +} + +void deal_with_sigchld(void) +{ +  set_signal_handler(SIGCHLD, sigchld_handler);  }  int @@ -120,9 +138,6 @@ daemonize (const char *logfile, void (*termhook)(int))  {    int fd;    pid_t childpid; -#ifdef HAVE_SIGACTION -  struct sigaction sa_new; -#endif /* HAVE_SIGACTION */    /* if we are started by init (process 1) via /etc/inittab we needn't        bother to detach from our process group context */ @@ -131,34 +146,14 @@ daemonize (const char *logfile, void (*termhook)(int))      goto nottyDetach;    /* Ignore BSD terminal stop signals */ -#ifdef HAVE_SIGACTION -  memset (&sa_new, 0, sizeof sa_new); -  sigemptyset (&sa_new.sa_mask); -  sa_new.sa_handler = SIG_IGN; -#ifdef SA_RESTART	/* SunOS 4.1 portability hack */ -  sa_new.sa_flags = SA_RESTART; -#endif -#endif /* HAVE_SIGACTION */  #ifdef 	SIGTTOU -#ifndef HAVE_SIGACTION -  signal(SIGTTOU, SIG_IGN); -#else -  sigaction (SIGTTOU, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ +  set_signal_handler(SIGTTOU, SIG_IGN);  #endif  #ifdef	SIGTTIN -#ifndef HAVE_SIGACTION -  signal(SIGTTIN, SIG_IGN); -#else -  sigaction (SIGTTIN, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ +  set_signal_handler(SIGTTIN, SIG_IGN);  #endif  #ifdef	SIGTSTP -#ifndef HAVE_SIGACTION -  signal(SIGTSTP, SIG_IGN); -#else -  sigaction (SIGTSTP, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ +  set_signal_handler(SIGTSTP, SIG_IGN);  #endif    /* In case we were not started in the background, fork and let @@ -199,11 +194,7 @@ daemonize (const char *logfile, void (*termhook)(int))  #endif    /* lose controlling tty */ -#ifndef HAVE_SIGACTION -  signal(SIGHUP, SIG_IGN); -#else -  sigaction (SIGHUP, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ +  set_signal_handler(SIGHUP, SIG_IGN);    if ((childpid = fork()) < 0) {      report(stderr, "fork (%s)\n", strerror(errno));      return(PS_IOERR);  | 
