<pathentry base-path="cpp-sp" include="shibsp" kind="inc" path="" system="true"/>\r
<pathentry base-path="cpp-sp" include="" kind="inc" path="" system="true"/>\r
<pathentry kind="mac" name="SHIBSP_API" path="" value=""/>\r
+<pathentry kind="mac" name="WIN32" path="" value=""/>\r
+<pathentry kind="mac" name="_MSC_VER" path="" value=""/>\r
<pathentry kind="out" path=""/>\r
<pathentry excluding="util/|impl/|security/|metadata/|remoting/|remoting/impl/|attribute/|binding/|binding/impl/|attribute/resolver/|attribute/resolver/impl/|handler/|handler/impl/|attribute/filtering/|attribute/filtering/impl/|lite/" kind="src" path="shibsp"/>\r
<pathentry excluding="resolver/|resolver/impl/|filtering/|filtering/impl/" kind="src" path="shibsp/attribute"/>\r
\r
#else\r
\r
+int daemon_wait = 3;\r
+bool shibd_running = false;\r
+\r
static void term_handler(int arg)\r
{\r
shibd_shutdown = true;\r
}\r
\r
+static void run_handler(int arg)\r
+{\r
+ shibd_running = true;\r
+}\r
+\r
static int setup_signals(void)\r
{\r
struct sigaction sa;\r
if (sigaction(SIGTERM, &sa, NULL) < 0) {\r
return -1;\r
}\r
+\r
+ memset(&sa, 0, sizeof (sa));\r
+ sa.sa_handler = run_handler;\r
+\r
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {\r
+ return -1;\r
+ }\r
+\r
return 0;\r
}\r
\r
fprintf(stderr, " -t\tcheck configuration file for problems.\n");\r
fprintf(stderr, " -f\tforce removal of listener socket.\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
fprintf(stderr, " -h\tprint this help message.\n");\r
exit(1);\r
{\r
int opt;\r
\r
- while ((opt = getopt(argc, argv, "d:c:x:p:ftvh")) > 0) {\r
+ while ((opt = getopt(argc, argv, "d:c:x:p:w:ftvh")) > 0) {\r
switch (opt) {\r
case 'd':\r
shar_prefix=optarg;\r
case 'p':\r
pidfile=optarg;\r
break;\r
+ case 'w':\r
+ if (optarg)\r
+ daemon_wait = atoi(optarg);\r
+ if (daemon_wait <= 0)\r
+ daemon_wait = 3;\r
+ break;\r
default:\r
return -1;\r
}\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
+ switch (fork()) {\r
+ case 0:\r
+ break;\r
+ case -1:\r
+ perror("forking");\r
+ exit(EXIT_FAILURE);\r
+ default:\r
+ sleep(daemon_wait);\r
+ exit(shibd_running ? EXIT_SUCCESS : EXIT_FAILURE);\r
+ }\r
+ }\r
+\r
if (!conf.instantiate(shar_config)) {\r
fprintf(stderr, "configuration is invalid, check console for specific problems\n");\r
conf.term();\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
+ }\r
+\r
// Write the pid file\r
if (pidfile) {\r
FILE* pidf = fopen(pidfile, "w");\r
}\r
}\r
\r
+ freopen("/dev/null", "r", stdin);\r
+ freopen("/dev/null", "w", stdout);\r
+ freopen("/dev/null", "w", stderr);\r
+\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
m_lock->unlock();
}
-SocketListener::SocketListener(const DOMElement* e) : m_catchAll(false), log(&Category::getInstance(SHIBSP_LOGCAT".Listener")),
- m_socketpool(NULL), m_shutdown(NULL), m_child_lock(NULL), m_child_wait(NULL), m_socket((ShibSocket)0)
+SocketListener::SocketListener(const DOMElement* e)
+ : m_catchAll(false), log(&Category::getInstance(SHIBSP_LOGCAT".Listener")), m_socketpool(NULL),
+#ifndef WIN32
+ m_signal(0),
+#endif
+ m_shutdown(NULL), m_child_lock(NULL), m_child_wait(NULL), m_socket((ShibSocket)0)
{
// Are we a client?
if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
return false;
}
+#ifndef WIN32
+ if (m_signal) {
+ // Notify our parent that we're entering the select loop.
+ pid_t ppid = getppid();
+ kill(ppid, SIGUSR1);
+ log->info("notified parent (%d) upon entering select loop", ppid);
+ }
+#endif
+
while (!*m_shutdown) {
fd_set readfds;
FD_ZERO(&readfds);