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]); }
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; } }
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 *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: usage(); } } argc -= optind; argv += optind; if (argc == 0) usage(); ppfh = 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); } } /* Do the same for actual daemon process. */ 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; } /* Write out parent pidfile if needed. */ pidfile_write(ppfh); /* * 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) { warn("signal"); goto exit; } /* * Because SIGCHLD is ignored by default, setup dummy handler * for it, so we can mask it. */ if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) { warn("signal"); goto exit; } /* * Block interesting signals. */ sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) { warn("sigprocmask"); goto exit; } /* * 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) { warn("fork"); goto exit; } } 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; } exit: pidfile_remove(pfh); pidfile_remove(ppfh); exit(1); /* If daemon(3) succeeded exit status does not matter. */ }
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); }
/* * Daemonize and persist pid */ int daemon_start() { struct sigaction sig_action; sigset_t sig_set; pid_t otherpid; int curPID; pthread_t tcp4_thread, udp4_thread; pthread_t tcp6_thread, udp6_thread; /* Check if we can acquire the pid file */ pfh = pidfile_open(NULL, 0644, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", (intmax_t)otherpid); } err(EXIT_FAILURE, "Cannot open or create pidfile"); } init_logger(); /* Initialize TCP46 and UDP46 sockets */ if (init_tcp() == EXIT_FAILURE) return (EXIT_FAILURE); if (init_udp() == EXIT_FAILURE) return (EXIT_FAILURE); /* start daemonizing */ curPID = fork(); switch (curPID) { case 0: /* This process is the child */ break; case -1: /* fork() failed, should exit */ perror("fork"); return (EXIT_FAILURE); default: /* fork() successful, should exit * (parent) */ return (EXIT_SUCCESS); } /* we are the child, complete the daemonization */ /* Close standard IO */ fclose(stdin); fclose(stdout); fclose(stderr); /* Block unnecessary signals */ sigemptyset(&sig_set); sigaddset(&sig_set, SIGCHLD); /* ignore child - i.e. we don't need * to wait for it */ sigaddset(&sig_set, SIGTSTP); /* ignore tty stop signals */ sigaddset(&sig_set, SIGTTOU); /* ignore tty background writes */ sigaddset(&sig_set, SIGTTIN); /* ignore tty background reads */ sigprocmask(SIG_BLOCK, &sig_set, NULL); /* Block the above specified * signals */ /* Catch necessary signals */ sig_action.sa_handler = signal_handler; sigemptyset(&sig_action.sa_mask); sig_action.sa_flags = 0; sigaction(SIGTERM, &sig_action, NULL); sigaction(SIGHUP, &sig_action, NULL); sigaction(SIGINT, &sig_action, NULL); /* create new session and process group */ setsid(); /* persist pid */ pidfile_write(pfh); /* Create TCP and UDP listener threads */ pthread_create(&tcp4_thread, NULL, tcp4_handler, NULL); pthread_create(&udp4_thread, NULL, udp4_handler, NULL); #ifdef PF_INET6 pthread_create(&tcp6_thread, NULL, tcp6_handler, NULL); pthread_create(&udp6_thread, NULL, udp6_handler, NULL); #endif /* * Wait for threads to terminate, which normally shouldn't ever * happen */ pthread_join(tcp4_thread, NULL); pthread_join(udp4_thread, NULL); #ifdef PF_INET6 pthread_join(tcp6_thread, NULL); pthread_join(udp6_thread, NULL); #endif return (EXIT_SUCCESS); }
/* * 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); } }