int runDaemon(DUNE::Daemon& daemon) { setDaemonSignalHandlers(); bool call_abort = false; try { daemon.start(); while (!s_stop) { if (!daemon.isRunning()) { call_abort = true; break; } Delay::wait(1.0); } DUNE_WRN("Daemon", DTR("stopping tasks")); daemon.stopAndJoin(); } catch (std::exception& e) { DUNE_ERR("Daemon", e.what()); return 1; } catch (...) { DUNE_ERR("Daemon", DTR("unhandled exception")); return 1; } if (call_abort) std::abort(); return 0; }
int main(int argc, char** argv) { DUNE::Tasks::Context ctx; Path bin = ctx.dir_app / "dune"; #if defined(DUNE_OS_POSIX) setLauncherSignalHandlers(); Counter<double> delta(c_restart_period); while (!s_stop) { pid_t pid = fork(); if (pid == 0) { char name[PATH_MAX] = {0}; std::strcpy(name, bin.c_str()); argv[0] = name; execv(argv[0], argv); } int rv = waitForDaemon(pid); if (rv == 0) break; if (rv == SIGABRT) DUNE_WRN("Launcher", DTR("execution aborted")); else DUNE_ERR("Launcher", DTR("daemon crashed with signal ") << rv); Delay::wait(2.0); if (delta.overflow()) delta.reset(); } #endif return 0; }
void setDaemonSignalHandlers(void) { // POSIX implementation. #if defined(DUNE_SYS_HAS_SIGACTION) // Install signal handlers. struct sigaction actions; std::memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = handleTerminate; sigaction(SIGALRM, &actions, 0); sigaction(SIGHUP, &actions, 0); sigaction(SIGINT, &actions, 0); sigaction(SIGQUIT, &actions, 0); sigaction(SIGTERM, &actions, 0); sigaction(SIGCHLD, &actions, 0); sigaction(SIGCONT, &actions, 0); sigaction(SIGPIPE, &actions, 0); // Enable core dumps. struct rlimit rlim; rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rlim) == -1) DUNE_WRN("Daemon", "core dumps will not be created"); // Microsoft Windows implementation. #elif defined(DUNE_OS_WINDOWS) SetConsoleCtrlHandler((PHANDLER_ROUTINE)handleTerminate, TRUE); #endif }
void RequestHandler::handleRequest(TCPSocket* sock) { char mtd[16]; char uri[512]; char bfr[c_max_request_size] = {0}; // Search for end of request. unsigned idx = 0; unsigned didx = 0; bool eor = false; while (!eor && (idx < (c_max_request_size - 1))) { int rv = sock->read(bfr + idx, 1); if (rv <= 0) throw ConnectionClosed(); if (didx == 0 && bfr[idx] == '\r') didx = 1; else if (didx == 1 && bfr[idx] == '\n') didx = 2; else if (didx == 2 && bfr[idx] == '\r') didx = 3; else if (didx == 3 && bfr[idx] == '\n') { eor = true; didx = 0; } else didx = 0; ++idx; } // Get header. int size = idx - 4; if (size <= 0) { DUNE_WRN("HTTP", "request too short"); return; } char* hdr = new char[size + 1]; std::memcpy(hdr, bfr, size); hdr[size] = 0; Utils::TupleList headers(hdr, ":", "\r\n", true); // Parse request line. if (std::sscanf(hdr, "%s %s %*s", mtd, uri) == 2) { std::string uri_dec = URL::decode(uri); const char* uri_clean = uri_dec.c_str(); if (std::strcmp(mtd, "GET") == 0) { handleGET(sock, headers, uri_clean); } else if (std::strcmp(mtd, "POST") == 0) { handlePOST(sock, headers, uri_clean); } else if (std::strcmp(mtd, "PUT") == 0) { handlePUT(sock, headers, uri_clean); } } delete[] hdr; }