void ServerApplication::beDaemon() { #if !defined(POCO_NO_FORK_EXEC) pid_t pid; if ((pid = fork()) < 0) throw SystemException("cannot fork daemon process"); else if (pid != 0) exit(0); setsid(); umask(027); // attach stdin, stdout, stderr to /dev/null // instead of just closing them. This avoids // issues with third party/legacy code writing // stuff to stdout/stderr. FILE* fin = freopen("/dev/null", "r+", stdin); if (!fin) throw Poco::OpenFileException("Cannot attach stdin to /dev/null"); FILE* fout = freopen("/dev/null", "r+", stdout); if (!fout) throw Poco::OpenFileException("Cannot attach stdout to /dev/null"); FILE* ferr = freopen("/dev/null", "r+", stderr); if (!ferr) throw Poco::OpenFileException("Cannot attach stderr to /dev/null"); #else throw Poco::NotImplementedException("platform does not allow fork/exec"); #endif }
void ServerApplication::ServiceMain(DWORD argc, LPTSTR* argv) #endif { ServerApplication& app = static_cast<ServerApplication&>(Application::instance()); app.config().setBool("application.runAsService", true); #if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) _serviceStatusHandle = RegisterServiceCtrlHandlerW(L"", ServiceControlHandler); #else _serviceStatusHandle = RegisterServiceCtrlHandlerA("", ServiceControlHandler); #endif if (!_serviceStatusHandle) throw SystemException("cannot register service control handler"); _serviceStatus.dwServiceType = SERVICE_WIN32; _serviceStatus.dwCurrentState = SERVICE_START_PENDING; _serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; _serviceStatus.dwWin32ExitCode = 0; _serviceStatus.dwServiceSpecificExitCode = 0; _serviceStatus.dwCheckPoint = 0; _serviceStatus.dwWaitHint = 0; SetServiceStatus(_serviceStatusHandle, &_serviceStatus); try { #if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) std::vector<std::string> args; for (DWORD i = 0; i < argc; ++i) { std::string arg; Poco::UnicodeConverter::toUTF8(argv[i], arg); args.push_back(arg); } app.init(args); #else app.init(argc, argv); #endif _serviceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(_serviceStatusHandle, &_serviceStatus); int rc = app.run(); _serviceStatus.dwWin32ExitCode = rc ? ERROR_SERVICE_SPECIFIC_ERROR : 0; _serviceStatus.dwServiceSpecificExitCode = rc; } catch (Exception& exc) { app.logger().log(exc); _serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; _serviceStatus.dwServiceSpecificExitCode = EXIT_CONFIG; } catch (...) { app.logger().error("fatal error - aborting"); _serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; _serviceStatus.dwServiceSpecificExitCode = EXIT_SOFTWARE; } _serviceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(_serviceStatusHandle, &_serviceStatus); }
void ServerApplication::beDaemon() { pid_t pid; if ((pid = fork()) < 0) throw SystemException("cannot fork daemon process"); else if (pid != 0) exit(0); setsid(); umask(0); // attach stdin, stdout, stderr to /dev/null // instead of just closing them. This avoids // issues with third party/legacy code writing // stuff to stdout/stderr. FILE* fin = freopen("/dev/null", "r+", stdin); if (!fin) throw Poco::OpenFileException("Cannot attach stdin to /dev/null"); FILE* fout = freopen("/dev/null", "r+", stdout); if (!fout) throw Poco::OpenFileException("Cannot attach stdout to /dev/null"); FILE* ferr = freopen("/dev/null", "r+", stderr); if (!ferr) throw Poco::OpenFileException("Cannot attach stderr to /dev/null"); }