int setup_log() { if ((rploglen =str_len(rplog)) < 7) { warn3x("log must have at least seven characters.", 0, 0); return(0); } if (pipe(logpipe) == -1) { warn3x("unable to create pipe for log.", 0, 0); return(-1); } coe(logpipe[1]); coe(logpipe[0]); ndelay_on(logpipe[0]); ndelay_on(logpipe[1]); if (fd_copy(2, logpipe[1]) == -1) { warn3x("unable to set filedescriptor for log.", 0, 0); return(-1); } io[0].fd =logpipe[0]; io[0].events =IOPAUSE_READ; taia_now(&stamplog); return(1); }
int selfpipe_init (void) { if (selfpipe[0] >= 0) return (errno = EBUSY, -1); if (pipe(selfpipe) == -1) return -1; if ((ndelay_on(selfpipe[1]) == -1) || (coe(selfpipe[1]) == -1) || (ndelay_on(selfpipe[0]) == -1) || (coe(selfpipe[0]) == -1)) selfpipe_close(); return selfpipe[0]; }
/******************************************************************** * mkpqf() * * Function `mkpqf()' returns a pointer to a `pqf' data structure * containing the coefficients, length and the pre-periodized filter * named by the input parameters. * * Calling sequence: * mkpqf( coefs, alpha, omega, flags ) * * Inputs: * (const real *)coefs These are the filter coefficients, * assumed to be given in the array * `coefs[0],...,coefs[omega-alpha]' * are the only nonzero values. * * (int)alpha These are to be the first and last valid * (int)omega indices of the pqf->f struct member. * * (int)flags This is reserved for later uses, such as * indicating when to generate a full QF * sequence from just one symmetric half. * * Return value: * (pqf *)mkpqf The return value is a pointer to a newly * allocated pqf struct containing `coefs[]', * `alpha', `omega', and the preperiodized * version of `coefs[]'. * Assumptions: * (1) Conventional indexing: `alpha <= 0 <= omega'. */ extern pqf * mkpqf( const real *coefs, /* Original filter coefficients. */ int alpha, /* Least valid index of `?->f[]'. */ int omega, /* Greatest valid index of `?->f[]'. */ int flags) /* Reserved for future use. */ { pqf *qm; int M; assert(alpha <= 0); /* Conventional indexing. */ assert(0 <= omega); /* Conventional indexing. */ qm = (pqf *)calloc(1,sizeof(pqf)); assert(qm); qm->alpha = alpha; qm->omega = omega; qm->f = coefs-alpha; M = IFH( omega-alpha ); qm->fp = (real *)calloc( PQFL(M), sizeof(real)); assert(qm->fp); qfcirc( qm->fp, qm->f, alpha, omega ); qm->center = coe( qm->f, alpha, omega ); qm->deviation = lphdev( qm->f, alpha, omega ); return(qm); }
void f_init(char **script) { int i; int fd; for (i = 0;script[i];++i) ; f = (int *) alloc(i * sizeof(*f)); if (!f) strerr_die2x(111,FATAL,"out of memory"); for (i = 0;script[i];++i) { fd = -1; if (script[i][0] == '=') { if (fchdir(fdstartdir) == -1) strerr_die2sys(111,FATAL,"unable to switch to starting directory: "); fd = open_append(script[i] + 1); if (fd == -1) strerr_die4sys(111,FATAL,"unable to create ",script[i] + 1,": "); close(fd); fd = open_write(script[i] + 1); if (fd == -1) strerr_die4sys(111,FATAL,"unable to write ",script[i] + 1,": "); coe(fd); } f[i] = fd; } }
pid_t child_spawn1_internal (char const *prog, char const *const *argv, char const *const *envp, int *p, int to) { int e ; int syncp[2] ; pid_t pid ; if (coe(p[0]) < 0 || pipecoe(syncp) < 0) { e = errno ; fd_close(p[1]) ; fd_close(p[0]) ; errno = e ; return 0 ; } pid = fork() ; if (pid < 0) { e = errno ; fd_close(syncp[1]) ; fd_close(syncp[0]) ; fd_close(p[1]) ; fd_close(p[0]) ; errno = e ; return 0 ; } if (!pid) { fd_close(syncp[0]) ; fd_close(p[!(to & 1)]) ; if (fd_move(to & 1, p[to & 1]) < 0) goto err ; if ((to & 2) && (fd_copy(!(to & 1), to & 1) < 0)) goto err ; sig_blocknone() ; pathexec_run(prog, argv, envp) ; err: e = errno ; fd_write(syncp[1], (char *)&e, sizeof(e)) ; _exit(127) ; } fd_close(syncp[1]) ; fd_close(p[to & 1]) ; syncp[1] = fd_read(syncp[0], (char *)&e, sizeof(e)) ; if (syncp[1] < 0) { e = errno ; fd_close(syncp[0]) ; fd_close(p[!(to & 1)]) ; errno = e ; return 0 ; } fd_close(syncp[0]) ; if (syncp[1] == sizeof(e)) { fd_close(p[!(to & 1)]) ; wait_pid(pid, &syncp[1]) ; errno = e ; return 0 ; } return pid ; }
int call_open(struct call *cc, const char *prog, int timeout, int flagstar) { int pit[2]; int pif[2]; const char *(args[2]); args[0] = prog; args[1] = 0; if (pipe(pit) == -1) return -1; if (pipe(pif) == -1) { close(pit[0]); close(pit[1]); return -1; } switch(cc->pid = vfork()) { case -1: close(pit[0]); close(pit[1]); close(pif[0]); close(pif[1]); return -1; case 0: close(pit[1]); close(pif[0]); if (fd_move(0,pit[0]) == -1) _exit(120); if (fd_move(1,pif[1]) == -1) _exit(120); if (chdir(auto_qmail) == -1) _exit(61); execv(*args,(char **)args); _exit(120); } if (timeout != 0) mytimeout = timeout; cc->flagerr = 0; cc->flagabort = 0; cc->flagstar = flagstar; cc->tofd = pit[1]; close(pit[0]); cc->fromfd = pif[0]; close(pif[1]); coe(cc->tofd); coe(cc->fromfd); substdio_fdbuf(&cc->ssto, mywrite, cc->tofd, cc->tobuf, sizeof(cc->tobuf)); substdio_fdbuf(&cc->ssfrom, myread, cc->fromfd, cc->frombuf, sizeof(cc->frombuf)); return 0; }
int main(int argc,char **argv) { struct stat st; dir = argv[1]; if (!dir || argv[2]) strerr_die1x(100,"supervise: usage: supervise dir"); if (pipe(selfpipe) == -1) strerr_die4sys(111,FATAL,"unable to create pipe for ",dir,": "); coe(selfpipe[0]); coe(selfpipe[1]); ndelay_on(selfpipe[0]); ndelay_on(selfpipe[1]); sig_block(sig_child); sig_catch(sig_child,trigger); if (chdir(dir) == -1) strerr_die4sys(111,FATAL,"unable to chdir to ",dir,": "); if (stat("down",&st) != -1) flagwantup = 0; else if (errno != error_noent) strerr_die4sys(111,FATAL,"unable to stat ",dir,"/down: "); mkdir("supervise",0700); fdlock = open_append("supervise/lock"); if ((fdlock == -1) || (lock_exnb(fdlock) == -1)) strerr_die4sys(111,FATAL,"unable to acquire ",dir,"/supervise/lock: "); coe(fdlock); fifo_make("supervise/control",0600); fdcontrol = open_read("supervise/control"); if (fdcontrol == -1) strerr_die4sys(111,FATAL,"unable to read ",dir,"/supervise/control: "); coe(fdcontrol); ndelay_on(fdcontrol); /* shouldn't be necessary */ fdcontrolwrite = open_write("supervise/control"); if (fdcontrolwrite == -1) strerr_die4sys(111,FATAL,"unable to write ",dir,"/supervise/control: "); coe(fdcontrolwrite); pidchange(); announce(); fifo_make("supervise/ok",0600); fdok = open_read("supervise/ok"); if (fdok == -1) strerr_die4sys(111,FATAL,"unable to read ",dir,"/supervise/ok: "); coe(fdok); if (!flagwant || flagwantup) trystart(); doit(); announce(); _exit(0); }
static void write_log(int fd, int level, const char *info0, const char *info1, const char *info2) { struct stat st; int fdx, ret; char tmp[2048]; char timestr[128]; char loglevel[3][16] = { "NOTICE", "WARNING", "FATAL" }; if (fd == fdlog) { if ((ret = stat(status_files[5], &st)) < 0 || st.st_size > 1800000000) { close(fdlog); if (ret == 0) unlink(status_files[5]); fdlog = open_append(status_files[5]); coe(fdlog); } fdx = fdlog; } else if (fd == fdlogwf) { if ((ret = stat(status_files[6], &st)) < 0 || st.st_size > 1800000000) { close(fdlogwf); if (ret == 0) unlink(status_files[6]); fdlogwf = open_append(status_files[6]); coe(fdlogwf); } fdx = fdlogwf; } else return; bzero(timestr, 128); gettimenow(timestr, 128); snprintf(tmp, 2048, "[%s] %s %s%s%s", level >= 0 && level < 3 ? loglevel[level] : "", timestr, info0, info1, info2); write(fdx, tmp, strlen(tmp)); }
int unirandomegd_sinit (union unirandominfo *u, char const *path) { register int s = randomegd_open(path) ; if (s == -1) return 0 ; if (coe(s) == -1) { register int e = errno ; fd_close(s) ; errno = e ; return 0 ; } u->egd.fd = s ; return 1 ; }
int pipe_internal (int *p, unsigned int flags) { #ifdef HASPIPE2 return pipe2(p, ((flags & DJBUNIX_FLAG_COE) ? O_CLOEXEC : 0) | ((flags & DJBUNIX_FLAG_NB) ? O_NONBLOCK : 0)) ; #else int pi[2] ; if (pipe(pi) < 0) return -1 ; if (flags & DJBUNIX_FLAG_COE) if ((coe(pi[0]) < 0) || (coe(pi[1]) < 0)) goto err ; if (flags & DJBUNIX_FLAG_NB) if ((ndelay_on(pi[0]) < 0) || (ndelay_on(pi[1]) < 0)) goto err ; p[0] = pi[0] ; p[1] = pi[1] ; return 0 ; err: { register int e = errno ; fd_close(pi[1]) ; fd_close(pi[0]) ; errno = e ; } return -1 ; #endif }
int socket_internal (int domain, int type, int protocol, unsigned int flags) { int s = socket(domain, type, protocol) ; if (s == -1) return -1 ; if ((((flags & DJBUNIX_FLAG_NB) ? ndelay_on(s) : ndelay_off(s)) < 0) || (((flags & DJBUNIX_FLAG_COE) ? coe(s) : uncoe(s)) < 0)) { register int e = errno ; fd_close(s) ; errno = e ; return -1 ; } return s ; }
int socketpair_internal (int domain, int type, int protocol, unsigned int flags, int *sv) { int fd[2] ; if (socketpair(domain, type, protocol, fd) < 0) return -1 ; if (flags & DJBUNIX_FLAG_NB) { if (ndelay_on(fd[0]) < 0) goto err ; if (ndelay_on(fd[1]) < 0) goto err ; } else { if (ndelay_off(fd[0]) < 0) goto err ; if (ndelay_off(fd[1]) < 0) goto err ; } if (flags & DJBUNIX_FLAG_COE) { if (coe(fd[0]) < 0) goto err ; if (coe(fd[1]) < 0) goto err ; } else { if (uncoe(fd[0]) < 0) goto err ; if (uncoe(fd[1]) < 0) goto err ; } sv[0] = fd[0] ; sv[1] = fd[1] ; return 0 ; err: { register int e = errno ; fd_close(fd[1]) ; fd_close(fd[0]) ; errno = e ; } return -1 ; }
pid_t child_spawn1_internal (char const *prog, char const *const *argv, char const *const *envp, int *p, int to) { posix_spawn_file_actions_t actions ; posix_spawnattr_t attr ; int e ; pid_t pid ; int haspath = !!env_get("PATH") ; if (coe(p[!(to & 1)]) < 0) { e = errno ; goto err ; } e = posix_spawnattr_init(&attr) ; if (e) goto err ; { sigset_t set ; sigemptyset(&set) ; e = posix_spawnattr_setsigmask(&attr, &set) ; if (e) goto errattr ; e = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK) ; if (e) goto errattr ; } e = posix_spawn_file_actions_init(&actions) ; if (e) goto errattr ; e = posix_spawn_file_actions_adddup2(&actions, p[to & 1], to & 1) ; if (e) goto erractions ; e = posix_spawn_file_actions_addclose(&actions, p[to & 1]) ; if (e) goto erractions ; if (to & 2) { e = posix_spawn_file_actions_adddup2(&actions, to & 1, !(to & 1)) ; if (e) goto erractions ; } if (!haspath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) { e = errno ; goto erractions ; } e = posix_spawnp(&pid, prog, &actions, &attr, (char *const *)argv, (char *const *)envp) ; if (!haspath) unsetenv("PATH") ; posix_spawn_file_actions_destroy(&actions) ; posix_spawnattr_destroy(&attr) ; fd_close(p[to & 1]) ; if (e) goto errp ; return pid ; erractions: posix_spawn_file_actions_destroy(&actions) ; errattr: posix_spawnattr_destroy(&attr) ; err: fd_close(p[to & 1]) ; errp: fd_close(p[!(to & 1)]) ; errno = e ; return 0 ; }
static int setup_log(void) { rploglen = strlen(rplog); if (rploglen < 7) { warnx("log must have at least seven characters"); return 0; } if (pipe(logpipe)) { warnx("cannot create pipe for log"); return -1; } coe(logpipe[1]); coe(logpipe[0]); ndelay_on(logpipe[0]); ndelay_on(logpipe[1]); if (dup2(logpipe[1], 2) == -1) { warnx("cannot set filedescriptor for log"); return -1; } pfd[0].fd = logpipe[0]; pfd[0].events = POLLIN; stamplog = monotonic_sec(); return 1; }
static int setup_log(void) { rploglen = strlen(rplog); if (rploglen < 7) { warnx("log must have at least seven characters"); return 0; } if (pipe(logpipe)) { warnx("cannot create pipe for log"); return -1; } coe(logpipe[1]); coe(logpipe[0]); ndelay_on(logpipe[0]); ndelay_on(logpipe[1]); if (dup2(logpipe[1], 2) == -1) { warnx("cannot set filedescriptor for log"); return -1; } io[0].fd = logpipe[0]; io[0].events = IOPAUSE_READ; taia_now(&stamplog); return 1; }
static void show_config() { int i, len; struct stat st; char buf[4096]; if (stat(status_files[5], &st) < 0) { close(fdlog); fdlog = open_append(status_files[5]); coe(fdlog); } bzero(buf, 4096); snprintf(buf, 4096, "alarm_interval: %u\nmax_tries: %d\nmax_tries_if_coredumped: %d\nalarm_mail : %s\ngsm_list_len: %d\n", alarm_interval, max_tries, max_tries_if_coredumped, alarm_mail, gsm_list_len); for (i = 0; i < gsm_list_len; i++) { len = strlen(buf); snprintf(buf + len, 4096 - len, "alarm_gsm[%d]: %s\n", i, alarm_gsm[i]); } write(fdlog, buf, strlen(buf)); }
int main(int argc,char **argv) { umask(022); fdstartdir = open_read("."); if (fdstartdir == -1) strerr_die2sys(111,FATAL,"unable to switch to current directory: "); coe(fdstartdir); sig_block(sig_term); sig_block(sig_alarm); sig_catch(sig_term,exitasap); sig_catch(sig_alarm,forcerotate); ++argv; f_init(argv); c_init(argv); doit(argv); c_quit(); _exit(0); }
int ipc_accept_internal (int s, char *p, unsigned int l, int *trunc, unsigned int options) { struct sockaddr_un sa ; socklen_t dummy = sizeof sa ; register int fd ; byte_zero((char*)&sa, (unsigned int)dummy) ; do #ifdef SKALIBS_HASACCEPT4 fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ; #else fd = accept(s, (struct sockaddr *)&sa, &dummy) ; #endif while ((fd == -1) && (errno == EINTR)) ; if (fd == -1) return -1 ; #ifndef SKALIBS_HASACCEPT4 if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0) || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0)) { register int e = errno ; fd_close(fd) ; errno = e ; return -1 ; } #endif if (p) { dummy = byte_chr(sa.sun_path, dummy, 0) ; *trunc = 1 ; if (!l) return fd ; if (l < (dummy + 1)) dummy = l - 1 ; else *trunc = 0 ; byte_copy(p, dummy, sa.sun_path) ; p[dummy] = 0 ; } return fd ; }
int main (int argc, const char * const *argv, char * const *envp) { const char * prog[2]; int pid, pid2; int wstat; int st; iopause_fd x; #ifndef IOPAUSE_POLL fd_set rfds; struct timeval t; #endif char ch; int ttyfd; struct stat s; if (getpid() != 1) strerr_die2x(111, FATAL, "must be run as process no 1."); setsid(); sig_block(sig_alarm); sig_block(sig_child); sig_catch(sig_child, sig_child_handler); sig_block(sig_cont); sig_catch(sig_cont, sig_cont_handler); sig_block(sig_hangup); sig_block(sig_int); sig_catch(sig_int, sig_int_handler); sig_block(sig_pipe); sig_block(sig_term); /* console */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 0); dup2(ttyfd, 1); dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } /* create selfpipe */ while (pipe(selfpipe) == -1) { strerr_warn2(FATAL, "unable to create selfpipe, pausing: ", &strerr_sys); sleep(5); } coe(selfpipe[0]); coe(selfpipe[1]); ndelay_on(selfpipe[0]); ndelay_on(selfpipe[1]); #ifdef RB_DISABLE_CAD /* activate ctrlaltdel handling, glibc, dietlibc */ if (RB_DISABLE_CAD == 0) reboot_system(0); #endif strerr_warn3(INFO, "$Id: 25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $", ": booting.", 0); /* runit */ for (st =0; st < 3; st++) { /* if (st == 2) logwtmp("~", "reboot", ""); */ while ((pid =fork()) == -1) { strerr_warn4(FATAL, "unable to fork for \"", stage[st], "\" pausing: ", &strerr_sys); sleep(5); } if (!pid) { /* child */ prog[0] =stage[st]; prog[1] =0; /* stage 1 gets full control of console */ if (st == 0) { if ((ttyfd =open("/dev/console", O_RDWR)) != -1) { #ifdef TIOCSCTTY ioctl(ttyfd, TIOCSCTTY, (char *)0); #endif dup2(ttyfd, 0); if (ttyfd > 2) close(ttyfd); } else strerr_warn2(WARNING, "unable to open /dev/console: ", &strerr_sys); } else setsid(); sig_unblock(sig_alarm); sig_unblock(sig_child); sig_uncatch(sig_child); sig_unblock(sig_cont); sig_ignore(sig_cont); sig_unblock(sig_hangup); sig_unblock(sig_int); sig_uncatch(sig_int); sig_unblock(sig_pipe); sig_unblock(sig_term); strerr_warn3(INFO, "enter stage: ", stage[st], 0); execve(*prog, (char *const *)prog, envp); strerr_die4sys(0, FATAL, "unable to start child: ", stage[st], ": "); } x.fd =selfpipe[0]; x.events =IOPAUSE_READ; for (;;) { int child; sig_unblock(sig_child); sig_unblock(sig_cont); sig_unblock(sig_int); #ifdef IOPAUSE_POLL poll(&x, 1, 14000); #else t.tv_sec =14; t.tv_usec =0; FD_ZERO(&rfds); FD_SET(x.fd, &rfds); select(x.fd +1, &rfds, (fd_set*)0, (fd_set*)0, &t); #endif sig_block(sig_cont); sig_block(sig_child); sig_block(sig_int); while (read(selfpipe[0], &ch, 1) == 1) {} while ((child =wait_nohang(&wstat)) > 0) if (child == pid) break; if (child == -1) { strerr_warn2(WARNING, "wait_nohang, pausing: ", &strerr_sys); sleep(5); } /* reget stderr */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } if (child == pid) { if (wait_exitcode(wstat) != 0) { if (wait_crashed(wstat)) strerr_warn3(WARNING, "child crashed: ", stage[st], 0); else strerr_warn3(WARNING, "child failed: ", stage[st], 0); if (st == 0) /* this is stage 1 */ if (wait_crashed(wstat) || (wait_exitcode(wstat) == 100)) { strerr_warn3(INFO, "leave stage: ", stage[st], 0); strerr_warn2(WARNING, "skipping stage 2...", 0); st++; break; } if (st == 1) /* this is stage 2 */ if (wait_crashed(wstat) || (wait_exitcode(wstat) == 111)) { strerr_warn2(WARNING, "killing all processes in stage 2...", 0); kill(-pid, 9); sleep(5); strerr_warn2(WARNING, "restarting.", 0); st--; break; } } strerr_warn3(INFO, "leave stage: ", stage[st], 0); break; } if (child != 0) { /* collect terminated children */ write(selfpipe[1], "", 1); continue; } /* sig? */ if (!sigc && !sigi) { #ifdef DEBUG strerr_warn2(WARNING, "poll: ", &strerr_sys); #endif continue; } if (st != 1) { strerr_warn2(WARNING, "signals only work in stage 2.", 0); sigc =sigi =0; continue; } if (sigi && (stat(CTRLALTDEL, &s) != -1) && (s.st_mode & S_IXUSR)) { strerr_warn2(INFO, "ctrl-alt-del request...", 0); prog[0] =CTRLALTDEL; prog[1] =0; while ((pid2 =fork()) == -1) { strerr_warn4(FATAL, "unable to fork for \"", CTRLALTDEL, "\" pausing: ", &strerr_sys); sleep(5); } if (!pid2) { /* child */ strerr_warn3(INFO, "enter stage: ", prog[0], 0); execve(*prog, (char *const *) prog, envp); strerr_die4sys(0, FATAL, "unable to start child: ", prog[0], ": "); } if (wait_pid(&wstat, pid2) == -1) strerr_warn2(FATAL, "wait_pid: ", &strerr_sys); if (wait_crashed(wstat)) strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0); strerr_warn3(INFO, "leave stage: ", prog[0], 0); sigi =0; sigc++; } if (sigc && (stat(STOPIT, &s) != -1) && (s.st_mode & S_IXUSR)) { int i; /* unlink(STOPIT); */ chmod(STOPIT, 0); /* kill stage 2 */ #ifdef DEBUG strerr_warn2(WARNING, "sending sigterm...", 0); #endif kill(pid, sig_term); i =0; while (i < 5) { if ((child =wait_nohang(&wstat)) == pid) { #ifdef DEBUG strerr_warn2(WARNING, "stage 2 terminated.", 0); #endif pid =0; break; } if (child) continue; if (child == -1) strerr_warn2(WARNING, "wait_nohang: ", &strerr_sys); #ifdef DEBUG strerr_warn2(WARNING, "waiting...", 0); #endif sleep(1); i++; } if (pid) { /* still there */ strerr_warn2(WARNING, "stage 2 not terminated, sending sigkill...", 0); kill(pid, 9); if (wait_pid(&wstat, pid) == -1) strerr_warn2(WARNING, "wait_pid: ", &strerr_sys); } sigc =0; strerr_warn3(INFO, "leave stage: ", stage[st], 0); /* enter stage 3 */ break; } sigc =sigi =0; #ifdef DEBUG strerr_warn2(WARNING, "no request.", 0); #endif } } /* reget stderr */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } #ifdef RB_AUTOBOOT /* fallthrough stage 3 */ strerr_warn2(INFO, "sending KILL signal to all processes...", 0); kill(-1, SIGKILL); pid =fork(); switch (pid) { case 0: case -1: if ((stat(REBOOT, &s) != -1) && (s.st_mode & S_IXUSR)) { strerr_warn2(INFO, "system reboot.", 0); sync(); reboot_system(RB_AUTOBOOT); } else { #ifdef RB_POWER_OFF strerr_warn2(INFO, "power off...", 0); sync(); reboot_system(RB_POWER_OFF); sleep(2); #endif #ifdef RB_HALT_SYSTEM strerr_warn2(INFO, "system halt.", 0); sync(); reboot_system(RB_HALT_SYSTEM); #else #ifdef RB_HALT strerr_warn2(INFO, "system halt.", 0); sync(); reboot_system(RB_HALT); #else strerr_warn2(INFO, "system reboot.", 0); sync(); reboot_system(RB_AUTOBOOT); #endif #endif } if (pid == 0) _exit(0); break; default: sig_unblock(sig_child); while (wait_pid(0, pid) == -1); } #endif for (;;) sig_pause(); /* not reached */ strerr_die2x(0, INFO, "exit."); return(0); }
unsigned int NAME (char const *prog, char const *const *argv, char const *const *envp, unsigned int uid, unsigned int gid, int *fds) { int p[NPIPES][2] ; int syncpipe[2] ; int pid ; int e ; if (pipe(p[0]) < 0) return 0 ; if (pipe(p[1]) < 0) { e = errno ; goto errp0 ; } #ifdef _CHILD_SPAWN2_ if (pipe(p[2]) < 0) { e = errno ; goto errp1 ; } #endif if (pipe(syncpipe) < 0) { e = errno ; goto errp2 ; } if (coe(syncpipe[1]) < 0) { e = errno ; goto errsp ; } pid = fork() ; if (pid < 0) { e = errno ; goto errsp ; } else if (!pid) { unsigned int m = 25 ; unsigned int n = str_len(PROG) ; char fmt[25 + UINT_FMT] = "SKACLIENT2_ADDITIONAL_FD" ; char name[n + 9] ; byte_copy(name, n, PROG) ; byte_copy(name + n, 9, " (child)") ; PROG = name ; #ifdef _CHILD_SPAWN2_ fmt[m-1] = '=' ; m += uint_fmt(fmt + m, p[2][1]) ; fmt[m++] = 0 ; fd_close(p[2][0]) ; #endif fd_close(syncpipe[0]) ; fd_close(p[1][1]) ; fd_close(p[0][0]) ; if ((fd_move(0, p[1][0]) < 0) || (fd_move(1, p[0][1]) < 0)) goto syncdie ; if (gid && (prot_gid(gid) < 0)) goto syncdie ; if (uid && (prot_uid(uid) < 0)) goto syncdie ; /* XXX: we should unignore signals here, but there's a compromise to be XXX: found between bloat, API complexity, and theoretical correctness. XXX: Not sure what The Right Thing is; just not unignoring atm. XXX: 20130326 edit: The Right Thing is probably to leave the ignore XXX: status alone, because programs that do actual signal handling XXX: are likely to use a selfpipe, and selfpipe_finish() restores XXX: old signal handlers - it knows what to do and we don't. So, XXX: leave that work to selfpipe_finish(). */ sig_blocknone() ; /* empty sigprocmask in the child, always */ pathexec_r_name(prog, argv, envp, env_len(envp), fmt, m) ; syncdie: { char c = errno ; fd_write(syncpipe[1], &c, 1) ; } _exit(111) ; } { char c ; fd_close(syncpipe[1]) ; #ifdef _CHILD_SPAWN2_ fd_close(p[2][1]) ; #endif fd_close(p[1][0]) ; fd_close(p[0][1]) ; p[1][0] = fd_read(syncpipe[0], &c, 1) ; if (p[1][0] < 0) goto killclosewait ; else if (p[1][0]) { e = c ; goto closewait ; } } fd_close(syncpipe[0]) ; if ((ndelay_on(p[0][0]) < 0) || (coe(p[0][0]) < 0) || (ndelay_on(p[1][1]) < 0) || (coe(p[1][1]) < 0)) goto killclosewait ; #ifdef _CHILD_SPAWN2_ if ((ndelay_on(p[2][0]) < 0) || (coe(p[2][0]) < 0)) goto killclosewait ; fds[2] = p[2][0] ; #endif fds[0] = p[0][0] ; fds[1] = p[1][1] ; return (unsigned int)pid ; errsp: fd_close(syncpipe[1]) ; fd_close(syncpipe[0]) ; errp2: #ifdef _CHILD_SPAWN2_ fd_close(p[2][1]) ; fd_close(p[2][0]) ; errp1: #endif fd_close(p[1][1]) ; fd_close(p[1][0]) ; errp0: fd_close(p[0][1]) ; fd_close(p[0][0]) ; errno = e ; return 0 ; killclosewait: e = errno ; kill(pid, SIGKILL) ; closewait: #ifdef _CHILD_SPAWN2_ fd_close(p[2][0]) ; #endif fd_close(p[1][1]) ; fd_close(p[0][0]) ; wait_pid(&syncpipe[1], pid) ; errno = e ; return 0 ; }
int main(int argc, char **argv) { int fdfifo, fdfifowrite; char *x; unsigned long id; VERSIONINFO; x = env_get("WORKDIR"); if (!x) strerr_die2x(111, FATAL, "$WORKDIR not set"); if (chdir(x) == -1) strerr_die4sys(111, FATAL, "unable to chdir to ", x, ": "); x = env_get("GID"); if (!x) strerr_die2x(111, FATAL, "$GID not set"); scan_ulong(x,&id); if (prot_gid((int) id) == -1) strerr_die2sys(111, FATAL, "unable to setgid: "); x = env_get("UID"); if (!x) strerr_die2x(111, FATAL, "$UID not set"); scan_ulong(x,&id); /* undocumented feature */ if(id == 0) if(!env_get("IWANTTORUNASROOTANDKNOWWHATIDO")) strerr_die2x(111, FATAL, "unable to run under uid 0: please change $UID"); if (prot_uid((int) id) == -1) strerr_die2sys(111, FATAL, "unable to setuid: "); buffer_putsflush(buffer_2, ARGV0 "starting\n"); if(fifo_make(FIFONAME, 0620) == -1) strerr_warn4(ARGV0, "unable to create fifo ", FIFONAME, " ", &strerr_sys); fdfifo = open_read(FIFONAME); if(fdfifo == -1) strerr_die4sys(111, FATAL, "unable to open for read ", FIFONAME, " "); coe(fdfifo); ndelay_on(fdfifo); /* DJB says: shouldn't be necessary */ /* we need this to keep the fifo from beeing closed */ fdfifowrite = open_write(FIFONAME); if (fdfifowrite == -1) strerr_die4sys(111, FATAL, "unable to open for write ", FIFONAME, " "); coe(fdfifowrite); /* init a buffer for nonblocking reading */ buffer_init(&wr, waitread, fdfifo, waitreadspace, sizeof waitreadspace); t = dAVLAllocTree(); /* read snapshot of dnsdatatree */ fill_db(); /* SIGALRM can be used to check if dumping the database is needed */ sig_catch(sig_alarm, sigalrm); /* SIGHUP can be used to force dumping the database */ sig_catch(sig_hangup, sighup); /* check if out child is done */ sig_catch(sig_child, sigchld); // XXX SIGINT, SIGTERM, /* do our normal workloop */ doit(); /* we shouldn't get here */ return 1; }
void restart(struct cyclog *d) { struct stat st; int fd; int flagprocessed; if (fchdir(fdstartdir) == -1) strerr_die2sys(111,FATAL,"unable to switch to starting directory: "); mkdir(d->dir,0700); d->fddir = open_read(d->dir); if ((d->fddir == -1) || (fchdir(d->fddir) == -1)) strerr_die4sys(111,FATAL,"unable to open directory ",d->dir,": "); coe(d->fddir); d->fdlock = open_append("lock"); if ((d->fdlock == -1) || (lock_exnb(d->fdlock) == -1)) strerr_die4sys(111,FATAL,"unable to lock directory ",d->dir,": "); coe(d->fdlock); if (stat("current",&st) == -1) { if (errno != error_noent) strerr_die4sys(111,FATAL,"unable to stat ",d->dir,"/current: "); } else if (st.st_mode & 0100) { fd = open_append("current"); if (fd == -1) strerr_die4sys(111,FATAL,"unable to append to ",d->dir,"/current: "); if (fchmod(fd,0644) == -1) strerr_die4sys(111,FATAL,"unable to set mode of ",d->dir,"/current: "); coe(fd); d->fdcurrent = fd; d->bytes = st.st_size; return; } unlink("state"); unlink("newstate"); flagprocessed = 0; if (stat("processed",&st) == -1) { if (errno != error_noent) strerr_die4sys(111,FATAL,"unable to stat ",d->dir,"/processed: "); } else if (st.st_mode & 0100) flagprocessed = 1; if (flagprocessed) { unlink("previous"); finish(d,"processed","s"); } else { unlink("processed"); finish(d,"previous","u"); } finish(d,"current","u"); fd = open_trunc("state"); if (fd == -1) strerr_die4sys(111,FATAL,"unable to write to ",d->dir,"/state: "); close(fd); fd = open_append("current"); if (fd == -1) strerr_die4sys(111,FATAL,"unable to write to ",d->dir,"/current: "); if (fchmod(fd,0644) == -1) strerr_die4sys(111,FATAL,"unable to set mode of ",d->dir,"/current: "); coe(fd); d->fdcurrent = fd; d->bytes = 0; }
void fullcurrent(struct cyclog *d) { int fd; int pid; int wstat; while (fchdir(d->fddir) == -1) pause3("unable to switch to ",d->dir,", pausing: "); while (fsync(d->fdcurrent) == -1) pause3("unable to write ",d->dir,"/current to disk, pausing: "); close(d->fdcurrent); while (rename("current","previous") == -1) pause3("unable to rename current to previous in directory ",d->dir,", pausing: "); while ((d->fdcurrent = open_append("current")) == -1) pause3("unable to create ",d->dir,"/current, pausing: "); coe(d->fdcurrent); d->bytes = 0; while (fchmod(d->fdcurrent,0644) == -1) pause3("unable to set mode of ",d->dir,"/current, pausing: "); while (chmod("previous",0744) == -1) pause3("unable to set mode of ",d->dir,"/previous, pausing: "); if (!d->processor) finish(d,"previous","s"); else { for (;;) { while ((pid = fork()) == -1) pause3("unable to fork for processor in ",d->dir,", pausing: "); if (!pid) { startprocessor(d); strerr_die4sys(111,FATAL,"unable to run ",d->processor,": "); } if (wait_pid(&wstat,pid) == -1) pause3("wait failed for processor in ",d->dir,", pausing: "); else if (wait_crashed(wstat)) pause3("processor crashed in ",d->dir,", pausing: "); else if (!wait_exitcode(wstat)) break; strerr_warn4(WARNING,"processor failed in ",d->dir,", pausing",0); deepsleep(5); } while ((fd = open_append("processed")) == -1) pause3("unable to create ",d->dir,"/processed, pausing: "); while (fsync(fd) == -1) pause3("unable to write ",d->dir,"/processed to disk, pausing: "); while (fchmod(fd,0744) == -1) pause3("unable to set mode of ",d->dir,"/processed, pausing: "); close(fd); while ((fd = open_append("newstate")) == -1) pause3("unable to create ",d->dir,"/newstate, pausing: "); while (fsync(fd) == -1) pause3("unable to write ",d->dir,"/newstate to disk, pausing: "); close(fd); while (unlink("previous") == -1) pause3("unable to remove ",d->dir,"/previous, pausing: "); while (rename("newstate","state") == -1) pause3("unable to rename newstate to state in directory ",d->dir,", pausing: "); finish(d,"processed","s"); } }
int runsvdir_main(int argc, char **argv) { struct stat s; dev_t last_dev = last_dev; /* for gcc */ ino_t last_ino = last_ino; /* for gcc */ time_t last_mtime = 0; int wstat; int curdir; int pid; unsigned deadline; unsigned now; unsigned stampcheck; char ch; int i; argv++; if (!*argv) bb_show_usage(); if (argv[0][0] == '-') { switch (argv[0][1]) { case 'P': set_pgrp = 1; case '-': ++argv; } if (!*argv) bb_show_usage(); } sig_catch(SIGTERM, s_term); sig_catch(SIGHUP, s_hangup); svdir = *argv++; if (argv && *argv) { rplog = *argv; if (setup_log() != 1) { rplog = 0; warnx("log service disabled"); } } curdir = open_read("."); if (curdir == -1) fatal2_cannot("open current directory", ""); coe(curdir); stampcheck = monotonic_sec(); for (;;) { /* collect children */ for (;;) { pid = wait_nohang(&wstat); if (pid <= 0) break; for (i = 0; i < svnum; i++) { if (pid == sv[i].pid) { /* runsv has gone */ sv[i].pid = 0; check = 1; break; } } } now = monotonic_sec(); if ((int)(now - stampcheck) >= 0) { /* wait at least a second */ stampcheck = now + 1; if (stat(svdir, &s) != -1) { if (check || s.st_mtime != last_mtime || s.st_ino != last_ino || s.st_dev != last_dev ) { /* svdir modified */ if (chdir(svdir) != -1) { last_mtime = s.st_mtime; last_dev = s.st_dev; last_ino = s.st_ino; check = 0; //if (now <= mtime) // sleep(1); runsvdir(); while (fchdir(curdir) == -1) { warn2_cannot("change directory, pausing", ""); sleep(5); } } else warn2_cannot("change directory to ", svdir); } } else warn2_cannot("stat ", svdir); } if (rplog) { if ((int)(now - stamplog) >= 0) { write(logpipe[1], ".", 1); stamplog = now + 900; } } pfd[0].revents = 0; sig_block(SIGCHLD); deadline = (check ? 1 : 5); if (rplog) poll(pfd, 1, deadline*1000); else sleep(deadline); sig_unblock(SIGCHLD); if (pfd[0].revents & POLLIN) { while (read(logpipe[0], &ch, 1) > 0) { if (ch) { for (i = 6; i < rploglen; i++) rplog[i-1] = rplog[i]; rplog[rploglen-1] = ch; } } } switch (exitsoon) { case 1: _exit(0); case 2: for (i = 0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM); _exit(111); } } /* not reached */ return 0; }
int main(int argc, char **argv) { struct sigaction sa; if (parse_argv(argc, argv) < 0) _exit(100); snprintf(status_files[0], 1024, "%s/lock", status_dir); snprintf(status_files[1], 1024, "%s/control", status_dir); snprintf(status_files[2], 1024, "%s/ok", status_dir); snprintf(status_files[3], 1024, "%s/status", status_dir); snprintf(status_files[4], 1024, "%s/status.new", status_dir); snprintf(status_files[5], 1024, "%s/supervise.log", status_dir); snprintf(status_files[6], 1024, "%s/supervise.log.wf", status_dir); sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); if (sigaction(SIGHUP, &sa, NULL) < 0) { printf("unable to ignore SIGHUP for %s\n", service); _exit(110); } if (mkdir(status_dir, 0700) < 0 && errno != EEXIST) { printf("unable to create dir: %s\n", status_dir); _exit(110); } fdlog = open_append(status_files[5]); if (fdlog == -1) { printf("unable to open %s%s", status_dir, "/supervise.log"); _exit(111); } coe(fdlog); fdlogwf = open_append(status_files[6]); if (fdlogwf == -1) { printf("unable to open %s%s", status_dir, "/supervise.log.wf"); _exit(1); } coe(fdlogwf); if (daemon(1, 0) < 0) { printf("failed to daemonize supervise!\n"); _exit(111); } if (pipe(selfpipe) == -1) { write_log(fdlogwf, FATAL, "unable to create pipe for ", service, "\n"); _exit(111); } coe(selfpipe[0]); coe(selfpipe[1]); ndelay_on(selfpipe[0]); ndelay_on(selfpipe[1]); sig_block(sig_child); sig_catch(sig_child, trigger); sig_block(sig_alarm); sig_catch(sig_alarm, timer_handler); sig_unblock(sig_alarm); fdlock = open_append(status_files[0]); if ((fdlock == -1) || (lock_exnb(fdlock) == -1)) { write_log(fdlogwf, FATAL, "Unable to acquier ", status_dir, "/lock\n"); _exit(111); } coe(fdlock); fifo_make(status_files[1], 0600); fdcontrol = open_read(status_files[1]); if (fdcontrol == -1) { write_log(fdlogwf, FATAL, "unable to read ", status_dir, "/control\n"); _exit(1); } coe(fdcontrol); ndelay_on(fdcontrol); fdcontrolwrite = open_write(status_files[1]); if (fdcontrolwrite == -1) { write_log(fdlogwf, FATAL, "unable to write ", status_dir, "/control\n"); _exit(1); } coe(fdcontrolwrite); fifo_make(status_files[2], 0600); fdok = open_read(status_files[2]); if (fdok == -1) { write_log(fdlogwf, FATAL, "unable to read ", status_dir, "/ok\n"); _exit(1); } coe(fdok); if (!restart_sh[0]) { parse_conf(); } pidchange(); announce(); if (!flagwant || flagwantup) trystart(); doit(); announce(); _exit(0); }
int main(int argc, char **argv) { struct stat s; time_t mtime =0; int wstat; int curdir; int pid; struct taia deadline; struct taia now; struct taia stampcheck; char ch; int i; progname =*argv++; if (! argv || ! *argv) usage(); if (**argv == '-') { switch (*(*argv +1)) { case 'P': pgrp =1; case '-': ++argv; } if (! argv || ! *argv) usage(); } sig_catch(sig_term, s_term); sig_catch(sig_hangup, s_hangup); svdir =*argv++; if (argv && *argv) { rplog =*argv; if (setup_log() != 1) { rplog =0; warn3x("log service disabled.", 0, 0); } } if ((curdir =open_read(".")) == -1) fatal("unable to open current directory", 0); coe(curdir); taia_now(&stampcheck); for (;;) { /* collect children */ for (;;) { if ((pid =wait_nohang(&wstat)) <= 0) break; for (i =0; i < svnum; i++) { if (pid == sv[i].pid) { /* runsv has gone */ sv[i].pid =0; check =1; break; } } } taia_now(&now); if (now.sec.x < (stampcheck.sec.x -3)) { /* time warp */ warn3x("time warp: resetting time stamp.", 0, 0); taia_now(&stampcheck); taia_now(&now); if (rplog) taia_now(&stamplog); } if (taia_less(&now, &stampcheck) == 0) { /* wait at least a second */ taia_uint(&deadline, 1); taia_add(&stampcheck, &now, &deadline); if (stat(svdir, &s) != -1) { if (check || \ s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev) { /* svdir modified */ if (chdir(svdir) != -1) { mtime =s.st_mtime; dev =s.st_dev; ino =s.st_ino; check =0; if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime)) sleep(1); runsvdir(); while (fchdir(curdir) == -1) { warn("unable to change directory, pausing", 0); sleep(5); } } else warn("unable to change directory to ", svdir); } } else warn("unable to stat ", svdir); } if (rplog) if (taia_less(&now, &stamplog) == 0) { write(logpipe[1], ".", 1); taia_uint(&deadline, 900); taia_add(&stamplog, &now, &deadline); } /* half a second */ deadline.sec.x =0; deadline.nano =500000000UL; deadline.atto =0; taia_add(&deadline, &now, &deadline); sig_block(sig_child); if (rplog) iopause(io, 1, &deadline, &now); else iopause(0, 0, &deadline, &now); sig_unblock(sig_child); if (rplog && (io[0].revents | IOPAUSE_READ)) while (read(logpipe[0], &ch, 1) > 0) if (ch) { for (i =6; i < rploglen; i++) rplog[i -1] =rplog[i]; rplog[rploglen -1] =ch; } switch(exitsoon) { case 1: _exit(0); case 2: for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM); _exit(111); } } /* for (;;) */ /* not reached */ _exit(0); }