Permalink
Browse files

ensure clean service shutdown and clean ^C, ^Z behavior.

When supervise(8) itself receives certain signals, they should be propagated to the service.

When supervise(8) receives SIGTERM or SIGINT, propagate this to the supervised process by behaving as if `svc -dx` had been called. SIGTERM occurs during system shutdown. SIGINT can occur when svscan(8) is running in terminal foreground and gets ^C. In both cases, not propagating the signal to a setsid service will result in orphans that continue to run.

When supervise(8) receives SIGTSTOP, for example because svscan(8) is running in terminal foreground and gets ^Z, behave as if `svc -p` had been called. Similarly, when supervise(8) receives SIGCONT, behave as if `svc -c` had been called. This ensures that setsid services stop and resume when running in foreground.
  • Loading branch information...
acg committed Mar 24, 2014
1 parent 68f1388 commit 4cc51d76a38d7651aa7c749e8e3b0f41d7cd9658
Showing with 31 additions and 0 deletions.
  1. +1 −0 sig.c
  2. +1 −0 sig.h
  3. +29 −0 supervise.c
View
1 sig.c
@@ -10,6 +10,7 @@ int sig_hangup = SIGHUP;
int sig_int = SIGINT;
int sig_pipe = SIGPIPE;
int sig_term = SIGTERM;
int sig_ttystop = SIGTSTP;
void (*sig_defaulthandler)() = SIG_DFL;
void (*sig_ignorehandler)() = SIG_IGN;
View
1 sig.h
@@ -10,6 +10,7 @@ extern int sig_hangup;
extern int sig_int;
extern int sig_pipe;
extern int sig_term;
extern int sig_ttystop;
extern void (*sig_defaulthandler)();
extern void (*sig_ignorehandler)();
View
@@ -78,6 +78,27 @@ static void trigger(void)
ignored = write(selfpipe[1],"",1);
}
static void terminate(void)
{
int ignored;
ignored = write(fdcontrolwrite,"dx",2);
ignored = write(selfpipe[1],"",1);
}
static void ttystop(void)
{
int ignored;
ignored = write(fdcontrolwrite,"p",1);
ignored = write(selfpipe[1],"",1);
}
static void resume(void)
{
int ignored;
ignored = write(fdcontrolwrite,"c",1);
ignored = write(selfpipe[1],"",1);
}
static int forkexecve(const char *argv[],int fd,int sid)
{
int f;
@@ -91,6 +112,10 @@ static int forkexecve(const char *argv[],int fd,int sid)
case 0:
sig_uncatch(sig_child);
sig_unblock(sig_child);
sig_uncatch(sig_int);
sig_uncatch(sig_term);
sig_uncatch(sig_ttystop);
sig_uncatch(sig_cont);
if (sid) setsid(); /* shouldn't fail; if it does, too bad */
if (fd >= 0 && logpipe[0] >= 0) {
dup2(logpipe[fd],fd);
@@ -407,6 +432,10 @@ int main(int argc,char **argv)
sig_block(sig_child);
sig_catch(sig_child,trigger);
sig_catch(sig_term,terminate);
sig_catch(sig_int,terminate);
sig_catch(sig_ttystop,ttystop);
sig_catch(sig_cont,resume);
if (chdir(dir) == -1)
strerr_die3sys(111,FATAL,"unable to chdir to ",dir);

0 comments on commit 4cc51d7

Please sign in to comment.