int main (int argc, char *const *argv) { stralloc3 blah = STRALLOC3_ZERO ; PROG = "s6-update-symlinks" ; if (argc < 3) strerr_dieusage(100, USAGE) ; { register char *const *p = argv + 1 ; for (; *p ; p++) if (**p != '/') strerr_dieusage(100, USAGE) ; } { register unsigned int i = str_len(argv[1]) ; while (i && (argv[1][i-1] == '/')) argv[1][--i] = 0 ; if (!i) strerr_diefu1x(100, "replace root directory") ; } if (!makeuniquename(&blah.dst, argv[1], MAGICNEW)) strerr_diefu2sys(111, "make random unique name based on ", argv[1]) ; if ((unlink(blah.dst.s) == -1) && (errno != ENOENT)) strerr_diefu2sys(111, "unlink ", blah.dst.s) ; { char *const *p = argv + 2 ; for (; *p ; p++) { register int r ; blah.src.len = 0 ; if (!stralloc_cats(&blah.src, *p) || !stralloc_0(&blah.src)) strerr_diefu1sys(111, "make stralloc") ; r = addlink(&blah, 0, 0) ; if (r < 0) { stralloc_free(&blah.tmp) ; stralloc_free(&blah.src) ; cleanup(&blah.dst, 0) ; stralloc_free(&blah.dst) ; if (r == CONFLICT) strerr_dief4x(100, "destination ", errdst.s, " conflicts with source ", errsrc.s) ; else strerr_dief2sys(111, "error processing ", *p) ; } } } stralloc_free(&blah.tmp) ; if (rename(blah.dst.s, argv[1]) == -1) /* be atomic if possible */ { blah.src.len = 0 ; if (!makeuniquename(&blah.src, argv[1], MAGICOLD)) { cleanup(&blah.dst, 0) ; strerr_diefu2sys(111, "make random unique name based on ", argv[1]) ; } if (rename(argv[1], blah.src.s) == -1) { cleanup(&blah.dst, 0) ; strerr_diefu4sys(111, "rename ", argv[1], " to ", blah.src.s) ; } /* XXX: unavoidable race condition here: argv[1] does not exist */ if (rename(blah.dst.s, argv[1]) == -1) { rename(blah.src.s, argv[1]) ; cleanup(&blah.dst, 0) ; strerr_diefu4sys(111, "rename ", blah.dst.s, " to ", argv[1]) ; } stralloc_free(&blah.dst) ; if (rm_rf_in_tmp(&blah.src, 0) == -1) strerr_warnwu2sys("remove old directory ", blah.src.s) ; stralloc_free(&blah.src) ; } return 0 ; }
int main (int argc, char const *const *argv) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; PROG = "s6-supervise" ; if (argc < 2) strerr_dieusage(100, USAGE) ; if (chdir(argv[1]) < 0) strerr_diefu2sys(111, "chdir to ", argv[1]) ; { register unsigned int proglen = str_len(PROG) ; register unsigned int namelen = str_len(argv[1]) ; char progname[proglen + namelen + 2] ; byte_copy(progname, proglen, PROG) ; progname[proglen] = ' ' ; byte_copy(progname + proglen + 1, namelen + 1, argv[1]) ; PROG = progname ; if (!fd_sanitize()) strerr_diefu1sys(111, "sanitize stdin and stdout") ; x[1].fd = s6_supervise_lock(S6_SUPERVISE_CTLDIR) ; if (!ftrigw_fifodir_make(S6_SUPERVISE_EVENTDIR, getegid(), 0)) strerr_diefu2sys(111, "mkfifodir ", S6_SUPERVISE_EVENTDIR) ; x[0].fd = selfpipe_init() ; if (x[0].fd == -1) strerr_diefu1sys(111, "init selfpipe") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGTERM) ; sigaddset(&set, SIGHUP) ; sigaddset(&set, SIGQUIT) ; sigaddset(&set, SIGCHLD) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } if (!ftrigw_clean(S6_SUPERVISE_EVENTDIR)) strerr_warnwu2sys("ftrigw_clean ", S6_SUPERVISE_EVENTDIR) ; { struct stat st ; if (stat("down", &st) == -1) { if (errno != ENOENT) strerr_diefu1sys(111, "stat down") ; } else status.flagwantup = 0 ; if (stat("nosetsid", &st) == -1) { if (errno != ENOENT) strerr_diefu1sys(111, "stat nosetsid") ; } else flagsetsid = 0 ; } tain_now_g() ; settimeout(0) ; tain_copynow(&status.stamp) ; announce() ; ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ; while (cont) { register int r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) (*actions[state][V_TIMEOUT])() ; else { if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) strerr_diefu1x(111, "iopause: trouble with pipes") ; if (x[0].revents & IOPAUSE_READ) handle_signals() ; else if (x[1].revents & IOPAUSE_READ) handle_control(x[1].fd) ; } } ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "x", 1) ; } return 0 ; }