/* kill older tincd for this net */ bool kill_other(int signal) { #ifndef HAVE_MINGW pid_t pid; pid = read_pid(pidfilename); if(!pid) { if(netname) fprintf(stderr, "No other tincd is running for net `%s'.\n", netname); else fprintf(stderr, "No other tincd is running.\n"); return false; } errno = 0; /* No error, sometimes errno is only changed on error */ /* ESRCH is returned when no process with that pid is found */ if(kill(pid, signal) && errno == ESRCH) { if(netname) fprintf(stderr, "The tincd for net `%s' is no longer running. ", netname); else fprintf(stderr, "The tincd is no longer running. "); fprintf(stderr, "Removing stale lock file.\n"); remove_pid(pidfilename); } return true; #else return remove_service(); #endif }
int stop(void) { int pid; char cmd[512]; // read pid from pid lock pid = read_pid(router_id); if (pid < 0) { return pid; } // terminate the task // kill both child and parent task sprintf(cmd, "pkill -TERM -P %d", pid); system(cmd); sprintf(cmd, "kill -TERM %d", pid); system(cmd); // kill(pid, SIG_TERM); printf("\x1B[32mRouter%d\033[0m Terminated\n", router_id); remove_pid(router_id); return 0; }
/* removes fd from register, returning its filename and status via filename and status arguments. */ void deregister_fd(int fd) { struct pid_reg **pid_iter = find_pid(getpid()); if (*pid_iter) { struct fd_reg **fd_iter = find_fd(*pid_iter, fd); if (*fd_iter) { remove_fd(fd_iter); if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter); } } }
int start(void) { int pid; int ret; // fork a subprocess to execute the job pid = fork(); if (pid < 0) // failed to fork { printf("\x1B[31mFailed to fork subprocess\033[0m\n"); return -2; } else if (pid == 0) // child process { pid = getpid(); // write pid to file to make sure that the router is not allowed to be // executed twice at the same time ret = write_pid(pid, router_id); if (ret) { return ret; } printf("\x1B[32mRouter%d\033[0m starts at pid=\x1B[32m%d\033[0m\n", router_id, pid); // start the router demon ret = router_demon_start(); if (ret) { return ret; } remove_pid(router_id); } else // parent process { } return 0; }
int main (int argc, char **argv) { botcfg.state = STATE_INIT; //piHiPri (45); if (setup () != 0) { fprintf (stderr, "Error setting up\n"); return 1; } if (read_options (argc, argv) != 0) { fprintf (stderr, "Error reading options\n"); return 1; } if (botcfg.state == STATE_INIT) { //User didn't chose either record or replay, falling back to passthrough botcfg.state = STATE_RUNNING; } if (joystick_setup () != 0) { fprintf (stderr, "Error setting up joysticks\n"); return 1; } //drop_privs (); if (check_pid ()) { fprintf (stderr, "Are we already running?\n"); return 1; } main_loop (); clear_all_buttons (); fprintf (stdout, "Exiting...\n"); remove_pid (); return 0 ; }
static RETSIGTYPE fatal_signal_handler(int a) { struct sigaction act; logger(LOG_ERR, "Got fatal signal %d (%s)", a, strsignal(a)); if(do_detach) { logger(LOG_NOTICE, "Trying to re-execute in 5 seconds..."); act.sa_handler = fatal_signal_square; act.sa_mask = emptysigset; act.sa_flags = 0; sigaction(SIGSEGV, &act, NULL); close_network_connections(); sleep(5); remove_pid(pidfilename); execvp(g_argv[0], g_argv); } else { logger(LOG_NOTICE, "Not restarting."); exit(1); } }
int main2(int argc, char **argv) { InitializeCriticalSection(&mutex); EnterCriticalSection(&mutex); #endif if(!detach()) return 1; #ifdef HAVE_MLOCKALL /* Lock all pages into memory if requested. * This has to be done after daemon()/fork() so it works for child. * No need to do that in parent as it's very short-lived. */ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "mlockall", strerror(errno)); return 1; } #endif /* Setup sockets and open device. */ if(!setup_network()) goto end; /* Initiate all outgoing connections. */ try_outgoing_connections(); /* Change process priority */ char *priority = 0; if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { if(!strcasecmp(priority, "Normal")) { if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "Low")) { if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else if(!strcasecmp(priority, "High")) { if (setpriority(HIGH_PRIORITY_CLASS) != 0) { logger(LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); goto end; } } else { logger(LOG_ERR, "Invalid priority `%s`!", priority); goto end; } } /* drop privileges */ if (!drop_privs()) goto end; /* Start main loop. It only exits when tinc is killed. */ status = main_loop(); /* Shutdown properly. */ ifdebug(CONNECTIONS) dump_device_stats(); close_network_connections(); end: logger(LOG_NOTICE, "Terminating"); #ifndef HAVE_MINGW remove_pid(pidfilename); #endif EVP_cleanup(); ENGINE_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); ERR_free_strings(); exit_configuration(&config_tree); free_names(); return status; }
void start_server(void) { int pid, c_dsc; struct sockaddr_in s_sin, c_sin; socklen_t s_len, c_len; http_in_t* req; s_len = sizeof(s_sin); c_len = sizeof(c_sin); s_sin.sin_family = AF_INET; s_sin.sin_port = htons(conf.port); s_sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Creates socket */ if((s_dsc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { log_critical("Failed to create socket: %s", strerror(errno)); remove_pid(); return; } /* Binds socket */ if(bind(s_dsc, (struct sockaddr*)&s_sin, s_len) < 0) { log_critical("Failed to bind: %s", strerror(errno)); remove_pid(); return; } /* Listens */ if(listen(s_dsc, SOMAXCONN) < 0) { log_critical("Failed to listen: %s", strerror(errno)); remove_pid(); return; } /* Infinite loop */ while(1) { if((c_dsc = accept(s_dsc, (struct sockaddr*)&c_sin, &c_len)) < 0) { log_error("Failed to accept: %s", strerror(errno)); continue; } pid = fork(); switch(pid) { case -1: /* Error */ log_error("Failed to fork: %s", strerror(errno)); break; case 0: /* Child process */ close(s_dsc); log_debug("Connection by %s:%d", inet_ntoa(c_sin.sin_addr), htons(c_sin.sin_port)); /* Receives HTTP request */ req = http_recv(c_dsc); /* Sends HTTP response */ http_send(c_dsc, req); close(c_dsc); exit(EXIT_SUCCESS); default: /* Father process */ close(c_dsc); } } }
int main(int argc, char **argv) { struct timespec mtime = { 0 }; sigset_t mask, sigmask_orig; int c, fd; int ep_timeout = 0; int ignore_timer = 0; int new_events = 0; char *eventdir, *prog, **prog_args; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "foreground", no_argument, 0, 'f' }, { "loglevel", required_argument, 0, 'L' }, { "logfile", required_argument, 0, 'l' }, { "pidfile", required_argument, 0, 'p' }, { "timeout", required_argument, 0, 't' }, { 0, 0, 0, 0 } }; while ((c = getopt_long(argc, argv, "hVfL:l:p:", long_options, NULL)) != -1) { switch (c) { case 't': timeout = atoi(optarg); if (!timeout) timeout = DEFAULT_TIMEOUT; break; case 'p': pidfile = optarg; break; case 'l': logfile = optarg; break; case 'L': log_priority = logging_level(optarg); break; case 'f': daemonize = 0; break; case 'V': printf("%s %s\n", PROGRAM_NAME, VERSION); return EXIT_SUCCESS; default: case 'h': printf("Usage: %s [options] DIRECTORY PROGRAM [ARGS...]\n" "\nThe utility monitors the DIRECTORY and when\n" "new files appear run the PROGRAM.\n\n" "Options:\n" " -p, --pidfile=FILE pid file location;\n" " -l, --logfile=FILE log file;\n" " -L, --loglevel=LVL logging level;\n" " -t, --timeout=SEC number of seconds that need to wait" " for files before the PROGRAM launch;\n" " -f, --foreground stay in the foreground;\n" " -V, --version print program version and exit;\n" " -h, --help show this text and exit.\n" "\n", PROGRAM_NAME); return EXIT_SUCCESS; } } if (optind >= argc) error(EXIT_FAILURE, 0, "You must specify the directory"); eventdir = argv[optind++]; if (optind >= argc) error(EXIT_FAILURE, 0, "You must specify the program"); prog = canonicalize_file_name(argv[optind]); if (!prog) error(EXIT_FAILURE, errno, "Bad program"); argv[optind] = strrchr(prog, '/'); if (!argv[optind]) argv[optind] = prog; prog_args = argv + optind; if (!log_priority) log_priority = logging_level("info"); if (pidfile && check_pid(pidfile)) error(EXIT_FAILURE, 0, "%s: already running", PROGRAM_NAME); if (chdir("/") < 0) error(EXIT_FAILURE, errno, "%s: chdir(/)", PROGRAM_NAME); close(STDIN_FILENO); if ((fd = open("/dev/null", O_RDONLY)) < 0) error(EXIT_FAILURE, errno, "%s: open(/dev/null)", PROGRAM_NAME); if (fd != STDIN_FILENO) { dup2(fd, STDIN_FILENO); close(fd); } if (daemonize && daemon(0, 1) < 0) error(EXIT_FAILURE, errno, "%s: daemon", PROGRAM_NAME); logging_init(); info("starting version %s", VERSION); if (pidfile && write_pid(pidfile) == 0) return EXIT_FAILURE; sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); sigdelset(&mask, SIGABRT); sigdelset(&mask, SIGSEGV); if ((fd_ep = epoll_create1(EPOLL_CLOEXEC)) < 0) fatal("epoll_create1: %m"); if ((fd_signal = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC)) < 0) fatal("signalfd: %m"); epollin_add(fd_ep, fd_signal); if ((fd_eventdir = inotify_init1(IN_NONBLOCK | IN_CLOEXEC)) < 0) fatal("inotify_init1: %m"); if (inotify_add_watch(fd_eventdir, eventdir, IN_ONLYDIR | IN_DONT_FOLLOW | IN_MOVED_TO | IN_CLOSE_WRITE) < 0) fatal("inotify_add_watch: %m"); epollin_add(fd_ep, fd_eventdir); ignore_timer = is_dir_not_empty(eventdir); if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); last.tv_sec = now.tv_sec; while (!do_exit) { struct epoll_event ev[42]; int i, fdcount; ssize_t size; if ((fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), ep_timeout)) < 0) continue; if (!ep_timeout) ep_timeout = timeout * 1000; for (i = 0; i < fdcount; i++) { if (!(ev[i].events & EPOLLIN)) { continue; } else if (ev[i].data.fd == fd_signal) { struct signalfd_siginfo fdsi; size = TEMP_FAILURE_RETRY(read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo))); if (size != sizeof(struct signalfd_siginfo)) { err("unable to read signal info"); continue; } handle_signal(fdsi.ssi_signo); } else if (ev[i].data.fd == fd_eventdir) { read_inotify_events(fd_eventdir); new_events += 1; } } if (new_events) { struct stat sb; new_events = 0; if (lstat(eventdir, &sb) < 0) fatal("lstat: %s: %m", eventdir); if (mtime.tv_sec != sb.st_mtim.tv_sec || mtime.tv_nsec != sb.st_mtim.tv_nsec) { if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); last.tv_sec = now.tv_sec; } mtime.tv_sec = sb.st_mtim.tv_sec; mtime.tv_nsec = sb.st_mtim.tv_nsec; } if (worker_pid) continue; if (!ignore_timer) { if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); if (now.tv_sec < last.tv_sec || (now.tv_sec - last.tv_sec) < timeout) continue; } ignore_timer = 0; if ((worker_pid = spawn_worker(prog, prog_args)) < 0) fatal("spawn_worker: %m"); dbg("Run worker %d", worker_pid); } epollin_remove(fd_ep, fd_signal); epollin_remove(fd_ep, fd_eventdir); free(prog); if (pidfile) remove_pid(pidfile); logging_close(); return EXIT_SUCCESS; }
/* irc_exit: cleans up and leaves */ void BX_irc_exit (int really_quit, char *reason, char *format, ...) { char buffer[BIG_BUFFER_SIZE]; logger(current_window, NULL, 0); if (get_int_var(MSGLOG_VAR)) log_toggle(0, NULL); if (format) { va_list arglist; va_start(arglist, format); vsprintf(buffer, format, arglist); va_end(arglist); } else sprintf(buffer, "%s -- just do it.",irc_version); if (really_quit) { put_it("%s", convert_output_format("$G Signon time : $0-", "%s", my_ctime(start_time))); put_it("%s", convert_output_format("$G Signoff time : $0-", "%s", my_ctime(now))); put_it("%s", convert_output_format("$G Total uptime : $0-", "%s", convert_time(now - start_time))); } do_hook(EXIT_LIST, "%s", reason ? reason : buffer); close_all_servers(reason ? reason : buffer); put_it("%s", buffer ? buffer : reason ? reason : empty_string); clean_up_processes(); if (!dumb_mode && term_initialized) { cursor_to_input(); /* Needed so that ircII doesn't gobble * the last line of the kill. */ term_cr(); term_clear_to_eol(); term_reset(); } destroy_call_stack(); #if defined(THREAD) && defined(WANT_NSLOOKUP) kill_dns(); #endif remove_pid(); if (really_quit) { #ifdef GUI gui_exit(); #else #if defined(WANT_DETACH) && !defined(GUI) kill_attached_if_needed(0); #endif fprintf(stdout, "\r"); fflush(stdout); exit(0); #endif } }
static void remove_pidfile(void) { (void) remove_pid(PIDFILE); }
static void handle_signal(int sig) { int serrno = errno; char signame[10] = { '\0' }; pid_t pid; RC_PID *pi; int status = 0; struct winsize ws; sigset_t sset; switch (sig) { case SIGCHLD: do { pid = waitpid(-1, &status, WNOHANG); if (pid < 0) { if (errno != ECHILD) eerror("waitpid: %s", strerror(errno)); return; } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); /* Remove that pid from our list */ if (pid > 0) remove_pid(pid); break; case SIGWINCH: if (rc_logger_tty >= 0) { ioctl(STDIN_FILENO, TIOCGWINSZ, &ws); ioctl(rc_logger_tty, TIOCSWINSZ, &ws); } break; case SIGINT: if (!signame[0]) snprintf(signame, sizeof(signame), "SIGINT"); /* FALLTHROUGH */ case SIGTERM: if (!signame[0]) snprintf(signame, sizeof(signame), "SIGTERM"); /* FALLTHROUGH */ case SIGQUIT: if (!signame[0]) snprintf(signame, sizeof(signame), "SIGQUIT"); eerrorx("%s: caught %s, aborting", applet, signame); /* NOTREACHED */ case SIGUSR1: eerror("rc: Aborting!"); /* Block child signals */ sigemptyset(&sset); sigaddset(&sset, SIGCHLD); sigprocmask(SIG_BLOCK, &sset, NULL); /* Kill any running services we have started */ LIST_FOREACH(pi, &service_pids, entries) kill(pi->pid, SIGTERM); /* Notify plugins we are aborting */ rc_plugin_run(RC_HOOK_ABORT, NULL); exit(EXIT_FAILURE); /* NOTREACHED */ default: eerror("%s: caught unknown signal %d", applet, sig); } /* Restore errno */ errno = serrno; }