\r
if (!shar_checkonly) {\r
// Run the listener.\r
- if (!conf.getServiceProvider()->getListenerService()->run(unlink_socket, &shibd_shutdown)) {\r
- fprintf(stderr, "listener failed to enter listen loop\n");\r
+ ListenerService* listener = conf.getServiceProvider()->getListenerService();\r
+ if (!listener->init(unlink_socket)) {\r
+ fprintf(stderr, "listener failed to initialize\n");\r
+ conf.term();\r
return -3;\r
}\r
+ else if (!listener->run(&shibd_shutdown)) {\r
+ fprintf(stderr, "listener failed during service\n");\r
+ listener->term();\r
+ conf.term();\r
+ return -3;\r
+ }\r
+ listener->term();\r
}\r
\r
conf.term();\r
\r
int daemon_wait = 3;\r
bool shibd_running = false;\r
+bool daemonize = true;\r
\r
static void term_handler(int arg)\r
{\r
shibd_running = true;\r
}\r
\r
+static void child_handler(int arg)\r
+{\r
+ // Terminate the parent's wait/sleep if the newly born daemon dies early.\r
+}\r
+\r
static int setup_signals(void)\r
{\r
struct sigaction sa;\r
return -1;\r
}\r
\r
- memset(&sa, 0, sizeof (sa));\r
- sa.sa_handler = run_handler;\r
+ if (daemonize) {\r
+ memset(&sa, 0, sizeof (sa));\r
+ sa.sa_handler = run_handler;\r
\r
- if (sigaction(SIGUSR1, &sa, NULL) < 0) {\r
- return -1;\r
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {\r
+ return -1;\r
+ }\r
+\r
+ memset(&sa, 0, sizeof (sa));\r
+ sa.sa_handler = child_handler;\r
+\r
+ if (sigaction(SIGCHLD, &sa, NULL) < 0) {\r
+ return -1;\r
+ }\r
}\r
\r
return 0;\r
fprintf(stderr, " -d\tinstallation prefix to use.\n");\r
fprintf(stderr, " -c\tconfig file to use.\n");\r
fprintf(stderr, " -x\tXML schema catalogs to use.\n");\r
- fprintf(stderr, " -t\tcheck configuration file for problems.\n");\r
+ fprintf(stderr, " -t\ttest configuration file for problems.\n");\r
fprintf(stderr, " -f\tforce removal of listener socket.\n");\r
+ fprintf(stderr, " -F\tstay in the foreground.\n");\r
fprintf(stderr, " -p\tpid file to use.\n");\r
fprintf(stderr, " -w\tseconds to wait for successful daemonization.\n");\r
fprintf(stderr, " -v\tprint software version.\n");\r
{\r
int opt;\r
\r
- while ((opt = getopt(argc, argv, "d:c:x:p:w:ftvh")) > 0) {\r
+ while ((opt = getopt(argc, argv, "d:c:x:p:w:fFtvh")) > 0) {\r
switch (opt) {\r
case 'd':\r
shar_prefix=optarg;\r
case 'f':\r
unlink_socket = true;\r
break;\r
+ case 'F':\r
+ daemonize = false;\r
+ break;\r
case 't':\r
shar_checkonly=true;\r
+ daemonize=false;\r
break;\r
case 'v':\r
shar_version=true;\r
return -1;\r
}\r
\r
- // We must fork() early, while we're single threaded.\r
- // StorageService cleanup thread is about to start.\r
- if (!shar_checkonly) {\r
+ if (daemonize) {\r
+ // We must fork() early, while we're single threaded.\r
+ // StorageService cleanup thread is about to start.\r
switch (fork()) {\r
case 0:\r
break;\r
if (shar_checkonly)\r
fprintf(stderr, "overall configuration is loadable, check console for non-fatal problems\n");\r
else {\r
- if (setsid() == -1) {\r
- perror("setsid");\r
- exit(EXIT_FAILURE);\r
- }\r
- if (chdir("/") == -1) {\r
- perror("chdir to root");\r
- exit(EXIT_FAILURE);\r
+ // Init the listener.\r
+ ListenerService* listener = conf.getServiceProvider()->getListenerService();\r
+ if (!listener->init(unlink_socket)) {\r
+ fprintf(stderr, "listener failed to initialize\n");\r
+ conf.term();\r
+ return -3;\r
}\r
\r
- // Write the pid file\r
- if (pidfile) {\r
- FILE* pidf = fopen(pidfile, "w");\r
- if (pidf) {\r
- fprintf(pidf, "%d\n", getpid());\r
- fclose(pidf);\r
- } else {\r
- perror(pidfile); // keep running though\r
+ if (daemonize) {\r
+ if (setsid() == -1) {\r
+ perror("setsid");\r
+ exit(EXIT_FAILURE);\r
+ }\r
+ if (chdir("/") == -1) {\r
+ perror("chdir to root");\r
+ exit(EXIT_FAILURE);\r
}\r
- }\r
\r
- freopen("/dev/null", "r", stdin);\r
- freopen("/dev/null", "w", stdout);\r
- freopen("/dev/null", "w", stderr);\r
+ if (pidfile) {\r
+ FILE* pidf = fopen(pidfile, "w");\r
+ if (pidf) {\r
+ fprintf(pidf, "%d\n", getpid());\r
+ fclose(pidf);\r
+ }\r
+ else {\r
+ perror(pidfile);\r
+ }\r
+ }\r
\r
- // Run the listener\r
- if (!conf.getServiceProvider()->getListenerService()->setSignal(SIGUSR1)) {\r
- fprintf(stderr, "listener failed to accept signaling hook\n");\r
- return -3;\r
+ freopen("/dev/null", "r", stdin);\r
+ freopen("/dev/null", "w", stdout);\r
+ freopen("/dev/null", "w", stderr);\r
+\r
+ // Signal our parent that we are A-OK.\r
+ kill(getppid(), SIGUSR1);\r
}\r
- if (!conf.getServiceProvider()->getListenerService()->run(unlink_socket, &shibd_shutdown)) {\r
- fprintf(stderr, "listener failed to enter listen loop\n");\r
+\r
+ // Run the listener.\r
+ if (!listener->run(&shibd_shutdown)) {\r
+ fprintf(stderr, "listener failure during service\n");\r
+ listener->term();\r
+ conf.term();\r
+ if (pidfile)\r
+ unlink(pidfile);\r
return -3;\r
}\r
+ listener->term();\r
}\r
\r
conf.term();\r