int sortOutPidFile(char *progName) { int retVal=checkPidFile(OPENPORTD_PID_FILE); if(retVal) { fprintf(stderr,"%s already running (%d)\nRemove pidFile to over ride (%s)\n",progName,retVal,OPENPORTD_PID_FILE); syslog(LOG_ERR,"%s already running (%d)\n",progName,retVal); return -1; } writePidFile(OPENPORTD_PID_FILE); return 0; }
bool initializeServerGlobalState() { Listener::globalTicketHolder.resize(serverGlobalParams.maxConns).transitional_ignore(); #ifndef _WIN32 if (!serverGlobalParams.noUnixSocket && !fs::is_directory(serverGlobalParams.socket)) { cout << serverGlobalParams.socket << " must be a directory" << endl; return false; } #endif if (!serverGlobalParams.pidFile.empty()) { if (!writePidFile(serverGlobalParams.pidFile)) { // error message logged in writePidFile return false; } } int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); if (!serverGlobalParams.keyFile.empty() && clusterAuthMode != ServerGlobalParams::ClusterAuthMode_x509) { if (!setUpSecurityKey(serverGlobalParams.keyFile)) { // error message printed in setUpPrivateKey return false; } } // Auto-enable auth unless we are in mixed auth/no-auth or clusterAuthMode was not provided. // clusterAuthMode defaults to "keyFile" if a --keyFile parameter is provided. if (clusterAuthMode != ServerGlobalParams::ClusterAuthMode_undefined && !serverGlobalParams.transitionToAuth) { getGlobalAuthorizationManager()->setAuthEnabled(true); } #ifdef MONGO_CONFIG_SSL if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_x509 || clusterAuthMode == ServerGlobalParams::ClusterAuthMode_sendX509) { setInternalUserAuthParams( BSON(saslCommandMechanismFieldName << "MONGODB-X509" << saslCommandUserDBFieldName << "$external" << saslCommandUserFieldName << getSSLManager()->getSSLConfiguration().clientSubjectName)); } #endif return true; }
static void signalCallback (int sig) { switch (sig) { case SIGHUP : message (LOG_INFO, "got SIGHUP - reconfiguring\n"); parseArgs (args.argc, args.argv); setupIdleTimer (); break; case SIGTERM : case SIGINT : message (LOG_INFO, "got %s - exiting\n", sig == SIGTERM ? "SIGTERM" : "SIGINT"); writePidFile (NULL); exit (0); break; } }
static void parseArgs (int argc, char * const *argv) { int c, i; args.argc = argc; args.argv = argv; args.progname = basename(*argv); args.verbose = 0; args.daemon = 0; args.allowsleepcommand = setstr(args.allowsleepcommand, NULL); args.cantsleepcommand = setstr(args.cantsleepcommand, NULL); args.sleepcommand = setstr(args.sleepcommand, NULL); args.wakeupcommand = setstr(args.wakeupcommand, NULL); args.displaydimcommand = setstr(args.displaydimcommand, NULL); args.displayundimcommand = setstr(args.displayundimcommand, NULL); args.displaysleepcommand = setstr(args.displaysleepcommand, NULL); args.displaywakeupcommand = setstr(args.displaywakeupcommand, NULL); args.idletimeout = 0; args.idlecommand = setstr(args.idlecommand, NULL); args.idleresume = 0; args.idleresumecommand = setstr(args.idleresumecommand, NULL); args.breaklength = 0; args.resumecommand = setstr(args.resumecommand, NULL); args.plugcommand = setstr(args.plugcommand, NULL); args.unplugcommand = setstr(args.unplugcommand, NULL); writePidFile (NULL); if (argc == 1) usage (); optreset = optind = 1; while ((c = getopt_long(argc, argv, GETOPT_STRING, longopts, &i)) != -1) setOption (c, optarg); if (argc != optind) message (LOG_ERR, "superfluous arguments ignored: \"%s ...\"\n", argv[optind]); checkTimeoutCommand (&args.idletimeout, &args.idlecommand, "idlecommand without timeout ignored\n", "timeout without idlecommand ignored\n"); checkTimeoutCommand (&args.breaklength, &args.resumecommand, "resumecommand without break ignored\n", "break without resumecommand ignored\n"); if (! args.idlecommand && args.idleresumecommand) message (LOG_ERR, "idleresumecommand without idlecommand ignored\n"); if (! args.allowsleepcommand && ! args.cantsleepcommand && ! args.sleepcommand && ! args.wakeupcommand && ! args.displaydimcommand && ! args.displayundimcommand && ! args.displaysleepcommand && ! args.displaywakeupcommand && ! args.idlecommand && ! args.resumecommand && ! args.plugcommand && ! args.unplugcommand) message (LOG_ERR, "no useful options set\n"); }
DaemonTest(std::string const& pidfile) { //install SIGTERM handler struct sigaction tmp; std::memset(&tmp, 0, sizeof(tmp)); tmp.sa_handler = Stop; sigemptyset(&tmp.sa_mask); tmp.sa_flags = 0; struct sigaction oldsig; std::memset(&oldsig, 0, sizeof(oldsig)); if (::sigaction(SIGTERM, &tmp, &oldsig)) throw std::runtime_error("sigaction"); daemonize(); writePidFile(pidfile); }
int main(int argc, char **argv) { int fd; int i; pid_t pid; sigset_t set; mainParseOptions(argc, argv); printf("yang test ... opt_send_signal:%d\r\n", opt_send_signal); if (-1 == opt_send_signal) if (checkRunningPid()) exit(1); enableCoredumps(); writePidFile(); save_argv(argc, argv); init_setproctitle(); init_signals(); sigemptyset(&set); printf("father pid1=%d\n",getpid()); int worker_processes = 3; start_worker_processes(worker_processes, PROCESS_RESPAWN); start_dispatcher_process(PROCESS_RESPAWN); printf("father pid2=%d\n", getpid()); setproctitle("nginx:master"); int live = 1; for (;;) { printf("father before suspend\n"); sigsuspend(&set); printf("father after suspend\n"); if (reap) { reap = 0; fprintf(stderr, "reap children\n"); live = reap_children(); } } return 0; }
int CProcess::startDaemon(const char *szPidFile, const char *szLogFile) { if (getppid() == 1) { return 0; } int pid = fork(); if (pid < 0) exit(1); if (pid > 0) return pid; writePidFile(szPidFile); int fd =open("/dev/null", 0); if (fd != -1) { dup2(fd, 0); close(fd); } SYS_LOGGER.setFileName(szLogFile); return pid; }
/* * main function creates a socket, drops privileges * then calls a function to accept incoming connections in a loop. */ int main(int argc, char **argv, char **envp) { Tcp6Service *svc; srand(time(NULL)); if (signal(SIGCHLD, sigchld) == SIG_ERR) { #ifdef DEBUG err(-1, ERROR_SET_SIGCHLD); #else exit(-1); #endif } int opt; while ((opt = getopt(argc, argv, "c:")) != -1) { switch (opt) { case 'c': conf = parseConf(optarg); break; default: break; } } short svc_port = getShortOption(conf, "SERVER_PORT", 5042); string svc_host = getStringOption(conf, "SERVER_HOST", ""); try { if (svc_host.length() == 0) { svc = new Tcp6Service(svc_port); } else { svc = new Tcp6Service(svc_host.c_str(), svc_port); } } catch (int e) { exit(e); } drop_privs_user(svc_user); daemon(1, 0); writePidFile(); loop(svc); return 0; }
int main (int argc, char * const *argv) { parseArgs (argc, argv); if (args.daemon) { if (daemon(0, 0)) { message (LOG_ERR, "daemonizing failed: %d\n", errno); return (1); } writePidFile (args.pidfile); fclose (stdin); fclose (stdout); fclose (stderr); } signal (SIGHUP, signalCallback); signal (SIGINT, signalCallback); signal (SIGTERM, signalCallback); setupIdleTimer (); initializeResumeNotifications (); initializePowerNotifications (); initializeDisplayNotifications (); initializePowerSourceNotifications (); CFRunLoopRun (); return (0); }
int main(int argc, char **argv) { int err; server_init(); parse_arguments(argc, argv); log_set_file(logFile); if (nodaemon == 0) { err = daemonise(); if (err != 0) exit(1); err = writePidFile(pidFile); if (err != 0) exit(1); err = drop_privileges(); if (err != 0) exit(1); } err = signalisation(); if (err != 0) exit(1); serverSocket = openServerSocket(NULL, port); if (serverSocket == -1) exit(1); log_info("Server ready for connections"); request_t req; response_t resp; memset(&req, 0, sizeof(request_t)); memset(&resp, 0, sizeof(response_t)); while (serverSocket != -1) { int client = serverSocketAccept(serverSocket); if (client == -1) { continue; } int r = parseRequest(client, &req, &resp); if (r != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status); closeClient(client); continue; } log_info("Request: %s", req.path); if (1) { list_t* l = req.args; while (l) { pair_t* p = (pair_t*) l->data; log_debug("args[]: %s = %s", p->name, p->value); l = l->next; } l = req.headers; while (l) { pair_t* p = (pair_t*) l->data; log_debug("headers[]: '%s': '%s'", p->name, p->value); l = l->next; } } server_handle_request(&req, &resp); // Debug printf if (resp.status != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n" "Content-Length: %d\r\n" "Content-Type: %s\r\n" "\r\n", resp.status, resp.length, resp.content_type); clientWrite(client, resp.body, resp.length); } else { log_err("main.c, request status == 0, request not handle!"); } closeClient(client); request_clear(&req); response_clear(&resp); } removePidFile(pidFile); return 0; }
int main( int argc, char ** argv ) { int ch; strcpy( progname, "ufdbhttpd" ); globalPid = getpid(); globalErrorLog = NULL; closeAllFiles(); ufdbSetGlobalErrorLogFile(); while ((ch = getopt(argc, argv, "Ddhi:p:I:l:L:U:V")) > 0) { switch (ch) { case 'D': /* undocumented -D option: do not daemonize */ runAsDaemon = 0; break; case 'd': UFDBglobalDebug = 1; runAsDaemon = 0; break; case 'i': strcpy( interface, optarg ); break; case 'p': portnumber = atoi( optarg ); break; case 'I': strcpy( imagesDirectory, optarg ); break; case 'l': UFDBglobalLogDir = optarg; break; case 'L': /* undocumented -L option for alternate PID file */ globalPidFile = optarg; break; case 'U': if (strlen(optarg) <= 31) strcpy( UFDBglobalUserName, optarg ); else ufdbLogFatalError( "username supplied with -U option is too long" ); break; case 'V': UFDBglobalDebugHttpd = 1; break; case '?': case 'h': default: usage(); } } if (UFDBglobalLogDir == NULL || imagesDirectory[0] == '\0' || portnumber <= 0) { ufdbLogFatalError( "%s started with incorrect parameters. aborting...", progname ); usage(); exit( 1 ); } if (runAsDaemon) { pid_t pid; if ((pid = fork()) != 0) /* the parent exits */ { exit( 0 ); } if (setsid() < 0) ufdbLogFatalError( "cannot create daemon session: %s", strerror(errno) ); } globalPid = getpid(); ufdbSetSignalHandler( SIGPIPE, SIG_IGN ); ufdbSetSignalHandler( SIGUSR1, USR1signalReceived ); ufdbSetSignalHandler( SIGHUP, mySignalHandler ); ufdbSetSignalHandler( SIGINT, mySignalHandler ); ufdbSetSignalHandler( SIGTERM, TermHandler ); writePidFile(); atexit( removePidFile ); ufdbLogMessage( "%s " VERSION " started\ninterface=%s port=%d images=%s", progname, interface, portnumber, imagesDirectory ); if (UFDBglobalDebug) ufdbLogMessage( "debug option is ON" ); if (UFDBglobalDebugHttpd) ufdbLogMessage( "HTTP debug option is ON" ); if (UFDBglobalUserName[0] != '\0') ufdbLogMessage( "dropping privileges to user %s", UFDBglobalUserName ); ufdbSimulateHttpServer( interface, portnumber, UFDBglobalUserName, imagesDirectory, 0 ); exit( 0 ); return 0; /* make compiler happy */ }
int initService(int argc, char *argv[]) { int i; char *optpattern = "hl:p:s:e"; char *prog = argv[0]; char *p = NULL; string logDir = "/tmp"; int logLevel = Log::INFORMATION; int logMode = Log::DISABLE; #if defined(_SCI_LINUX) || defined(__APPLE__) string pidDir = "/var/run/"; #else string pidDir = "/var/opt/"; #endif string logFile; extern char *optarg; extern int optind; p = strrchr(prog, '/'); if (p != NULL) p++; else p = prog; while ((i = getopt(argc, argv, optpattern)) != EOF) { switch (i) { case 'l': logDir = optarg; break ; case 'p': pidDir = optarg; break; case 's': logLevel = atoi(optarg); break; case 'e': logMode = Log::ENABLE; break; case 'h': usage(p); exit(0); break; } } pidFile = pidDir + "/" + p + ".pid"; if (checkPidFile(pidFile) < 0) { printf("%s is already running...\n", p); return -1; } if (getuid() != 0) { printf("Must running as root\n"); return -1; } daemonInit(); writePidFile(pidFile); logFile = string(p) + ".log"; Log::getInstance()->init(logDir.c_str(), logFile.c_str(), logLevel, logMode); return 0; }
bool CmdLine::store( int argc , char ** argv , boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, boost::program_options::variables_map ¶ms ) { { // setup binary name cmdLine.binaryName = argv[0]; size_t i = cmdLine.binaryName.rfind( '/' ); if ( i != string::npos ) cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 ); // setup cwd char buffer[1024]; #ifdef _WIN32 verify( _getcwd( buffer , 1000 ) ); #else verify( getcwd( buffer , 1000 ) ); #endif cmdLine.cwd = buffer; } /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ int style = (((po::command_line_style::unix_style ^ po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); try { po::options_description all; all.add( visible ); all.add( hidden ); po::store( po::command_line_parser(argc, argv) .options( all ) .positional( positional ) .style( style ) .run(), params ); if ( params.count("config") ) { ifstream f( params["config"].as<string>().c_str() ); if ( ! f.is_open() ) { cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } stringstream ss; CmdLine::parseConfigFile( f, ss ); po::store( po::parse_config_file( ss , all ) , params ); f.close(); } po::notify(params); } catch (po::error &e) { cout << "error command line: " << e.what() << endl; cout << "use --help for help" << endl; //cout << visible << endl; return false; } if (params.count("verbose")) { logLevel = 1; } for (string s = "vv"; s.length() <= 12; s.append("v")) { if (params.count(s)) { logLevel = s.length(); } } if (params.count("quiet")) { cmdLine.quiet = true; } if (params.count("traceExceptions")) { DBException::traceExceptions = true; } if ( params.count( "maxConns" ) ) { int newSize = params["maxConns"].as<int>(); if ( newSize < 5 ) { out() << "maxConns has to be at least 5" << endl; ::_exit( EXIT_BADOPTIONS ); } else if ( newSize >= 10000000 ) { out() << "maxConns can't be greater than 10000000" << endl; ::_exit( EXIT_BADOPTIONS ); } connTicketHolder.resize( newSize ); } if (params.count("objcheck")) { cmdLine.objcheck = true; } if (params.count("bind_ip")) { // passing in wildcard is the same as default behavior; remove and warn if ( cmdLine.bind_ip == "0.0.0.0" ) { cout << "warning: bind_ip of 0.0.0.0 is unnecessary; listens on all ips by default" << endl; cmdLine.bind_ip = ""; } } string logpath; #ifndef _WIN32 if (params.count("unixSocketPrefix")) { cmdLine.socket = params["unixSocketPrefix"].as<string>(); if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; ::_exit(-1); } } if (params.count("nounixsocket")) { cmdLine.noUnixSocket = true; } if (params.count("fork") && !params.count("shutdown")) { cmdLine.doFork = true; if ( ! params.count( "logpath" ) && ! params.count( "syslog" ) ) { cout << "--fork has to be used with --logpath or --syslog" << endl; ::_exit(EXIT_BADOPTIONS); } if ( params.count( "logpath" ) ) { // test logpath logpath = params["logpath"].as<string>(); verify( logpath.size() ); if ( logpath[0] != '/' ) { logpath = cmdLine.cwd + "/" + logpath; } bool exists = boost::filesystem::exists( logpath ); FILE * test = fopen( logpath.c_str() , "a" ); if ( ! test ) { cout << "can't open [" << logpath << "] for log file: " << errnoWithDescription() << endl; ::_exit(-1); } fclose( test ); // if we created a file, unlink it (to avoid confusing log rotation code) if ( ! exists ) { unlink( logpath.c_str() ); } } cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); pid_t c = fork(); if ( c ) { int pstat; waitpid(c, &pstat, 0); if ( WIFEXITED(pstat) ) { if ( ! WEXITSTATUS(pstat) ) { cout << "child process started successfully, parent exiting" << endl; } _exit( WEXITSTATUS(pstat) ); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t c2 = fork(); if ( c2 ) { int pstat; cout << "forked process: " << c2 << endl; waitpid(c2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; ::_exit(-1); } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; ::_exit(-1); } } setupSignals( true ); if (params.count("syslog")) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (params.count("logpath") && !params.count("shutdown")) { if ( params.count("syslog") ) { cout << "Cant use both a logpath and syslog " << endl; ::_exit(EXIT_BADOPTIONS); } if ( logpath.size() == 0 ) logpath = params["logpath"].as<string>(); uassert( 10033 , "logpath has to be non-zero" , logpath.size() ); initLogging( logpath , params.count( "logappend" ) ); } if ( params.count("pidfilepath")) { writePidFile( params["pidfilepath"].as<string>() ); } if (params.count("keyFile")) { const string f = params["keyFile"].as<string>(); if (!setUpSecurityKey(f)) { // error message printed in setUpPrivateKey ::_exit(EXIT_BADOPTIONS); } cmdLine.keyFile = true; noauth = false; } else { cmdLine.keyFile = false; } #ifdef MONGO_SSL if (params.count("sslOnNormalPorts") ) { cmdLine.sslOnNormalPorts = true; if ( cmdLine.sslPEMKeyPassword.size() == 0 ) { log() << "need sslPEMKeyPassword" << endl; ::_exit(EXIT_BADOPTIONS); } if ( cmdLine.sslPEMKeyFile.size() == 0 ) { log() << "need sslPEMKeyFile" << endl; ::_exit(EXIT_BADOPTIONS); } cmdLine.sslServerManager = new SSLManager( false ); if ( ! cmdLine.sslServerManager->setupPEM( cmdLine.sslPEMKeyFile , cmdLine.sslPEMKeyPassword ) ) { ::_exit(EXIT_BADOPTIONS); } } else if ( cmdLine.sslPEMKeyFile.size() || cmdLine.sslPEMKeyPassword.size() ) { log() << "need to enable sslOnNormalPorts" << endl; ::_exit(EXIT_BADOPTIONS); } #endif { BSONObjBuilder b; for (po::variables_map::const_iterator it(params.begin()), end(params.end()); it != end; it++){ if (!it->second.defaulted()){ const string& key = it->first; const po::variable_value& value = it->second; const type_info& type = value.value().type(); if (type == typeid(string)){ if (value.as<string>().empty()) b.appendBool(key, true); // boost po uses empty string for flags like --quiet else { if ( key == "servicePassword" || key == "sslPEMKeyPassword" ) { b.append( key, "<password>" ); } else { b.append( key, value.as<string>() ); } } } else if (type == typeid(int)) b.append(key, value.as<int>()); else if (type == typeid(double)) b.append(key, value.as<double>()); else if (type == typeid(bool)) b.appendBool(key, value.as<bool>()); else if (type == typeid(long)) b.appendNumber(key, (long long)value.as<long>()); else if (type == typeid(unsigned)) b.appendNumber(key, (long long)value.as<unsigned>()); else if (type == typeid(unsigned long long)) b.appendNumber(key, (long long)value.as<unsigned long long>()); else if (type == typeid(vector<string>)) b.append(key, value.as<vector<string> >()); else b.append(key, "UNKNOWN TYPE: " + demangleName(type)); } } parsedOpts = b.obj(); } { BSONArrayBuilder b; for (int i=0; i < argc; i++) { b << argv[i]; if ( mongoutils::str::equals(argv[i], "--sslPEMKeyPassword") || mongoutils::str::equals(argv[i], "-sslPEMKeyPassword") || mongoutils::str::equals(argv[i], "--servicePassword") || mongoutils::str::equals(argv[i], "-servicePassword")) { b << "<password>"; i++; // hide password from ps output char* arg = argv[i]; while (*arg) { *arg++ = 'x'; } } } argvArray = b.arr(); } return true; }
int Service::run() { writeCommandFile(); writeOptionsFile(); logUser("Info: Starting daemon: '%s'", getID()); #ifdef __CYGWIN32__ if ((pid_ = waitFork()) != 0) #else if ((pid_ = fork()) != 0) #endif { if (pid_ < 0) { logUser("Error: Fork failed."); } else { #ifdef DEBUG logUser("Info: Created process with pid=%d", pid_); #endif } writePidFile(); // // The parent waits for a signal or a log // to know if its child (the service) starts // successfully. // if (pid_ > 0) { checkServiceStart(); } return pid_; } #ifdef DEBUG logUser("Info: Executing child with pid=%d and ppid=%d", getpid(), getppid()); #endif if (execvp(executablePath_, (char *const *) arguments_) == -1) { logUser("Error: Cannot execute '%s'. Error: '%s'", executablePath_, strerror(errno)); exit(-1); } /* * checkServiceStart() get rid of this. * exit(0); */ // // just to shut up the compiler // return 0; }
bool initializeServerGlobalState(bool isMongodShutdownSpecialCase) { Listener::globalTicketHolder.resize( cmdLine.maxConns ); #ifndef _WIN32 if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; return false; } if (cmdLine.doFork) { fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog); cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); cout << "about to fork child process, waiting until server is ready for connections." << endl; pid_t child1 = fork(); if (child1 == -1) { cout << "ERROR: stage 1 fork() failed: " << errnoWithDescription(); _exit(EXIT_ABRUPT); } else if (child1) { // this is run in the original parent process int pstat; waitpid(child1, &pstat, 0); if (WIFEXITED(pstat)) { if (WEXITSTATUS(pstat)) { cout << "ERROR: child process failed, exited with error number " << WEXITSTATUS(pstat) << endl; } else { cout << "child process started successfully, parent exiting" << endl; } _exit(WEXITSTATUS(pstat)); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t child2 = fork(); if (child2 == -1) { cout << "ERROR: stage 2 fork() failed: " << errnoWithDescription(); _exit(EXIT_ABRUPT); } else if (child2) { // this is run in the middle process int pstat; cout << "forked process: " << child2 << endl; waitpid(child2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // this is run in the final child process (the server) // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; return false; } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; return false; } } if (cmdLine.logWithSyslog) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (!cmdLine.logpath.empty() && !isMongodShutdownSpecialCase) { fassert(16448, !cmdLine.logWithSyslog); string absoluteLogpath = boost::filesystem::absolute( cmdLine.logpath, cmdLine.cwd).string(); if (!initLogging(absoluteLogpath, cmdLine.logAppend)) { cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl; return false; } } if (!cmdLine.pidFile.empty()) { writePidFile(cmdLine.pidFile); } if (!cmdLine.keyFile.empty()) { if (!setUpSecurityKey(cmdLine.keyFile)) { // error message printed in setUpPrivateKey return false; } AuthorizationManager::setAuthEnabled(true); } return true; }
int main(int argc, char *argv[]) { struct if_config_options *default_ifcnf; char conf_file_name[FILENAME_MAX]; struct ipaddr_str buf; bool loadedConfig = false; int i; #ifdef __linux__ struct interface *ifn; #endif /* __linux__ */ #ifdef _WIN32 WSADATA WsaData; size_t len; #endif /* __linux__ */ /* paranoia checks */ assert(sizeof(uint8_t) == 1); assert(sizeof(uint16_t) == 2); assert(sizeof(uint32_t) == 4); assert(sizeof(int8_t) == 1); assert(sizeof(int16_t) == 2); assert(sizeof(int32_t) == 4); printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n", olsrd_version, build_date, build_host); if (argc == 2) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "/?") == 0) { print_usage(false); exit(0); } if (strcmp(argv[1], "-v") == 0) { exit(0); } } debug_handle = stdout; #ifndef _WIN32 olsr_argv = argv; #endif /* _WIN32 */ setbuf(stdout, NULL); setbuf(stderr, NULL); #ifndef _WIN32 /* Check if user is root */ if (geteuid()) { fprintf(stderr, "You must be root(uid = 0) to run olsrd!\nExiting\n\n"); exit(EXIT_FAILURE); } #else /* _WIN32 */ DisableIcmpRedirects(); if (WSAStartup(0x0202, &WsaData)) { fprintf(stderr, "Could not initialize WinSock.\n"); olsr_exit(__func__, EXIT_FAILURE); } #endif /* _WIN32 */ /* Open syslog */ olsr_openlog("olsrd"); /* setup random seed */ initRandom(); /* Init widely used statics */ memset(&all_zero, 0, sizeof(union olsr_ip_addr)); /* * Set configfile name and * check if a configfile name was given as parameter */ #ifdef _WIN32 #ifndef WINCE GetWindowsDirectory(conf_file_name, FILENAME_MAX - 11); #else /* WINCE */ conf_file_name[0] = 0; #endif /* WINCE */ len = strlen(conf_file_name); if (len == 0 || conf_file_name[len - 1] != '\\') conf_file_name[len++] = '\\'; strscpy(conf_file_name + len, "olsrd.conf", sizeof(conf_file_name) - len); #else /* _WIN32 */ strscpy(conf_file_name, OLSRD_GLOBAL_CONF_FILE, sizeof(conf_file_name)); #endif /* _WIN32 */ olsr_cnf = olsrd_get_default_cnf(); for (i=1; i < argc-1;) { if (strcmp(argv[i], "-f") == 0) { loadedConfig = true; if (olsrmain_load_config(argv[i+1]) < 0) { exit(EXIT_FAILURE); } if (i+2 < argc) { memmove(&argv[i], &argv[i+2], sizeof(*argv) * (argc-i-1)); } argc -= 2; } else { i++; } } /* * set up configuration prior to processing commandline options */ if (!loadedConfig && olsrmain_load_config(conf_file_name) == 0) { loadedConfig = true; } if (!loadedConfig) { olsrd_free_cnf(olsr_cnf); olsr_cnf = olsrd_get_default_cnf(); } default_ifcnf = get_default_if_config(); if (default_ifcnf == NULL) { fprintf(stderr, "No default ifconfig found!\n"); exit(EXIT_FAILURE); } /* Initialize timers */ olsr_init_timers(); /* * Process olsrd options. */ if (olsr_process_arguments(argc, argv, olsr_cnf, default_ifcnf) < 0) { print_usage(true); olsr_exit(__func__, EXIT_FAILURE); } /* * Set configuration for command-line specified interfaces */ set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf); /* free the default ifcnf */ free(default_ifcnf); /* Sanity check configuration */ if (olsrd_sanity_check_cnf(olsr_cnf) < 0) { fprintf(stderr, "Bad configuration!\n"); olsr_exit(__func__, EXIT_FAILURE); } /* * Establish file lock to prevent multiple instances */ if (olsr_cnf->lock_file) { strscpy(lock_file_name, olsr_cnf->lock_file, sizeof(lock_file_name)); } else { size_t l; #ifdef DEFAULT_LOCKFILE_PREFIX strscpy(lock_file_name, DEFAULT_LOCKFILE_PREFIX, sizeof(lock_file_name)); #else /* DEFAULT_LOCKFILE_PREFIX */ strscpy(lock_file_name, conf_file_name, sizeof(lock_file_name)); #endif /* DEFAULT_LOCKFILE_PREFIX */ l = strlen(lock_file_name); snprintf(&lock_file_name[l], sizeof(lock_file_name) - l, "-ipv%d.lock", olsr_cnf->ip_version == AF_INET ? 4 : 6); } def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER); /* * socket for ioctl calls */ olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0); if (olsr_cnf->ioctl_s < 0) { #ifndef _WIN32 olsr_syslog(OLSR_LOG_ERR, "ioctl socket: %m"); #endif /* _WIN32 */ olsr_exit(__func__, 0); } #ifdef __linux__ olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); if (olsr_cnf->rtnl_s < 0) { olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m"); olsr_exit(__func__, 0); } if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) { olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking"); } if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) { olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m"); olsr_exit(__func__, 0); } #endif /* __linux__ */ /* * create routing socket */ #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0); if (olsr_cnf->rts < 0) { olsr_syslog(OLSR_LOG_ERR, "routing socket: %m"); olsr_exit(__func__, 0); } #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */ #ifdef __linux__ /* initialize gateway system */ if (olsr_cnf->smart_gw_active) { if (olsr_init_gateways()) { olsr_exit("Cannot initialize gateway tunnels", 1); } } /* initialize niit if index */ if (olsr_cnf->use_niit) { olsr_init_niit(); } #endif /* __linux__ */ /* Init empty TC timer */ set_empty_tc_timer(GET_TIMESTAMP(0)); /* enable ip forwarding on host */ /* Disable redirects globally (not for WIN32) */ net_os_set_global_ifoptions(); /* Initialize parser */ olsr_init_parser(); /* Initialize route-exporter */ olsr_init_export_route(); /* Initialize message sequencnumber */ init_msg_seqno(); /* Initialize dynamic willingness calculation */ olsr_init_willingness(); /* *Set up willingness/APM */ if (olsr_cnf->willingness_auto) { if (apm_init() < 0) { OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT); olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT); olsr_cnf->willingness_auto = 0; olsr_cnf->willingness = WILL_DEFAULT; } else { olsr_cnf->willingness = olsr_calculate_willingness(); OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double)olsr_cnf->will_int); } } /* Initialize net */ init_net(); /* Initializing networkinterfaces */ if (!olsr_init_interfacedb()) { if (olsr_cnf->allow_no_interfaces) { fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean that your configuration is fubar.\nI will continue after 5 seconds...\n"); olsr_startup_sleep(5); } else { fprintf(stderr, "No interfaces detected!\nBailing out!\n"); olsr_exit(__func__, EXIT_FAILURE); } } olsr_do_startup_sleep(); /* Print heartbeat to stdout */ #if !defined WINCE if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) { olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0); } #endif /* !defined WINCE */ /* Initialize the IPC socket */ if (olsr_cnf->ipc_connections > 0) { if (ipc_init()) { olsr_exit("ipc_init failure", 1); } } /* Initialisation of different tables to be used. */ olsr_init_tables(); /* daemon mode */ #ifndef _WIN32 if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) { printf("%s detaching from the current process...\n", olsrd_version); if (daemon(0, 0) < 0) { printf("daemon(3) failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } #endif /* _WIN32 */ writePidFile(); /* * Create locking file for olsrd, will be cleared after olsrd exits */ for (i=5; i>=0; i--) { OLSR_PRINTF(3, "Trying to get olsrd lock...\n"); if (!olsr_cnf->host_emul && olsr_create_lock_file(i > 0) == 0) { /* lock sucessfully created */ break; } sleep (1); } /* Load plugins */ olsr_load_plugins(); OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr)); #ifdef __linux__ /* create policy routing rules with priorities if necessary */ if (DEF_RT_NONE != olsr_cnf->rt_table_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true); } if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true); } if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true); } /* rule to default table on all olsrd interfaces */ if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) { for (ifn = ifnet; ifn; ifn = ifn->int_next) { olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true); } } /* trigger gateway selection */ if (olsr_cnf->smart_gw_active) { olsr_trigger_inetgw_startup(); } /* trigger niit static route setup */ if (olsr_cnf->use_niit) { olsr_setup_niit_routes(); } /* create lo:olsr interface */ if (olsr_cnf->use_src_ip_routes) { olsr_os_localhost_if(&olsr_cnf->main_addr, true); } #endif /* __linux__ */ /* Start syslog entry */ olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version); /* *signal-handlers */ /* ctrl-C and friends */ #ifdef _WIN32 #ifndef WINCE SetConsoleCtrlHandler(SignalHandler, true); #endif /* WINCE */ #else /* _WIN32 */ signal(SIGHUP, olsr_reconfigure); signal(SIGINT, olsr_shutdown); signal(SIGQUIT, olsr_shutdown); signal(SIGILL, olsr_shutdown); signal(SIGABRT, olsr_shutdown); // signal(SIGSEGV, olsr_shutdown); signal(SIGTERM, olsr_shutdown); signal(SIGPIPE, SIG_IGN); // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); #endif /* _WIN32 */ link_changes = false; /* Starting scheduler */ olsr_scheduler(); /* Like we're ever going to reach this ;-) */ return 1; } /* main */
//SIGPIPE是正常的信号,对端断开后本端协议栈在向对端传送数据时,对端会返回TCP RST,导致本端抛出SIGPIPE信号 void init_daemon(char* cmd) { int pid; char *buf = "This is a Daemon, wcdj\n"; char path[FILEPATH_MAX]; getRealPath(path); strcat(path,"/"); strcat(path,"pushserver.lock"); pid = readPidFile(path); if(pid != -1) { printf("The server is start ...\n"); } if(strcmp(cmd,"stop") == 0 && pid != -1){ closeServer(pid,0); int status; int w; do { w = waitpid(pid, &status, WUNTRACED | WCONTINUED); if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("exited, status=%d/n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d/n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d/n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued/n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); exit(0); } else if(strcmp(cmd,"restart") == 0 && pid != -1){ int status; int w; do { w = waitpid(pid, &status, WUNTRACED | WCONTINUED); if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("exited, status=%d/n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d/n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d/n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued/n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); }else if(pid != -1){ printf("The server is start ...\n"); exit(0); } /* 屏蔽一些有关控制终端操作的信号 * 防止在守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起 */ signal(SIGINT, SIG_IGN);// 终端中断 signal(SIGHUP, SIG_IGN);// 连接挂断 signal(SIGQUIT, SIG_IGN);// 终端退出 signal(SIGPIPE, SIG_IGN);// 向无读进程的管道写数据 signal(SIGTTOU, SIG_IGN);// 后台程序尝试写操作 signal(SIGTTIN, SIG_IGN);// 后台程序尝试读操作 signal(SIGTERM, SIG_IGN);// 终止 struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) < 0) printf("%s: can't get file limit", "pushserver"); int i; /* pid=fork(); if(pid>0) exit(0);//是父进程,结束父进程 else if(pid< 0) exit(1);//fork失败,退出 //是第一子进程,后台继续执行 setsid();//第一子进程成为新的会话组长和进程组长 //并与控制终端分离 pid=fork(); if(pid>0) exit(0);//是第一子进程,结束第一子进程 else if(pid< 0) exit(1);//fork失败,退出 */ if ((pid = fork()) < 0) printf("%s: can't fork", cmd); else if (pid != 0) /* parent */{ printf("tuichuzhu\n"); exit(0); } printf("jinlaile\n"); setsid(); //是第二子进程,继续 //第二子进程不再是会话组长 main_pid = getpid(); writePidFile(path); for(i=3;i< NOFILE;++i)//关闭打开的文件描述符 MAXFILE 65536 close(i); /* // [3] set current path char szPath[1024]; if(getcwd(szPath, sizeof(szPath)) == NULL) { perror("getcwd"); exit(1); } else { chdir(szPath); printf("set current path succ [%s]\n", szPath); } */ //chdir("/tmp");//改变工作目录到/tmp umask(0);//重设文件创建掩模 // [6] set termianl signal signal(SIGTERM, wait_close); signal(SIGHUP, restart_server); /* * Close all open file descriptors. */ if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; for (i = 0; i < rl.rlim_max; i++) close(i); /* * Attach file descriptors 0, 1, and 2 to /dev/null. */ int fd0 = open("/dev/null", O_RDWR); int fd1 = dup(0); int fd2 = dup(0); /* * Initialize the log file. */ openlog("pushserver", LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2); exit(1); } syslog(LOG_DEBUG, "daem ok "); return; }
static void setOption (const char c, char *optarg) { switch (c) { case 'n' : exit (sleepImmediately()); break; case 'v' : copyright (); break; case 'V' : args.verbose = 1; break; case 'd' : args.daemon = 1; break; case 'g' : printf ("%ld\n", getIdleTime()); exit (0); break; case 'f' : readConfig (optarg); break; case 'p' : writePidFile (optarg); break; case 'a' : if (args.allowsleepcommand == DENY_SLEEP) args.allowsleepcommand = NULL; args.allowsleepcommand = setstr(args.allowsleepcommand, optarg); if (args.allowsleepcommand == NULL) args.allowsleepcommand = DENY_SLEEP; break; case 'c' : args.cantsleepcommand = setstr(args.cantsleepcommand, optarg); break; case 's' : args.sleepcommand = setstr(args.sleepcommand, optarg); break; case 'w' : args.wakeupcommand = setstr(args.wakeupcommand, optarg); break; case 'D' : args.displaydimcommand = setstr(args.displaydimcommand, optarg); break; case 'E' : args.displayundimcommand = setstr(args.displayundimcommand, optarg); break; case 'S' : args.displaysleepcommand = setstr(args.displaysleepcommand, optarg); break; case 'W' : args.displaywakeupcommand = setstr(args.displaywakeupcommand, optarg); break; case 't' : args.idletimeout = scanTime(optarg, "invalid digit(s) in timeout argument '%s'\n"); break; case 'i' : args.idlecommand = setstr(args.idlecommand, optarg); break; case 'R' : args.idleresume = 0; args.idleresumecommand = setstr(args.idleresumecommand, optarg); break; case 'b' : args.breaklength = scanTime(optarg, "invalid digit(s) in pause argument '%s'\n"); break; case 'r' : args.resumecommand = setstr(args.resumecommand, optarg); break; case 'P' : args.plugcommand = setstr(args.plugcommand, optarg); break; case 'U' : args.unplugcommand = setstr(args.unplugcommand, optarg); break; default : exit (2); break; } }
bool CmdLine::store( int argc , char ** argv , boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, boost::program_options::variables_map ¶ms ){ /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ int style = (((po::command_line_style::unix_style ^ po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); try { po::options_description all; all.add( visible ); all.add( hidden ); po::store( po::command_line_parser(argc, argv) .options( all ) .positional( positional ) .style( style ) .run(), params ); if ( params.count("config") ){ ifstream f( params["config"].as<string>().c_str() ); if ( ! f.is_open() ){ cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } po::store( po::parse_config_file( f , all ) , params ); f.close(); } po::notify(params); } catch (po::error &e) { cout << "ERROR: " << e.what() << endl << endl; cout << visible << endl; return false; } if (params.count("verbose")) { logLevel = 1; } for (string s = "vv"; s.length() <= 12; s.append("v")) { if (params.count(s)) { logLevel = s.length(); } } if (params.count("quiet")) { cmdLine.quiet = true; } #ifndef _WIN32 if (params.count("fork")) { if ( ! params.count( "logpath" ) ){ cout << "--fork has to be used with --logpath" << endl; ::exit(-1); } cout.flush(); cerr.flush(); pid_t c = fork(); if ( c ){ _exit(0); } if ( chdir("/") < 0 ){ cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::exit(-1); } setsid(); pid_t c2 = fork(); if ( c2 ){ cout << "forked process: " << c2 << endl; _exit(0); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ){ cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; ::exit(-1); } f = freopen("/dev/null", "r", stdin); if ( f == NULL ){ cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; ::exit(-1); } setupCoreSignals(); setupSignals(); } #endif if (params.count("logpath")) { string lp = params["logpath"].as<string>(); uassert( 10033 , "logpath has to be non-zero" , lp.size() ); initLogging( lp , params.count( "logappend" ) ); } if ( params.count("pidfilepath")) { writePidFile( params["pidfilepath"].as<string>() ); } { BSONArrayBuilder b; for (int i=0; i < argc; i++) b << argv[i]; argvArray = b.arr(); } return true; }
int main(int argc, char **argv) { int err; parseArguments(argc, argv); if (nodaemon == 0) { err = daemonise(); if (err != 0) exit(1); err = writePidFile(pidFile); if (err != 0) exit(1); } err = signalisation(); if (err != 0) exit(1); serverSocket = openServerSocket(port); if (serverSocket == -1) exit(1); request_t req; response_t resp; output_t output; memset(&output, 0, sizeof(output_t)); while (serverSocket != -1) { memset(&req, 0, sizeof(request_t)); memset(&resp, 0, sizeof(response_t)); int client = serverSocketAccept(serverSocket); if (client == -1) continue; int r = parseRequest(client, &req, &resp); if (r != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status); closeClient(client); continue; } if (1) { printf("path: %s\n", req.path); for (int i =0; i < req.num_args; i++) printf("arg[%d]: %s = %s\n", i, req.names[i], req.values[i]); } const char* cmdline = findCommand(req.path); if (cmdline == NULL) { log_warn("Daemon: Invalid path: '%s'\n", req.path); clientPrint(client, "HTTP/1.1 404\r\n"); closeClient(client); continue; } if (execute(&output, cmdline) != 0) { clientPrint(client, "HTTP/1.1 500\r\n"); // Internal server error closeClient(client); continue; } if ((output.count > 8) && (strncmp(output.buf, "HTTP/1.1", 8) == 0)) { clientWrite(client, output.buf, output.count); } else { clientPrintf(client, "HTTP/1.1 200\r\nContent-Length: %d\r\n\r\n", output.count); clientWrite(client, output.buf, output.count); } closeClient(client); output_clear(&output); if (req.path) free(req.path); } removePidFile(pidFile); return 0; }
bool initializeServerGlobalState(bool isMongodShutdownSpecialCase) { Listener::globalTicketHolder.resize( cmdLine.maxConns ); #ifndef _WIN32 if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; return false; } if (cmdLine.doFork) { fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog); cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); pid_t c = fork(); if ( c ) { int pstat; waitpid(c, &pstat, 0); if ( WIFEXITED(pstat) ) { if ( ! WEXITSTATUS(pstat) ) { cout << "child process started successfully, parent exiting" << endl; } _exit( WEXITSTATUS(pstat) ); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t c2 = fork(); if ( c2 ) { int pstat; cout << "forked process: " << c2 << endl; waitpid(c2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; return false; } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; return false; } setupCoreSignals(); setupSignals( true ); } if (cmdLine.logWithSyslog) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (!cmdLine.logpath.empty() && !isMongodShutdownSpecialCase) { fassert(16448, !cmdLine.logWithSyslog); string absoluteLogpath = boost::filesystem::absolute( cmdLine.logpath, cmdLine.cwd).string(); if (!initLogging(absoluteLogpath, cmdLine.logAppend)) { cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl; return false; } } if (!cmdLine.pidFile.empty()) { writePidFile(cmdLine.pidFile); } if (!cmdLine.keyFile.empty()) { if (!setUpSecurityKey(cmdLine.keyFile)) { // error message printed in setUpPrivateKey return false; } noauth = false; } #ifdef MONGO_SSL if (cmdLine.sslOnNormalPorts) { if ( cmdLine.sslPEMKeyPassword.size() == 0 ) { log() << "need sslPEMKeyPassword" << endl; return false; } if ( cmdLine.sslPEMKeyFile.size() == 0 ) { log() << "need sslPEMKeyFile" << endl; return false; } cmdLine.sslServerManager = new SSLManager( false ); if ( ! cmdLine.sslServerManager->setupPEM( cmdLine.sslPEMKeyFile , cmdLine.sslPEMKeyPassword ) ) { return false; } } else if ( cmdLine.sslPEMKeyFile.size() || cmdLine.sslPEMKeyPassword.size() ) { log() << "need to enable sslOnNormalPorts" << endl; return false; } #endif return true; }
bool CmdLine::store( int argc , char ** argv , boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, boost::program_options::variables_map ¶ms ){ { // setup binary name cmdLine.binaryName = argv[0]; size_t i = cmdLine.binaryName.rfind( '/' ); if ( i != string::npos ) cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 ); } /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ int style = (((po::command_line_style::unix_style ^ po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); try { po::options_description all; all.add( visible ); all.add( hidden ); po::store( po::command_line_parser(argc, argv) .options( all ) .positional( positional ) .style( style ) .run(), params ); if ( params.count("config") ){ ifstream f( params["config"].as<string>().c_str() ); if ( ! f.is_open() ){ cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } po::store( po::parse_config_file( f , all ) , params ); f.close(); } po::notify(params); } catch (po::error &e) { cout << "error command line: " << e.what() << endl; cout << "use --help for help" << endl; //cout << visible << endl; return false; } if (params.count("verbose")) { logLevel = 1; } for (string s = "vv"; s.length() <= 12; s.append("v")) { if (params.count(s)) { logLevel = s.length(); } } if (params.count("quiet")) { cmdLine.quiet = true; } string logpath; #ifndef _WIN32 if (params.count("fork")) { if ( ! params.count( "logpath" ) ){ cout << "--fork has to be used with --logpath" << endl; ::exit(-1); } { // test logpath logpath = params["logpath"].as<string>(); assert( logpath.size() ); if ( logpath[0] != '/' ){ char temp[256]; assert( getcwd( temp , 256 ) ); logpath = (string)temp + "/" + logpath; } FILE * test = fopen( logpath.c_str() , "a" ); if ( ! test ){ cout << "can't open [" << logpath << "] for log file: " << errnoWithDescription() << endl; ::exit(-1); } fclose( test ); } cout.flush(); cerr.flush(); pid_t c = fork(); if ( c ){ _exit(0); } if ( chdir("/") < 0 ){ cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::exit(-1); } setsid(); pid_t c2 = fork(); if ( c2 ){ cout << "forked process: " << c2 << endl; _exit(0); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ){ cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; ::exit(-1); } f = freopen("/dev/null", "r", stdin); if ( f == NULL ){ cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; ::exit(-1); } setupCoreSignals(); setupSignals( true ); } #endif if (params.count("logpath")) { if ( logpath.size() == 0 ) logpath = params["logpath"].as<string>(); uassert( 10033 , "logpath has to be non-zero" , logpath.size() ); initLogging( logpath , params.count( "logappend" ) ); } if ( params.count("pidfilepath")) { writePidFile( params["pidfilepath"].as<string>() ); } if (params.count("keyFile")){ const string f = params["keyFile"].as<string>(); if (!setUpSecurityKey(f)) { // error message printed in setUpPrivateKey dbexit(EXIT_BADOPTIONS); } noauth = false; } { BSONArrayBuilder b; for (int i=0; i < argc; i++) b << argv[i]; argvArray = b.arr(); } return true; }
void Server::beginServer () { if (_log) _log->write ("Server starting"); if (_daemon) { daemonize (); // Only the child returns. writePidFile (); } signal (SIGHUP, signal_handler); // Graceful stop signal (SIGUSR1, signal_handler); // Config reload signal (SIGUSR2, signal_handler); TLSServer server; if (_config) { server.debug (_config->getInteger ("debug.tls")); std::string ciphers = _config->get ("ciphers"); if (ciphers != "") { server.ciphers (ciphers); if (_log) _log->format ("Using ciphers: %s", ciphers.c_str ()); } std::string trust = _config->get ("trust"); if (trust == "allow all") server.trust (TLSServer::allow_all); else if (trust == "strict") server.trust (TLSServer::strict); else if (_log) _log->format ("Invalid 'trust' setting value of '%s'", trust.c_str ()); } server.init (_ca_file, // CA _crl_file, // CRL _cert_file, // Cert _key_file); // Key server.queue (_queue_size); server.bind (_host, _port, _family); server.listen (); if (_log) _log->write ("Server ready"); _request_count = 0; while (1) { try { TLSTransaction tx; tx.trust (server.trust ()); server.accept (tx); if (_sighup) throw "SIGHUP shutdown."; // Get client address and port, for logging. if (_log_clients) tx.getClient (_client_address, _client_port); // Metrics. HighResTimer timer; timer.start (); std::string input; tx.recv (input); // Handle the request. ++_request_count; // Call the derived class handler. std::string output; handler (input, output); if (output.length ()) tx.send (output); if (_log) { timer.stop (); _log->format ("[%d] Serviced in %.6fs", _request_count, timer.total ()); } } catch (std::string& e) { if (_log) _log->write (std::string ("Error: ") + e); } catch (char* e) { if (_log) _log->write (std::string ("Error: ") + e); } catch (...) { if (_log) _log->write ("Error: Unknown exception"); } } }