diff --git a/src/nghttpd.cc b/src/nghttpd.cc index efa01103..e2232403 100644 --- a/src/nghttpd.cc +++ b/src/nghttpd.cc @@ -435,7 +435,7 @@ int main(int argc, char **argv) { #ifdef __sgi if (daemon(0, 0, 0, 0) == -1) { #else - if (daemon(0, 0) == -1) { + if (util::daemonize(0, 0) == -1) { #endif perror("daemon"); exit(EXIT_FAILURE); diff --git a/src/shrpx.cc b/src/shrpx.cc index 85b69dcb..bb3250f8 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1148,7 +1148,7 @@ int call_daemon() { return 0; } # endif // HAVE_LIBSYSTEMD - return daemon(0, 0); + return util::daemonize(0, 0); #endif // !__sgi } } // namespace diff --git a/src/util.cc b/src/util.cc index b3c8de53..bb30fcd3 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1542,6 +1542,46 @@ std::mt19937 make_mt19937() { return std::mt19937(rd()); } +int daemonize(int nochdir, int noclose) { +#if defined(__APPLE__) + pid_t pid; + pid = fork(); + if (pid == -1) { + return -1; + } else if (pid > 0) { + _exit(EXIT_SUCCESS); + } + if (setsid() == -1) { + return -1; + } + pid = fork(); + if (pid == -1) { + return -1; + } else if (pid > 0) { + _exit(EXIT_SUCCESS); + } + if (nochdir == 0) { + if (chdir("/") == -1) { + return -1; + } + } + if (noclose == 0) { + if (freopen("/dev/null", "r", stdin) == nullptr) { + return -1; + } + if (freopen("/dev/null", "w", stdout) == nullptr) { + return -1; + } + if (freopen("/dev/null", "w", stderr) == nullptr) { + return -1; + } + } + return 0; +#else // !defined(__APPLE__) + return daemon(nochdir, noclose); +#endif // !defined(__APPLE__) +} + } // namespace util } // namespace nghttp2 diff --git a/src/util.h b/src/util.h index 8babd222..38761e08 100644 --- a/src/util.h +++ b/src/util.h @@ -772,6 +772,10 @@ StringRef extract_host(const StringRef &hostport); // Returns new std::mt19937 object. std::mt19937 make_mt19937(); +// daemonize calls daemon(3). If __APPLE__ is defined, it implements +// daemon() using fork(). +int daemonize(int nochdir, int noclose); + } // namespace util } // namespace nghttp2