/* * Prepare for a clean shutdown */ void daemon_shutdown() { pidfile_remove(pfh); if (!use_syslog) log_close(lfh); }
/* * Log an error message, then exit. */ void error(char *fmt, ...) { va_list list; do_percentm(fbuf, sizeof(fbuf), fmt); va_start(list, fmt); vsnprintf(mbuf, sizeof(mbuf), fbuf, list); va_end(list); #ifndef DEBUG syslog(log_priority | LOG_ERR, "%s", mbuf); #endif /* Also log it to stderr? */ if (log_perror) { write(2, mbuf, strlen(mbuf)); write(2, "\n", 1); } syslog(LOG_CRIT, "exiting."); if (log_perror) { fprintf(stderr, "exiting.\n"); fflush(stderr); } if (pidfile != NULL) pidfile_remove(pidfile); exit(1); }
void handle_signal(int signo) { if (SIGINT == signo || SIGTERM == signo) { utlog(LOG_NOTICE, "Received SIGINT/TERM signal, shuting down.."); pidfile_remove(pidfile); exit(EXIT_SUCCESS); } }
void server() { // load Config File and Settings fprintf(stdout, "Starting fidistat Server...\n"); openlog("fidistat-server", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "Started Fidistat Server"); struct pidfh *pfh = daemon_start('s'); // Handle Signals signal(SIGTERM, handleSigterm_S); signal(SIGCHLD, handleChild); // Open Socket initConf(); tls_init(); struct tls* ctx = tls_server(); int sock = initTLS_S(ctx); sckt = sock; int connfd, pid; listen(sock, 10); // Destroy Config destroyConf(); while(!term) { connfd = accept(sock, (struct sockaddr*) NULL, NULL); if (term) { break; } pid = fork(); if (pid < 0) { syslog(LOG_ERR, "forking new Worker failed"); } else if (pid == 0) { close(sock); syslog(LOG_INFO, "New incoming connection"); worker(connfd, ctx); syslog(LOG_INFO, "Closing connection"); exit(0); } else { close(connfd); } } syslog(LOG_INFO, "Shutting down Server"); close(sock); tls_close(ctx); tls_free(ctx); tls_config_free(tlsServer_conf); pidfile_remove(pfh); syslog(LOG_INFO, "Stopped Fidistat Server"); closelog(); exit(0); }
static void v_daemon(struct pidfh **pfh) { int ret; #ifdef __APPLE__ logger(-1, "Daemonizing is not guaranteed to not kill kittens on Mac OS X.\n"); logger(-1, "Consider using -d to run in foreground instead.\n"); #endif ret = daemon(0,0); if (ret == -1) { warn("Cannot daemonize"); if (*pfh) pidfile_remove(*pfh); exit(EXIT_FAILURE); } assert(ret == 0); }
int main(int argc, char **argv) { int pid_fd = -1, r = 0; pid_t old_pid; struct pfiled pfiled; init_perr("pfiled"); parse_cmdline(argc, argv); perr(PI, 0, "p = %ld, nr_ops = %lu\n", cmdline_portno, cmdline_nr_ops); if (cmdline_pidfile){ pid_fd = pidfile_open(cmdline_pidfile, &old_pid); if (pid_fd < 0) { if (old_pid) { perr(PFE, 0, "Daemon already running, pid: %d.", old_pid); } else { perr(PFE, 0, "Cannot open or create pidfile"); } return -1; } } if (cmdline_daemon){ if (daemon(0, 1) < 0){ perr(PFE, 0, "Cannot daemonize"); r = -1; goto out; } } setup_signals(); if (pid_fd > 0) pidfile_write(pid_fd); if (pfiled_init(&pfiled) < 0){ r = -1; goto out; } r = pfiled_loop(&pfiled); out: if (pid_fd > 0) pidfile_remove(cmdline_pidfile, pid_fd); return r; }
int main(int argc, char **argv) { struct agent_core_t core; struct agent_plugin_t *plug; struct pidfh *pfh = NULL; core.config = calloc(1,sizeof(struct agent_config_t)); assert(core.config); core.plugins = NULL; core_alloc_plugins(&core); core_opt(&core, argc, argv); base64_init(); core_plugins(&core); if (core.config->P_arg) p_open(&pfh, core.config->P_arg); sandbox(&core); if (core.config->d_arg) logger(-1, "Plugins initialized. -d argument given, so not forking."); else v_daemon(&pfh); if (pfh) pidfile_write(pfh); ipc_sanity(&core); threads_started = 1; for (plug = core.plugins; plug != NULL; plug = plug->next) { if (plug->start != NULL) plug->thread = plug->start(&core, plug->name); } threads_started = 2; for (plug = core.plugins; plug; plug = plug->next) { if (plug->thread) { pthread_join(*(pthread_t *)plug->thread, NULL); free(plug->thread); } } /* * XXX: Might want to do this on SIGTERM too I suppose. */ if (pfh) pidfile_remove(pfh); return 0; }
void process_error(int ret_code, char *fmt,...) { va_list ap; char buf[1024]; va_start(ap, fmt); if (pfh) pidfile_remove(pfh); vsprintf(buf, fmt, ap); logd(LOG_ERR, buf); errx(ret_code, buf); /* does not reach */ va_end(ap); }
static void restart_mountd(void) { struct pidfh *pfh; pid_t mountdpid; pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid); if (pfh != NULL) { /* Mountd is not running. */ pidfile_remove(pfh); return; } if (errno != EEXIST) { /* Cannot open pidfile for some reason. */ return; } /* We have mountd(8) PID in mountdpid varible. */ kill(mountdpid, SIGHUP); }
void hastd_secondary(struct hast_resource *res, struct nv *nvin) { sigset_t mask; pthread_t td; pid_t pid; int error, mode, debuglevel; /* * Create communication channel between parent and child. */ if (proto_client(NULL, "socketpair://", &res->hr_ctrl) < 0) { KEEP_ERRNO((void)pidfile_remove(pfh)); pjdlog_exit(EX_OSERR, "Unable to create control sockets between parent and child"); } /* * Create communication channel between child and parent. */ if (proto_client(NULL, "socketpair://", &res->hr_event) < 0) { KEEP_ERRNO((void)pidfile_remove(pfh)); pjdlog_exit(EX_OSERR, "Unable to create event sockets between child and parent"); } pid = fork(); if (pid < 0) { KEEP_ERRNO((void)pidfile_remove(pfh)); pjdlog_exit(EX_OSERR, "Unable to fork"); } if (pid > 0) { /* This is parent. */ proto_close(res->hr_remotein); res->hr_remotein = NULL; proto_close(res->hr_remoteout); res->hr_remoteout = NULL; /* Declare that we are receiver. */ proto_recv(res->hr_event, NULL, 0); /* Declare that we are sender. */ proto_send(res->hr_ctrl, NULL, 0); res->hr_workerpid = pid; return; } gres = res; mode = pjdlog_mode_get(); debuglevel = pjdlog_debug_get(); /* Declare that we are sender. */ proto_send(res->hr_event, NULL, 0); /* Declare that we are receiver. */ proto_recv(res->hr_ctrl, NULL, 0); descriptors_cleanup(res); descriptors_assert(res, mode); pjdlog_init(mode); pjdlog_debug_set(debuglevel); pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role)); setproctitle("%s (%s)", res->hr_name, role2str(res->hr_role)); PJDLOG_VERIFY(sigemptyset(&mask) == 0); PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); /* Error in setting timeout is not critical, but why should it fail? */ if (proto_timeout(res->hr_remotein, 2 * HAST_KEEPALIVE) < 0) pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0) pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); init_local(res); init_environment(); if (drop_privs(res) != 0) exit(EX_CONFIG); pjdlog_info("Privileges successfully dropped."); /* * Create the control thread before sending any event to the parent, * as we can deadlock when parent sends control request to worker, * but worker has no control thread started yet, so parent waits. * In the meantime worker sends an event to the parent, but parent * is unable to handle the event, because it waits for control * request response. */ error = pthread_create(&td, NULL, ctrl_thread, res); PJDLOG_ASSERT(error == 0); init_remote(res, nvin); event_send(res, EVENT_CONNECT); error = pthread_create(&td, NULL, recv_thread, res); PJDLOG_ASSERT(error == 0); error = pthread_create(&td, NULL, disk_thread, res); PJDLOG_ASSERT(error == 0); (void)send_thread(res); }
int main(int argc, char * argv[]) { struct timeval timeout; fd_set fdset; int nfds; struct pidfh *pfh = NULL; const char *pidfile = NULL; int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load; int minfreq = -1, maxfreq = -1; int ch, mode, mode_ac, mode_battery, mode_none, idle, to; uint64_t mjoules_used; size_t len; /* Default mode for all AC states is adaptive. */ mode_ac = mode_none = MODE_HIADAPTIVE; mode_battery = MODE_ADAPTIVE; cpu_running_mark = DEFAULT_ACTIVE_PERCENT; cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; mjoules_used = 0; vflag = 0; /* User must be root to control frequencies. */ if (geteuid() != 0) errx(1, "must be root to run"); while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:v")) != -1) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); break; case 'b': parse_mode(optarg, &mode_battery, ch); break; case 'i': cpu_idle_mark = atoi(optarg); if (cpu_idle_mark < 0 || cpu_idle_mark > 100) { warnx("%d is not a valid percent", cpu_idle_mark); usage(); } break; case 'm': minfreq = atoi(optarg); if (minfreq < 0) { warnx("%d is not a valid CPU frequency", minfreq); usage(); } break; case 'M': maxfreq = atoi(optarg); if (maxfreq < 0) { warnx("%d is not a valid CPU frequency", maxfreq); usage(); } break; case 'n': parse_mode(optarg, &mode_none, ch); break; case 'p': poll_ival = atoi(optarg); if (poll_ival < 5) { warnx("poll interval is in units of ms"); usage(); } break; case 'P': pidfile = optarg; break; case 'r': cpu_running_mark = atoi(optarg); if (cpu_running_mark <= 0 || cpu_running_mark > 100) { warnx("%d is not a valid percent", cpu_running_mark); usage(); } break; case 'v': vflag = 1; break; default: usage(); } mode = mode_none; /* Poll interval is in units of ms. */ poll_ival *= 1000; /* Look up various sysctl MIBs. */ len = 2; if (sysctlnametomib("kern.cp_times", cp_times_mib, &len)) err(1, "lookup kern.cp_times"); len = 4; if (sysctlnametomib("dev.cpu.0.freq", freq_mib, &len)) err(EX_UNAVAILABLE, "no cpufreq(4) support -- aborting"); len = 4; if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len)) err(1, "lookup freq_levels"); /* Check if we can read the load and supported freqs. */ if (read_usage_times(NULL)) err(1, "read_usage_times"); if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq)) err(1, "error reading supported CPU frequencies"); if (numfreqs == 0) errx(1, "no CPU frequencies in user-specified range"); /* Run in the background unless in verbose mode. */ if (!vflag) { pid_t otherpid; pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { errx(1, "powerd already running, pid: %d", otherpid); } warn("cannot open pid file"); } if (daemon(0, 0) != 0) { warn("cannot enter daemon mode, exiting"); pidfile_remove(pfh); exit(EXIT_FAILURE); } pidfile_write(pfh); } /* Decide whether to use ACPI or APM to read the AC line status. */ acline_init(); /* * Exit cleanly on signals. */ signal(SIGINT, handle_sigs); signal(SIGTERM, handle_sigs); freq = initfreq = curfreq = get_freq(); i = get_freq_id(curfreq, freqs, numfreqs); if (freq < 1) freq = 1; /* * If we are in adaptive mode and the current frequency is outside the * user-defined range, adjust it to be within the user-defined range. */ acline_read(); if (acline_status > SRC_UNKNOWN) errx(1, "invalid AC line status %d", acline_status); if ((acline_status == SRC_AC && (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) || (acline_status == SRC_BATTERY && (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) || (acline_status == SRC_UNKNOWN && (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) { /* Read the current frequency. */ len = sizeof(curfreq); if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) { if (vflag) warn("error reading current CPU frequency"); } if (curfreq < freqs[numfreqs - 1]) { if (vflag) { printf("CPU frequency is below user-defined " "minimum; changing frequency to %d " "MHz\n", freqs[numfreqs - 1]); } if (set_freq(freqs[numfreqs - 1]) != 0) { warn("error setting CPU freq %d", freqs[numfreqs - 1]); } } else if (curfreq > freqs[0]) { if (vflag) { printf("CPU frequency is above user-defined " "maximum; changing frequency to %d " "MHz\n", freqs[0]); } if (set_freq(freqs[0]) != 0) { warn("error setting CPU freq %d", freqs[0]); } } } idle = 0; /* Main loop. */ for (;;) { FD_ZERO(&fdset); if (devd_pipe >= 0) { FD_SET(devd_pipe, &fdset); nfds = devd_pipe + 1; } else { nfds = 0; } if (mode == MODE_HIADAPTIVE || idle < 120) to = poll_ival; else if (idle < 360) to = poll_ival * 2; else to = poll_ival * 4; timeout.tv_sec = to / 1000000; timeout.tv_usec = to % 1000000; select(nfds, &fdset, NULL, &fdset, &timeout); /* If the user requested we quit, print some statistics. */ if (exit_requested) { if (vflag && mjoules_used != 0) printf("total joules used: %u.%03u\n", (u_int)(mjoules_used / 1000), (int)mjoules_used % 1000); break; } /* Read the current AC status and record the mode. */ acline_read(); switch (acline_status) { case SRC_AC: mode = mode_ac; break; case SRC_BATTERY: mode = mode_battery; break; case SRC_UNKNOWN: mode = mode_none; break; default: errx(1, "invalid AC line status %d", acline_status); } /* Read the current frequency. */ if (idle % 32 == 0) { if ((curfreq = get_freq()) == 0) continue; i = get_freq_id(curfreq, freqs, numfreqs); } idle++; if (vflag) { /* Keep a sum of all power actually used. */ if (mwatts[i] != -1) mjoules_used += (mwatts[i] * (poll_ival / 1000)) / 1000; } /* Always switch to the lowest frequency in min mode. */ if (mode == MODE_MIN) { freq = freqs[numfreqs - 1]; if (curfreq != freq) { if (vflag) { printf("now operating on %s power; " "changing frequency to %d MHz\n", modes[acline_status], freq); } idle = 0; if (set_freq(freq) != 0) { warn("error setting CPU freq %d", freq); continue; } } continue; } /* Always switch to the highest frequency in max mode. */ if (mode == MODE_MAX) { freq = freqs[0]; if (curfreq != freq) { if (vflag) { printf("now operating on %s power; " "changing frequency to %d MHz\n", modes[acline_status], freq); } idle = 0; if (set_freq(freq) != 0) { warn("error setting CPU freq %d", freq); continue; } } continue; } /* Adaptive mode; get the current CPU usage times. */ if (read_usage_times(&load)) { if (vflag) warn("read_usage_times() failed"); continue; } if (mode == MODE_ADAPTIVE) { if (load > cpu_running_mark) { if (load > 95 || load > cpu_running_mark * 2) freq *= 2; else freq = freq * load / cpu_running_mark; if (freq > freqs[0]) freq = freqs[0]; } else if (load < cpu_idle_mark && curfreq * load < freqs[get_freq_id( freq * 7 / 8, freqs, numfreqs)] * cpu_running_mark) { freq = freq * 7 / 8; if (freq < freqs[numfreqs - 1]) freq = freqs[numfreqs - 1]; } } else { /* MODE_HIADAPTIVE */ if (load > cpu_running_mark / 2) { if (load > 95 || load > cpu_running_mark) freq *= 4; else freq = freq * load * 2 / cpu_running_mark; if (freq > freqs[0] * 2) freq = freqs[0] * 2; } else if (load < cpu_idle_mark / 2 && curfreq * load < freqs[get_freq_id( freq * 31 / 32, freqs, numfreqs)] * cpu_running_mark / 2) { freq = freq * 31 / 32; if (freq < freqs[numfreqs - 1]) freq = freqs[numfreqs - 1]; } } if (vflag) { printf("load %3d%%, current freq %4d MHz (%2d), wanted freq %4d MHz\n", load, curfreq, i, freq); } j = get_freq_id(freq, freqs, numfreqs); if (i != j) { if (vflag) { printf("changing clock" " speed from %d MHz to %d MHz\n", freqs[i], freqs[j]); } idle = 0; if (set_freq(freqs[j])) warn("error setting CPU frequency %d", freqs[j]); } } if (set_freq(initfreq)) warn("error setting CPU frequency %d", initfreq); free(freqs); free(mwatts); devd_close(); if (!vflag) pidfile_remove(pfh); exit(0); }
int main(int argc, char const* argv[]) { ir::IRXDaemon* instance; OperationEnum operation; ModeEnum mode; struct pidfh* pfh; pid_t pid; bool daemonize; int i; int result(EXIT_SUCCESS); if ((instance = ir::IRXDaemon::_new()) != NULL) { operation = OPERATION_UNKNOWN; mode = MODE_UNKNOWN; if (argc > 1) { if ((result = instance->usage(argc, argv)) == EXIT_SUCCESS) { for (i = 1; i < argc; ++i) { if (strcmp(argv[i], "start") == 0) { operation = OPERATION_START; } else if (strcmp(argv[i], "restart") == 0) { operation = OPERATION_RESTART; } else if (strcmp(argv[i], "stop") == 0) { operation = OPERATION_STOP; } else if (strcmp(argv[i], "--daemon") == 0) { mode = MODE_DAEMON; } else if (strcmp(argv[i], "--application") == 0) { mode = MODE_APPLICATION; } } } } if (result == EXIT_SUCCESS) { if (operation == OPERATION_UNKNOWN) { operation = OPERATION_START; } if (mode == MODE_UNKNOWN) { mode = MODE_DAEMON; } g_quit = false; signal(SIGHUP, onSigHUP); signal(SIGINT, onSigINT); signal(SIGTERM, onSigTERM); signal(SIGCHLD, SIG_IGN); switch (operation) { case OPERATION_RESTART: case OPERATION_STOP: if ((pfh = pidfile_open(NULL, 0600, &pid)) != NULL) { instance->log(LOG_NOTICE, "already stopped"); pidfile_remove(pfh); } else { switch (errno) { case EEXIST: if (kill(pid, SIGTERM) == 0) { instance->log(LOG_NOTICE, "stopping pid = %d...", pid); while (true) { if (g_quit) { result = EXIT_FAILURE; break; } if (kill(pid, 0) != 0) { instance->log(LOG_NOTICE, "stopping done"); break; } sleep(1); } } else { instance->log(LOG_ERR, "can't stop pid = %d [%m]", pid); result = EX_OSERR; } break; case EACCES: instance->log(LOG_ERR, "run as super user"); result = EX_OSERR; break; default: instance->log(LOG_ERR, "can't stop [%m]"); result = EX_OSERR; break; } } break; default: // nop break; } if (result == EXIT_SUCCESS) { switch (operation) { case OPERATION_START: case OPERATION_RESTART: if ((pfh = pidfile_open(NULL, 0600, &pid)) != NULL) { instance->log(LOG_NOTICE, "starting pid = %d...", getpid()); daemonize = true; if (mode == MODE_APPLICATION) { daemonize = false; } #ifdef __APPLE__ if (getppid() == 1) { daemonize = false; } #endif if (daemonize) { if (daemon(0, 0) != 0) { instance->log(LOG_ERR, "can't daemonize pid = %d [%m]", getpid()); result = EX_OSERR; } } if (result == EXIT_SUCCESS) { instance->log(LOG_NOTICE, "changing pid = %d...", getpid()); pidfile_write(pfh); if ((result = instance->initialize()) == EXIT_SUCCESS) { instance->log(LOG_NOTICE, "starting done"); while (true) { if (g_quit) { result = EXIT_FAILURE; break; } instance->loop(); } } else { instance->log(LOG_ERR, "can't start pid = %d [%d]", getpid(), result); } instance->terminate(); } pidfile_remove(pfh); } else { switch (errno) { case EEXIST: instance->log(LOG_ERR, "already started pid = %d", pid); result = EX_OSERR; break; case EACCES: instance->log(LOG_ERR, "run as super user"); result = EX_OSERR; break; default: instance->log(LOG_ERR, "can't start [%m]"); result = EX_OSERR; break; } } break; default: // nop break; } } } ir::IRXDaemon::_delete(instance); } else { result = EXIT_FAILURE; } return result; }
int main(int argc, char *argv[]) { struct pidfh *pfh = NULL; int ch, nochdir, noclose, errcode; const char *pidfile, *user; pid_t otherpid; nochdir = noclose = 1; pidfile = user = NULL; while ((ch = getopt(argc, argv, "-cfp:u:")) != -1) { switch (ch) { case 'c': nochdir = 0; break; case 'f': noclose = 0; break; case 'p': pidfile = optarg; break; case 'u': user = optarg; break; default: usage(); } } argc -= optind; argv += optind; if (argc == 0) usage(); if (user != NULL) restrict_process(user); /* * Try to open the pidfile before calling daemon(3), * to be able to report the error intelligently */ if (pidfile) { pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { errx(3, "process already running, pid: %d", otherpid); } err(2, "pidfile ``%s''", pidfile); } } if (daemon(nochdir, noclose) == -1) err(1, NULL); /* Now that we are the child, write out the pid */ if (pidfile) pidfile_write(pfh); execvp(argv[0], argv); /* * execvp() failed -- unlink pidfile if any, and * report the error */ errcode = errno; /* Preserve errcode -- unlink may reset it */ if (pidfile) pidfile_remove(pfh); /* The child is now running, so the exit status doesn't matter. */ errc(1, errcode, "%s", argv[0]); }
int main(int argc, char *argv[]) { struct pidfh *pfh = NULL; sigset_t mask, oldmask; int ch, nochdir, noclose, restart; const char *pidfile, *user; pid_t otherpid, pid; nochdir = noclose = 1; restart = 0; pidfile = user = NULL; while ((ch = getopt(argc, argv, "-cfp:ru:")) != -1) { switch (ch) { case 'c': nochdir = 0; break; case 'f': noclose = 0; break; case 'p': pidfile = optarg; break; case 'r': restart = 1; break; case 'u': user = optarg; break; default: usage(); } } argc -= optind; argv += optind; if (argc == 0) usage(); pfh = NULL; /* * Try to open the pidfile before calling daemon(3), * to be able to report the error intelligently */ if (pidfile != NULL) { pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { errx(3, "process already running, pid: %d", otherpid); } err(2, "pidfile ``%s''", pidfile); } } if (daemon(nochdir, noclose) == -1) err(1, NULL); /* * If the pidfile or restart option is specified the daemon * executes the command in a forked process and wait on child * exit to remove the pidfile or restart the command. Normally * we don't want the monitoring daemon to be terminated * leaving the running process and the stale pidfile, so we * catch SIGTERM and forward it to the children expecting to * get SIGCHLD eventually. */ pid = -1; if (pidfile != NULL || restart) { /* * Restore default action for SIGTERM in case the * parent process decided to ignore it. */ if (signal(SIGTERM, SIG_DFL) == SIG_ERR) err(1, "signal"); /* * Because SIGCHLD is ignored by default, setup dummy handler * for it, so we can mask it. */ if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) err(1, "signal"); /* * Block interesting signals. */ sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) err(1, "sigprocmask"); /* * Try to protect against pageout kill. Ignore the * error, madvise(2) will fail only if a process does * not have superuser privileges. */ (void)madvise(NULL, 0, MADV_PROTECT); restart: /* * Spawn a child to exec the command, so in the parent * we could wait for it to exit and remove pidfile. */ pid = fork(); if (pid == -1) { pidfile_remove(pfh); err(1, "fork"); } } if (pid <= 0) { if (pid == 0) { /* Restore old sigmask in the child. */ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) err(1, "sigprocmask"); } /* Now that we are the child, write out the pid. */ pidfile_write(pfh); if (user != NULL) restrict_process(user); execvp(argv[0], argv); /* * execvp() failed -- report the error. The child is * now running, so the exit status doesn't matter. */ err(1, "%s", argv[0]); } setproctitle("%s[%d]", argv[0], pid); if (wait_child(pid, &mask) == 0 && restart) { sleep(1); goto restart; } pidfile_remove(pfh); exit(0); /* Exit status does not matter. */ }
/* * Periodically pat the watchdog, preventing it from firing. */ int main(int argc, char *argv[]) { struct rtprio rtp; struct pidfh *pfh; pid_t otherpid; if (getuid() != 0) errx(EX_SOFTWARE, "not super user"); parseargs(argc, argv); if (do_syslog) openlog("watchdogd", LOG_CONS|LOG_NDELAY|LOG_PERROR, LOG_DAEMON); rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; if (rtprio(RTP_SET, 0, &rtp) == -1) err(EX_OSERR, "rtprio"); if (!is_dry_run && watchdog_init() == -1) errx(EX_SOFTWARE, "unable to initialize watchdog"); if (is_daemon) { if (watchdog_onoff(1) == -1) err(EX_OSERR, "patting the dog"); pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { watchdog_onoff(0); errx(EX_SOFTWARE, "%s already running, pid: %d", getprogname(), otherpid); } warn("Cannot open or create pidfile"); } if (debugging == 0 && daemon(0, 0) == -1) { watchdog_onoff(0); pidfile_remove(pfh); err(EX_OSERR, "daemon"); } signal(SIGHUP, SIG_IGN); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); pidfile_write(pfh); if (madvise(0, 0, MADV_PROTECT) != 0) warn("madvise failed"); if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) warn("mlockall failed"); watchdog_loop(); /* exiting */ pidfile_remove(pfh); return (EX_OK); } else { if (passive) timeout |= WD_PASSIVE; else timeout |= WD_ACTIVE; if (watchdog_patpat(timeout) < 0) err(EX_OSERR, "patting the dog"); return (EX_OK); } }
heartbeat_daemon_tool(int argc, char *argv[]) { struct pidfh *ppfh, *pfh; sigset_t mask, oldmask; int ch, nochdir, noclose, restart, serrno; const char *pidfile, *ppidfile, *user; pid_t otherpid, pid; nochdir = noclose = 1; restart = 0; ppidfile = pidfile = user = NULL; while ((ch = getopt(argc, argv, "cfp:P:ru:")) != -1) { switch (ch) { case 'c': nochdir = 0; break; case 'f': noclose = 0; break; case 'p': pidfile = optarg; break; case 'P': ppidfile = optarg; break; case 'r': restart = 1; break; case 'u': user = optarg; break; default: daemon_tool_usage(); } } argc -= optind; argv += optind; if (argc == 0) daemon_tool_usage(); if (pidfile != NULL) { pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { errx(3, "process already running, pid: %d", otherpid); } err(2, "pidfile ``%s''", pidfile); } } if (ppidfile != NULL) { ppfh = pidfile_open(ppidfile, 0600, &otherpid); if (ppfh == NULL) { serrno = errno; pidfile_remove(pfh); errno = serrno; if (errno = EEXIST) { errx(3, "process already running, pid: %d", otherpid); } err(2, "ppidfile ``%s''", ppidfile); } } if (daemon(nochdir, noclose) == -1) { warn("daemon"); goto exit; } pidfile_write(ppfh); pid = -1; if (pidfile != NULL || ppidfile != NULL || restart) { if (signal(SIGTERM, SIG_DFL) == SIG_ERR) { warn("signal"); goto exit; } if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) { warn("signal"); goto exit; } sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) { warn("sigprocmask"); goto exit; } (void)madvise(NULL, 0, MADV_PROTECT); restart: pid = fork(); if (pid == -1) { warn("fork"); goto exit; } } if (pid <= 0) { if (pid == 0) { if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) err(1, "sigprocmask"); } pidfile_write(pfh); if (user != NULL) restrict_process(user); execvp(argv[0], argv); err(1, "%s", argv[0]); } setproctitle("%s[%d", argv[0], pid); if (wait_child(pid, &mask) == 0 && restart) { sleep(1); goto restart; } exit: pidfile_remove(pfh); pidfile_remove(ppfh); exit(1); }
int main(int argc, char *argv[]) { char optstring[] = "i:p:dfs:vh"; struct option longopts[] = { {"isns-server", 1, NULL, 'i'}, {"isns-port", 1, NULL, 'p'}, {"debug", 0, NULL, 'd'}, {"foreground", 0, NULL, 'f'}, {"configfs-iscsi-path", 1, NULL, 's'}, {"version", 0, NULL, 'v'}, {"help", 0, NULL, 'h'}, {NULL, 0, NULL, 0} }; int option; int longindex = 0; int ifd = -1, sfd = -1, tfd = -1; struct epoll_event events[EPOLL_MAX_FD]; ssize_t nr_events; bool daemon = true; int ret = EXIT_FAILURE; size_t configsz; conffile_read(); while ((option = getopt_long(argc, argv, optstring, longopts, &longindex)) != -1) { switch (option) { case 'i': configsz = sizeof(config.isns_server); strncpy(config.isns_server, optarg, configsz); config.isns_server[configsz - 1] = '\0'; break; case 'p': sscanf(optarg, "%hu", &config.isns_port); break; case 'd': config.log_level = LOG_DEBUG; daemon = false; break; case 'f': daemon = false; break; case 's': configsz = sizeof(config.configfs_iscsi_path); strncpy(config.configfs_iscsi_path, optarg, configsz); config.configfs_iscsi_path[configsz - 1] = '\0'; break; case 'v': printf(PROGNAME " version " TARGET_ISNS_VERSION "\n"); exit(EXIT_SUCCESS); break; case 'h': print_usage(); exit(EXIT_SUCCESS); break; case ':': case '?': exit(EXIT_FAILURE); break; } } if (!configfs_iscsi_path_exists()) { fprintf(stderr, "Error: configfs is not mounted or the " "target and iSCSI modules are not loaded.\n"); fprintf(stderr, "Error: %s missing.\n", config.configfs_iscsi_path); exit(EXIT_FAILURE); } if (daemon) { daemonize(); pidfile_create(); } log_init(PROGNAME, daemon, config.log_level); log_print(LOG_INFO, PROGNAME " version " TARGET_ISNS_VERSION " started"); epoll_init_fds(); if (isns_init(config.isns_server, config.isns_port) == -1) { log_print(LOG_ERR, "failed to initialize iSNS client"); goto err_init; } if ((epoll_fd = epoll_create1(0)) == -1) { log_print(LOG_ERR, "failed to create epoll instance"); goto err_epoll_fd; } if ((tfd = isns_registration_timer_init()) == -1) { log_print(LOG_ERR, "failed to create timerfd instance"); goto err_tfd; } epoll_set_fd(EPOLL_REGISTRATION_TIMER, tfd); if ((ifd = configfs_inotify_init()) == -1) { log_print(LOG_ERR, "failed to create inotify instance"); goto err_ifd; } epoll_set_fd(EPOLL_INOTIFY, ifd); if ((sfd = signal_init()) == -1) { log_print(LOG_ERR, "failed to create signalfd instance"); goto err_sfd; } epoll_set_fd(EPOLL_SIGNAL, sfd); isns_start(); while (true) { nr_events = epoll_wait(epoll_fd, events, ARRAY_SIZE(events), -1); for (int i = 0; i < nr_events; i++) { int fd = events[i].data.fd; if (fd == epoll_set[EPOLL_SIGNAL]) { if (signal_is_quit(fd)) goto quit; } else if (fd == epoll_set[EPOLL_INOTIFY]) configfs_inotify_events_handle(); else if (fd == epoll_set[EPOLL_REGISTRATION_TIMER]) isns_registration_refresh(); else if (fd == epoll_set[EPOLL_ISNS]) isns_handle(); else if (fd == epoll_set[EPOLL_SCN_LISTEN]) isns_scn_handle(true); else if (fd == epoll_set[EPOLL_SCN]) isns_scn_handle(false); } } quit: ret = EXIT_SUCCESS; isns_stop(); sleep(1); close(sfd); err_sfd: configfs_inotify_cleanup(); /* closes ifd */ err_ifd: close(tfd); err_tfd: close(epoll_fd); err_epoll_fd: isns_exit(); err_init: log_print(LOG_INFO, PROGNAME " stopped"); log_close(); if (daemon) pidfile_remove(); return ret; }
int main( int argc, char *argv[]) { const char *program = basename(argv[0]); int fps = DEFAULT_FPS; suseconds_t frameDuration = 1000000 / fps; bool isDaemon = false; uint32_t sourceDisplayNumber = DEFAULT_SOURCE_DISPLAY_NUMBER; uint32_t destDisplayNumber = DEFAULT_DESTINATION_DISPLAY_NUMBER; int32_t layerNumber = DEFAULT_LAYER_NUMBER; const char *pidfile = NULL; //--------------------------------------------------------------------- static const char *sopts = "d:f:hl:p:s:D"; static struct option lopts[] = { { "destination", required_argument, NULL, 'd' }, { "fps", required_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, { "layer", required_argument, NULL, 'l' }, { "pidfile", required_argument, NULL, 'p' }, { "source", required_argument, NULL, 's' }, { "daemon", no_argument, NULL, 'D' }, { NULL, no_argument, NULL, 0 } }; int opt = 0; while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { switch (opt) { case 'd': destDisplayNumber = atoi(optarg); break; case 'f': fps = atoi(optarg); if (fps > 0) { frameDuration = 1000000 / fps; } else { fps = 1000000 / frameDuration; } break; case 'h': printUsage(stdout, program); exit(EXIT_SUCCESS); break; case 'l': layerNumber = atoi(optarg); break; case 'p': pidfile = optarg; break; case 's': sourceDisplayNumber = atoi(optarg); break; case 'D': isDaemon = true; break; default: printUsage(stderr, program); exit(EXIT_FAILURE); break; } } //--------------------------------------------------------------------- struct pidfh *pfh = NULL; if (isDaemon) { if (pidfile != NULL) { pid_t otherpid; pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { fprintf(stderr, "%s is already running %jd\n", program, (intmax_t)otherpid); exit(EXIT_FAILURE); } } if (daemon(0, 0) == -1) { fprintf(stderr, "daemonize failed\n"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } if (pfh) { pidfile_write(pfh); } openlog(program, LOG_PID, LOG_USER); } //--------------------------------------------------------------------- if (signal(SIGINT, signalHandler) == SIG_ERR) { perrorLog(isDaemon, program, "installing SIGINT signal handler"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } //--------------------------------------------------------------------- if (signal(SIGTERM, signalHandler) == SIG_ERR) { perrorLog(isDaemon, program, "installing SIGTERM signal handler"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } //--------------------------------------------------------------------- bcm_host_init(); //--------------------------------------------------------------------- int result = 0; //--------------------------------------------------------------------- // Make sure the VC_DISPLAY variable isn't set. unsetenv("VC_DISPLAY"); //--------------------------------------------------------------------- DISPMANX_DISPLAY_HANDLE_T sourceDisplay = vc_dispmanx_display_open(sourceDisplayNumber); if (sourceDisplay == 0) { messageLog(isDaemon, program, LOG_ERR, "open source display failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } DISPMANX_MODEINFO_T sourceInfo; result = vc_dispmanx_display_get_info(sourceDisplay, &sourceInfo); if (result != 0) { messageLog(isDaemon, program, LOG_ERR, "getting source display dimensions failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } //--------------------------------------------------------------------- DISPMANX_DISPLAY_HANDLE_T destDisplay = vc_dispmanx_display_open(destDisplayNumber); if (destDisplay == 0) { messageLog(isDaemon, program, LOG_ERR, "open destination display failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } DISPMANX_MODEINFO_T destInfo; result = vc_dispmanx_display_get_info(destDisplay, &destInfo); if (result != 0) { messageLog(isDaemon, program, LOG_ERR, "getting destination display dimensions failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } //--------------------------------------------------------------------- messageLog(isDaemon, program, LOG_INFO, "copying from [%d] %dx%d to [%d] %dx%d", sourceDisplayNumber, sourceInfo.width, sourceInfo.height, destDisplayNumber, destInfo.width, destInfo.height); //--------------------------------------------------------------------- uint32_t image_ptr; DISPMANX_RESOURCE_HANDLE_T resource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, destInfo.width, destInfo.height, &image_ptr); //--------------------------------------------------------------------- VC_RECT_T sourceRect; vc_dispmanx_rect_set(&sourceRect, 0, 0, destInfo.width << 16, destInfo.height << 16); VC_RECT_T destRect; vc_dispmanx_rect_set(&destRect, 0, 0, 0, 0); //--------------------------------------------------------------------- VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0 }; DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); if (update == 0) { messageLog(isDaemon, program, LOG_ERR, "display update failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } DISPMANX_ELEMENT_HANDLE_T element; element = vc_dispmanx_element_add(update, destDisplay, layerNumber, &destRect, resource, &sourceRect, DISPMANX_PROTECTION_NONE, &alpha, NULL, DISPMANX_NO_ROTATE); if (element == 0) { messageLog(isDaemon, program, LOG_ERR, "failed to create DispmanX element"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } vc_dispmanx_update_submit_sync(update); //--------------------------------------------------------------------- struct timeval start_time; struct timeval end_time; struct timeval elapsed_time; //--------------------------------------------------------------------- while (run) { gettimeofday(&start_time, NULL); //----------------------------------------------------------------- result = vc_dispmanx_snapshot(sourceDisplay, resource, DISPMANX_NO_ROTATE); if (result != 0) { messageLog(isDaemon, program, LOG_ERR, "DispmanX snapshot failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } //----------------------------------------------------------------- update = vc_dispmanx_update_start(0); if (update == 0) { messageLog(isDaemon, program, LOG_ERR, "display update failed"); exitAndRemovePidFile(EXIT_FAILURE, pfh); } vc_dispmanx_element_change_source(update, element, resource); vc_dispmanx_update_submit_sync(update); //----------------------------------------------------------------- gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); if (elapsed_time.tv_sec == 0) { if (elapsed_time.tv_usec < frameDuration) { usleep(frameDuration - elapsed_time.tv_usec); } } } //--------------------------------------------------------------------- update = vc_dispmanx_update_start(0); vc_dispmanx_element_remove(update, element); vc_dispmanx_update_submit_sync(update); vc_dispmanx_resource_delete(resource); vc_dispmanx_display_close(sourceDisplay); vc_dispmanx_display_close(destDisplay); //--------------------------------------------------------------------- messageLog(isDaemon, program, LOG_INFO, "exiting"); if (isDaemon) { closelog(); } if (pfh) { pidfile_remove(pfh); } //--------------------------------------------------------------------- return 0 ; }
int main(int argc, char **argv) { int ch, debug = 0, error, iscsi_fd, maxproc = 30, retval, saved_errno, timeout = 60; bool dont_daemonize = false; struct pidfh *pidfh; pid_t pid, otherpid; const char *pidfile_path = DEFAULT_PIDFILE; struct iscsi_daemon_request request; while ((ch = getopt(argc, argv, "P:dl:m:t:")) != -1) { switch (ch) { case 'P': pidfile_path = optarg; break; case 'd': dont_daemonize = true; debug++; break; case 'l': debug = atoi(optarg); break; case 'm': maxproc = atoi(optarg); break; case 't': timeout = atoi(optarg); break; case '?': default: usage(); } } argc -= optind; if (argc != 0) usage(); log_init(debug); pidfh = pidfile_open(pidfile_path, 0600, &otherpid); if (pidfh == NULL) { if (errno == EEXIST) log_errx(1, "daemon already running, pid: %jd.", (intmax_t)otherpid); log_err(1, "cannot open or create pidfile \"%s\"", pidfile_path); } iscsi_fd = open(ISCSI_PATH, O_RDWR); if (iscsi_fd < 0 && errno == ENOENT) { saved_errno = errno; retval = kldload("iscsi"); if (retval != -1) iscsi_fd = open(ISCSI_PATH, O_RDWR); else errno = saved_errno; } if (iscsi_fd < 0) log_err(1, "failed to open %s", ISCSI_PATH); if (dont_daemonize == false) { if (daemon(0, 0) == -1) { log_warn("cannot daemonize"); pidfile_remove(pidfh); exit(1); } } pidfile_write(pidfh); register_sigchld(); for (;;) { log_debugx("waiting for request from the kernel"); memset(&request, 0, sizeof(request)); error = ioctl(iscsi_fd, ISCSIDWAIT, &request); if (error != 0) { if (errno == EINTR) { nchildren -= wait_for_children(false); assert(nchildren >= 0); continue; } log_err(1, "ISCSIDWAIT"); } if (dont_daemonize) { log_debugx("not forking due to -d flag; " "will exit after servicing a single request"); } else { nchildren -= wait_for_children(false); assert(nchildren >= 0); while (maxproc > 0 && nchildren >= maxproc) { log_debugx("maxproc limit of %d child processes hit; " "waiting for child process to exit", maxproc); nchildren -= wait_for_children(true); assert(nchildren >= 0); } log_debugx("incoming connection; forking child process #%d", nchildren); nchildren++; pid = fork(); if (pid < 0) log_err(1, "fork"); if (pid > 0) continue; } pidfile_close(pidfh); handle_request(iscsi_fd, &request, timeout); } return (0); }
int main(int argc, char *argv[], char *envp[]) { log_open(LOG_FILE); FM_LOG_TRACE("---"); check_pid(); int sockfd; socklen_t clilen; struct sockaddr_in serv_addr{}; struct sockaddr_in cli_addr{}; const char *cfg_file; if (argc > 1) { cfg_file = argv[1]; } else { cfg_file = DEFAULT_CFG_FILE; } read_config(cfg_file); FM_LOG_TRACE("read_config"); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { fatal_error("ERROR opening socket"); } FM_LOG_TRACE("socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (inet_aton(oj_config.ip, &serv_addr.sin_addr) == 0) { serv_addr.sin_addr.s_addr = INADDR_ANY; } serv_addr.sin_port = htons(oj_config.port); FM_LOG_NOTICE("IP address: %s %s", oj_config.ip, inet_ntoa(serv_addr.sin_addr)); FM_LOG_NOTICE("port: %d %d", oj_config.port, ntohs(serv_addr.sin_port)); int yes = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { fatal_error("setsockopt SO_REUSEADDR failed"); } if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fatal_error("ERROR on binding"); } FM_LOG_TRACE("bind"); clilen = sizeof(cli_addr); if (listen(sockfd, oj_config.backlog) < 0) { fatal_error("ERROR on listening"); } FM_LOG_NOTICE("listen backlog: %d", oj_config.backlog); if (daemon(0, 0) == -1) { FM_LOG_FATAL("Cannot daemonize"); pidfile_remove(pfh); exit(EXIT_FAILURE); } print_word_dir(); print_user_group(); pidfile_write(pfh); struct sigaction sa{}; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGTERM, &sa, nullptr) == -1) { // install signal hander for timeout FM_LOG_FATAL("cannot handle SIGTERM"); exit(EXIT_FAILURE); } else { FM_LOG_DEBUG("set signal_handler"); } for (int i = 0; i < oj_config.thread_num; i++) { std::thread t(ThreadWork); t.detach(); } FM_LOG_NOTICE("thread count: %d", oj_config.thread_num); std::thread(SendWork).detach(); while (isRunning) { int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd != -1) { work(newsockfd, cli_addr); } } pidfile_remove(pfh); close(sockfd); return 0; }
void tap_init(void) { channel_t *chan; struct ifreq ifr; int fd, s; char pidfile[PATH_MAX]; fd = open(interface_name, O_RDWR); if (fd == -1) { log_err("Could not open \"%s\": %m", interface_name); exit(EXIT_FAILURE); } memset(&ifr, 0, sizeof(ifr)); if (ioctl(fd, TAPGIFNAME, &ifr) == -1) { log_err("Could not get interface name: %m"); exit(EXIT_FAILURE); } s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) { log_err("Could not open PF_LINK socket: %m"); exit(EXIT_FAILURE); } ifr.ifr_addr.sa_family = AF_LINK; ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; b2eaddr(ifr.ifr_addr.sa_data, &local_bdaddr); if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) { log_err("Could not set %s physical address: %m", ifr.ifr_name); exit(EXIT_FAILURE); } if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { log_err("Could not get interface flags: %m"); exit(EXIT_FAILURE); } if ((ifr.ifr_flags & IFF_UP) == 0) { ifr.ifr_flags |= IFF_UP; if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) { log_err("Could not set IFF_UP: %m"); exit(EXIT_FAILURE); } } close(s); log_info("Using interface %s with addr %s", ifr.ifr_name, ether_ntoa((struct ether_addr *)&ifr.ifr_addr.sa_data)); chan = channel_alloc(); if (chan == NULL) exit(EXIT_FAILURE); chan->send = tap_send; chan->recv = tap_recv; chan->mru = ETHER_HDR_LEN + ETHER_MAX_LEN; memcpy(chan->raddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); memcpy(chan->laddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); chan->state = CHANNEL_OPEN; if (!channel_open(chan, fd)) exit(EXIT_FAILURE); snprintf(pidfile, sizeof(pidfile), "%s/%s.pid", _PATH_VARRUN, ifr.ifr_name); chan->pfh = pidfile_open(pidfile, 0600, NULL); if (chan->pfh == NULL) log_err("can't create pidfile"); else if (pidfile_write(chan->pfh) < 0) { log_err("can't write pidfile"); pidfile_remove(chan->pfh); chan->pfh = NULL; } }
/* * Prepare for a clean shutdown */ void daemon_shutdown() { pidfile_remove(pfh); }