int main(int argc,const char * const *argv,const char * const *envp) { char ch; int wstat; int pi[2]; int i; int ignored; if (!argv[1]) strerr_die1x(100,"fghack: usage: fghack child"); if (pipe(pi) == -1) strerr_die2sys(111,FATAL,"unable to create pipe: "); switch(pid = fork()) { case -1: strerr_die2sys(111,FATAL,"unable to fork: "); case 0: close(pi[0]); for (i = 0;i < 30;++i) ignored = dup(pi[1]); pathexec_run(argv[1],argv + 1,envp); strerr_die4sys(111,FATAL,"unable to run ",argv[1],": "); } close(pi[1]); for (;;) { i = buffer_unixread(pi[0],&ch,1); if ((i == -1) && (errno == error_intr)) continue; if (i == 1) continue; break; } if (wait_pid(&wstat,pid) == -1) strerr_die2sys(111,FATAL,"wait failed: "); if (wait_crashed(wstat)) strerr_die2x(111,FATAL,"child crashed"); _exit(wait_exitcode(wstat)); }
void doit(char *dir) { struct stat st; int r; int fd; const char *x; const char *fntemp; char status[40]; buffer_puts(&b,dir); buffer_puts(&b,": "); if (chdir(dir) == -1) { x = error_str(errno); buffer_puts(&b,"unable to chdir: "); buffer_puts(&b,x); return; } if (!svpath_init()) { strerr_warn4(WARNING,"unable to set up control path for ",dir,": ",&strerr_sys); return; } normallyup = 0; if (stat("down",&st) == -1) { if (errno != error_noent) { x = error_str(errno); buffer_puts(&b,"unable to stat down: "); buffer_puts(&b,x); return; } normallyup = 1; } if ((fntemp = svpath_make("/ok")) == 0) die_nomem(); fd = open_write(fntemp); if (fd == -1) { if (errno == error_nodevice) { buffer_puts(&b,"supervise not running"); return; } x = error_str(errno); buffer_puts(&b,"unable to open "); buffer_puts(&b,fntemp); buffer_puts(&b,": "); buffer_puts(&b,x); return; } close(fd); if ((fntemp = svpath_make("/status")) == 0) die_nomem(); fd = open_read(fntemp); if (fd == -1) { x = error_str(errno); buffer_puts(&b,"unable to open "); buffer_puts(&b,fntemp); buffer_puts(&b,": "); buffer_puts(&b,x); return; } r = buffer_unixread(fd,status,sizeof status); close(fd); if (r < 18) { if (r == -1) x = error_str(errno); else x = "bad format"; buffer_puts(&b,"unable to read "); buffer_puts(&b,fntemp); buffer_puts(&b,": "); buffer_puts(&b,x); return; } showstatus(status,r); if (r >= 20+18) { buffer_puts(&b,"\n"); buffer_puts(&b,dir); buffer_puts(&b," log: "); showstatus(status+20,r-20); } }
int main(int argc, const char * const *argv) { int opt; unsigned long sec =600; int verbose =0; int doexit =0; int dokill =0; int wdir; int fd; char status[20]; int r; unsigned long pid; struct tai start; struct tai now; progname =*argv; while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) { switch(opt) { case 't': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 6000)) usage(); break; case 'x': doexit =1; break; case 'k': dokill =1; break; case 'v': verbose =1; break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); for (dir =argv; *dir; ++dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) continue; /* bummer */ if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */ if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { close(fd); continue; /* bummer */ } close(fd); } dir =argv; tai_now(&start); while (*dir) { if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, 20); close(fd); if ((r < 18) || (r == 19)) { /* supervise compatibility */ if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! doexit && ! pid) { /* ok, service is down */ if (verbose) strerr_warn3(INFO, *dir, ": down.", 0); dir++; continue; } if (status[17] != 'd') { /* catch previous failures */ if ((fd =open_write("supervise/control")) == -1) { warn(*dir, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { warn(*dir, ": unable to write to supervise/control: ", &strerr_sys); close(fd); continue; } close(fd); } tai_now(&now); tai_sub(&now, &now, &start); if (tai_approx(&now) >= sec) { /* timeout */ if (verbose) strerr_warn2(INFO, "timeout.", 0); if (dokill) { if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/control")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*argv, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "k", 1) != 1) warn(*argv, ": unable to write to supervise/control: ", &strerr_sys); else strerr_warn3(INFO, *dir, ": killed.", 0); close(fd); dir++; if (! *dir) _exit(111); continue; } _exit(111); } sleep(1); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
int main(int argc, const char * const *argv) { int opt; int verbose =0; char status[18]; int fd; int is; int r; int wdir; unsigned long pid; struct tai when; struct tai now; char sulong[FMT_ULONG]; progname =*argv; while ((opt =getopt(argc, argv, "s:vV")) != opteof) { switch(opt) { case 's': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 600)) usage(); break; case 'v': verbose =1; break; case 'V': strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); dir =argv; while (*dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) warn(*dir, ": runsv not running.", 0); else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, sizeof status); close(fd); if (r < sizeof status) { if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! pid) { warn(*dir, ": is down.", 0); continue; } tai_unpack(status, &when); tai_now(&now); if (tai_less(&now, &when)) when =now; tai_sub(&when, &now, &when); is =tai_approx(&when); if (is >= sec) { /* ok */ if (verbose) { sulong[fmt_ulong(sulong, is)] =0; strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0); } dir++; continue; } sleep(sec -is); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
void doit(char *dir) { struct stat st; int r; int fd; const char *x; struct tai when; struct tai now; buffer_puts(&b,dir); buffer_puts(&b,": "); if (chdir(dir) == -1) { x = error_str(errno); buffer_puts(&b,"unable to chdir: "); buffer_puts(&b,x); return; } normallyup = 0; if (stat("down",&st) == -1) { if (errno != error_noent) { x = error_str(errno); buffer_puts(&b,"unable to stat down: "); buffer_puts(&b,x); return; } normallyup = 1; } fd = open_write("supervise/ok"); if (fd == -1) { if (errno == error_nodevice) { buffer_puts(&b,"supervise not running"); return; } x = error_str(errno); buffer_puts(&b,"unable to open supervise/ok: "); buffer_puts(&b,x); return; } close(fd); fd = open_read("supervise/status"); if (fd == -1) { x = error_str(errno); buffer_puts(&b,"unable to open supervise/status: "); buffer_puts(&b,x); return; } r = buffer_unixread(fd,status,sizeof status); close(fd); if (r < sizeof status) { if (r == -1) x = error_str(errno); else x = "bad format"; buffer_puts(&b,"unable to read supervise/status: "); buffer_puts(&b,x); return; } pid = (unsigned char) status[15]; pid <<= 8; pid += (unsigned char) status[14]; pid <<= 8; pid += (unsigned char) status[13]; pid <<= 8; pid += (unsigned char) status[12]; paused = status[16]; want = status[17]; tai_unpack(status,&when); tai_now(&now); if (tai_less(&now,&when)) when = now; tai_sub(&when,&now,&when); if (pid) { buffer_puts(&b,"up (pid "); buffer_put(&b,strnum,fmt_ulong(strnum,pid)); buffer_puts(&b,") "); } else buffer_puts(&b,"down "); buffer_put(&b,strnum,fmt_ulong(strnum,tai_approx(&when))); buffer_puts(&b," seconds"); if (pid && !normallyup) buffer_puts(&b,", normally down"); if (!pid && normallyup) buffer_puts(&b,", normally up"); if (pid && paused) buffer_puts(&b,", paused"); if (!pid && (want == 'u')) buffer_puts(&b,", want up"); if (pid && (want == 'd')) buffer_puts(&b,", want down"); }