void main(int argc, char *argv[]) { debug = 0; ARGBEGIN{ case 'd': debug = 1; break; default: usage(); }ARGEND initcap(); srand(getpid()*time(0)); runas(argv[0], argv[1]); }
void main(int argc, char *argv[]) { debug = 0; ARGBEGIN{ case 'd': debug = 1; break; default: usage(); }ARGEND initcap(); if(argc >= 2) runas(argv[0], argv[1]); else usage(); }
int main(int argc, char *argv[]) { CREW crew; int i; int count = 0; int res; BOOLEAN result; char ** keys; void * statusp; C = new_conf(); parse_cmdline_cfg(C, argc, argv); parse_cfgfile(C); parse_cmdline(C, argc, argv); RUNNER R = new_runner(conf_get_user(C), conf_get_group(C)); runas(R); runner_destroy(R); sigmasker(); if (is_daemon(C)) { res = fork(); if (res == -1 ){ // ERRROR NOTIFY(FATAL, "%s: [error] unable to run in the background\n", program_name); } else if (res == 0) { // CHILD PID P = new_pid(conf_get_pidfile(C)); HASH H = conf_get_items(C); count = conf_get_count(C); keys = hash_get_keys_delim(H, ':'); if ((crew = new_crew(count, count, FALSE)) == NULL) { NOTIFY(FATAL, "%s: [error] unable to allocate memory for %d log files", program_name, count); } set_pid(P, getpid()); pid_destroy(P); for (i = 0; i < count && crew_get_shutdown(crew) != TRUE; i++) { FIDO F = new_fido(C, keys[i]); result = crew_add(crew, (void*)start, F); if (result == FALSE) { NOTIFY(FATAL, "%s: [error] unable to spawn additional threads", program_name); } } crew_join(crew, TRUE, &statusp); conf_destroy(C); } else { // PARENT } } else { HASH H = conf_get_items(C); count = conf_get_count(C); keys = hash_get_keys_delim(H, ':'); if ((crew = new_crew(count, count, FALSE)) == NULL) { NOTIFY(FATAL, "%s: [error] unable to allocate memory for %d log files", program_name, count); } for (i = 0; i < count && crew_get_shutdown(crew) != TRUE; i++) { FIDO F = new_fido(C, keys[i]); result = crew_add(crew, (void*)start, F); } crew_join(crew, TRUE, &statusp); conf_destroy(C); } exit(EXIT_SUCCESS); } /* end of int main **/
int CPCD::Process::start() { /* We need to fork() twice, so that the second child (grandchild?) can * become a daemon. The original child then writes the pid file, * so that the monitor knows the pid of the new process, and then * exit()s. That way, the monitor process can pickup the pid, and * the running process is a daemon. * * This is a bit tricky but has the following advantages: * - the cpcd can die, and "reconnect" to the monitored clients * without restarting them. * - the cpcd does not have to wait() for the childs. init(1) will * take care of that. */ logger.info("Starting %d: %s", m_id, m_name.c_str()); m_status = STARTING; int pid = -1; switch(m_processType){ case TEMPORARY:{ #ifndef _WIN32 /** * Simple fork * don't ignore child */ switch(pid = fork()) { case 0: /* Child */ setsid(); writePid(getpgrp()); if(runas(m_runas.c_str()) == 0){ signal(SIGCHLD, SIG_DFL); do_exec(); } _exit(1); break; case -1: /* Error */ logger.error("Cannot fork: %s\n", strerror(errno)); m_status = STOPPED; return -1; break; default: /* Parent */ logger.debug("Started temporary %d : pid=%d", m_id, pid); break; } #else //_WIN32 do_exec(); #endif break; } #ifndef _WIN32 case PERMANENT:{ /** * PERMANENT */ switch(fork()) { case 0: /* Child */ signal(SIGCHLD, SIG_IGN); switch(pid = fork()) { case 0: /* Child */ setsid(); writePid(getpgrp()); if(runas(m_runas.c_str()) != 0){ _exit(1); } signal(SIGCHLD, SIG_DFL); do_exec(); _exit(1); /* NOTREACHED */ break; case -1: /* Error */ logger.error("Cannot fork: %s\n", strerror(errno)); writePid(-1); _exit(1); break; default: /* Parent */ logger.debug("Started permanent %d : pid=%d", m_id, pid); _exit(0); break; } break; case -1: /* Error */ logger.error("Cannot fork: %s\n", strerror(errno)); m_status = STOPPED; return -1; break; default: /* Parent */ break; } break; } #endif default: logger.critical("Unknown process type"); return -1; } while(readPid() < 0){ sched_yield(); } errno = 0; pid_t pgid = IF_WIN(-1, getpgid(pid)); if(pgid != -1 && pgid != m_pid){ logger.error("pgid and m_pid don't match: %d %d (%d)", pgid, m_pid, pid); } if(isRunning()){ m_status = RUNNING; return 0; } m_status = STOPPED; return -1; }
int main(int argc, char *argv[]) { if (argc == 1) print_usage(); int in_guard_mode = 0; int dump_core = 0; int children_instance = 0; char *run_as_user = NULL; // parse args int c = -1; extern char *optarg; extern int optopt; const char *opt = ":gvu:Cs:ep:h"; while((c = getopt(argc, argv, opt)) != -1) { switch (c) { case 'v': // version fprintf(stderr, "\033[0;32m%s %s\033[0m\n", SVC_EDITION, BIN_V); return 0; case 'g': in_guard_mode = 1; break; case 'u': run_as_user = optarg; break; case 'C': dump_core = 1; break; case 'e': children_instance = 1; break; case 'p': break; case ':': fprintf(stderr, "\n\033[0;35mOption -%c requires an operand\033[0m\n", optopt); case 'h': default: print_usage(); } } const int max_clients = 1024*4; set_max_fds(max_clients); g_max_fds = get_max_fds(); if (run_as_user && runas(run_as_user) != 0) { fprintf(stderr, "\033[0;35mSudo to %s error!\033[0m\n", run_as_user); return -1; } if (dump_core && dump_corefile() != 0) { fprintf(stderr, "\033[0;35mSet dump corefile error!\033[0m\n"); return -1; } if (in_guard_mode) { if (children_instance == 0) guard_process(g_svc_name, argc, argv); clean_fds(); }else output_pid(g_svc_name); //= child process child_sig_handle(); sys::r = new reactor(); if (sys::r->open(max_clients, max_clients + 16) != 0) { fprintf(stderr, "Error: reactor - open failed!\n"); return -1; } if (sys::init_svc() != 0) { fprintf(stderr, "Error: init_svc - init failed!\n"); return -1; } s_log->rinfo("launch ok! max fds:%d", g_max_fds); e_log->rinfo("launch ok! max fds:%d", g_max_fds); // reactor event loop sys::r->run_reactor_event_loop(); return 1; }