Index: cgi-fcgi/cgi-fcgi.c =================================================================== --- cgi-fcgi/cgi-fcgi.c.orig +++ cgi-fcgi/cgi-fcgi.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "fcgi_config.h" @@ -583,7 +585,7 @@ #define MAXARGS 16 static int ParseArgs(int argc, char *argv[], int *doBindPtr, int *doStartPtr, - char *connectPathPtr, char *appPathPtr, int *nServersPtr) { + char *connectPathPtr, char *appPathPtr, int *nServersPtr, int *doDaemonPtr) { int i, x, err = 0, @@ -599,6 +601,7 @@ *connectPathPtr = '\0'; *appPathPtr = '\0'; *nServersPtr = 0; + *doDaemonPtr = TRUE; for(i = 0; i < MAXARGS; i++) av[i] = NULL; @@ -649,7 +652,7 @@ } } err = ParseArgs(ac, av, doBindPtr, doStartPtr, - connectPathPtr, appPathPtr, nServersPtr); + connectPathPtr, appPathPtr, nServersPtr, doDaemonPtr); for(x = 1; x < ac; x++) { ASSERT(av[x] != NULL); free(av[x]); @@ -673,7 +676,9 @@ } else { strcpy(connectPathPtr, argv[i]); } - } else { + } else if(!strcmp(argv[i], "-supervise")) { + *doDaemonPtr = FALSE; + } else { fprintf(stderr, "Unknown option %s\n", argv[i]); err++; } @@ -718,6 +723,15 @@ return err; } +void handle_shutdown(int s) +{ + /* Kill our children processes */ + signal(s, SIG_IGN); + kill(0, s); + + exit(0); +} + int main(int argc, char **argv) { char **envp = environ; @@ -728,20 +742,22 @@ int headerLen, valueLen; char *equalPtr; FCGI_BeginRequestRecord beginRecord; - int doBind, doStart, nServers; + int doBind, doStart, nServers, doDaemon; char appPath[MAXPATHLEN], bindPath[MAXPATHLEN]; + int pid; if(ParseArgs(argc, argv, &doBind, &doStart, - (char *) &bindPath, (char *) &appPath, &nServers)) { + (char *) &bindPath, (char *) &appPath, &nServers, &doDaemon)) { fprintf(stderr, "Usage:\n" " cgi-fcgi -f , or\n" " cgi-fcgi -connect [] , or\n" -" cgi-fcgi -start -connect [] , or\n" +" cgi-fcgi -start -connect [-supervise] [] , or\n" " cgi-fcgi -bind -connect ,\n" "where is either the pathname of a UNIX domain socket\n" "or (if -bind is given) a hostName:portNumber specification\n" -"or (if -start is given) a :portNumber specification (uses local host).\n"); +"or (if -start is given) a :portNumber specification (uses local host).\n" +"-supervise is for running with runit or daemontools.\n"); exit(1); } @@ -757,12 +773,27 @@ bytesToRead = 0; } + /* Become a process group leader */ + setsid(); + + /* Register our signal handler */ + signal(SIGHUP, handle_shutdown); + signal(SIGINT, handle_shutdown); + signal(SIGTERM, handle_shutdown); + if(doBind) { appServerSock = OS_FcgiConnect(bindPath); } if(doStart && (!doBind || appServerSock < 0)) { FCGI_Start(bindPath, appPath, nServers); if(!doBind) { + if(!doDaemon) { + for(pid=nServers; pid != 0; pid--) { + wait(0); + } + } + signal(SIGTERM, SIG_IGN); + kill(0, SIGTERM); exit(0); } else { appServerSock = OS_FcgiConnect(bindPath);