Exemple #1
0
void el_execsequence (char const *const *argv1, char const *const *argv2, char const *const *envp)
{
  if (!argv2[0])
  {
    pathexec0_run(argv1, envp) ;
    strerr_dieexec(111, argv1[0]) ;
  }
  else
  {
    int wstat ;
    unsigned int j = 2 ;
#ifdef EXECLINE_OLD_VARNAMES
    char fmt[UINT_FMT * 2 + 15] = "?=" ;
#else
    char fmt[UINT_FMT + 1] = "?=" ;
#endif
    pid_t pid = el_spawn0(argv1[0], argv1, envp) ;
    if (!pid) strerr_warnwu2sys("spawn ", argv1[0]) ;
    if (wait_pid(pid, &wstat) < 0)
      strerr_diefu2sys(111, "wait for ", argv1[0]) ;
    j += uint_fmt(fmt + j, wait_status(wstat)) ; fmt[j++] = 0 ;
#ifdef EXECLINE_OLD_VARNAMES
    byte_copy(fmt + j, 13, "LASTEXITCODE=") ; j += 13 ;
    j += uint_fmt(fmt + j, wait_status(wstat)) ; fmt[j++] = 0 ;
#endif
    pathexec_r(argv2, envp, env_len(envp), fmt, j) ;
  }
  strerr_dieexec(111, argv2[0]) ;
}
Exemple #2
0
int main (int argc, char const *const *argv, char const *const *envp)
{
  int incr = 10 ;
  int strict = 0 ;
  PROG = "s6-nice" ;
  {
    subgetopt_t l = SUBGETOPT_ZERO ;
    for (;;)
    {
      register int opt = subgetopt_r(argc, argv, "Iin:", &l) ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 'I' : strict = 0 ; break ;
        case 'i' : strict = 1 ; break ;
        case 'n': if (!int_scan(l.arg, &incr)) strerr_dieusage(100, USAGE) ; break ;
        default : strerr_dieusage(100, USAGE) ;
      }
    }
    argc -= l.ind ; argv += l.ind ;
  }
  if (!argc) strerr_dieusage(100, USAGE) ;

  errno = 0 ;
  if ((nice(incr) < 0) && errno)
  {
    char fmt[1+UINT_FMT] ;
    fmt[int_fmt(fmt, incr)] = 0 ;
    if (strict) strerr_diefu2sys(111, "nice to ", fmt) ;
    else strerr_warnwu2sys("nice to ", fmt) ;
  }
  pathexec_run(argv[0], argv, envp) ;
  strerr_dieexec((errno == ENOENT) ? 127 : 126, argv[0]) ;
}
Exemple #3
0
static inline void tryfinish (int islast)
{
  register pid_t pid = fork() ;
  if (pid < 0)
  {
    strerr_warnwu2sys("fork for ", "./finish") ;
    if (islast) bail() ;
    state = DOWN ;
    settimeout(1) ;
    return ;
  }
  else if (!pid)
  {
    char fmt0[UINT_FMT] ;
    char fmt1[UINT_FMT] ;
    char *cargv[4] = { "finish", fmt0, fmt1, 0 } ;
    selfpipe_finish() ;
    fmt0[uint_fmt(fmt0, WIFSIGNALED(status.wstat) ? 256 : WEXITSTATUS(status.wstat))] = 0 ;
    fmt1[uint_fmt(fmt1, WTERMSIG(status.wstat))] = 0 ;
    if (flagsetsid) setsid() ;
    execve("./finish", cargv, (char *const *)environ) ;
    _exit(127) ;
  }
  status.pid = pid ;
  status.flagfinishing = 1 ;
  state = islast ? LASTFINISH : FINISH ;
}
Exemple #4
0
static int doit (char const *s)
{
  if (mkdir(s, 0755) == -1)
  {
    if (errno != EEXIST)
    {
      strerr_warnwu2sys("mkdir ", s) ;
      return 111 ;
    }
  }
  return 0 ;
}
Exemple #5
0
static void trystart (unsigned int i, char const *name, int islog)
{
  int pid = fork() ;
  switch (pid)
  {
    case -1 :
      tain_addsec_g(&services[i].restartafter[islog], CHECK_RETRY_TIMEOUT) ;
      strerr_warnwu2sys("fork for ", name) ;
      return ;
    case 0 :
    {
      char const *cargv[3] = { "s6-supervise", name, 0 } ;
      PROG = "s6-svscan (child)" ;
      selfpipe_finish() ;
      if (services[i].flaglog)
        if (fd_move(!islog, services[i].p[!islog]) == -1)
          strerr_diefu2sys(111, "set fds for ", name) ;
      pathexec_run(S6_BINPREFIX "s6-supervise", cargv, (char const **)environ) ;
      strerr_dieexec(111, S6_BINPREFIX "s6-supervise") ;
    }
  }
  services[i].pid[islog] = pid ;
}
Exemple #6
0
static void check (char const *name)
{
  struct stat st ;
  unsigned int namelen ;
  unsigned int i = 0 ;
  if (name[0] == '.') return ;
  if (stat(name, &st) == -1)
  {
    strerr_warnwu2sys("stat ", name) ;
    retrydirlater() ;
    return ;
  }
  if (!S_ISDIR(st.st_mode)) return ;
  namelen = str_len(name) ;
  for (; i < n ; i++) if ((services[i].ino == st.st_ino) && (services[i].dev == st.st_dev)) break ;
  if (i < n)
  {
    if (services[i].flaglog && (services[i].p[0] < 0))
    {
     /* See BLACK MAGIC above. */
      services[i].p[0] = -2 ;
      return ;
    }
  }
  else
  {
    if (n >= max)
    {
      strerr_warnwu3x("start supervisor for ", name, ": too many services") ;
      return ;
    }
    else
    {
      struct stat su ;
      char tmp[namelen + 5] ;
      byte_copy(tmp, namelen, name) ;
      byte_copy(tmp + namelen, 5, "/log") ;
      if (stat(tmp, &su) < 0)
        if (errno == ENOENT) services[i].flaglog = 0 ;
        else
        {
          strerr_warnwu2sys("stat ", tmp) ;
          retrydirlater() ;
          return ;
        }
      else if (!S_ISDIR(su.st_mode))
        services[i].flaglog = 0 ;
      else
      {
        if (pipecoe(services[i].p) < 0)
        {
          strerr_warnwu1sys("pipecoe") ;
          retrydirlater() ;
          return ;
        }
        services[i].flaglog = 1 ;
      }
      services[i].ino = st.st_ino ;
      services[i].dev = st.st_dev ;
      tain_copynow(&services[i].restartafter[0]) ;
      tain_copynow(&services[i].restartafter[1]) ;
      services[i].pid[0] = 0 ;
      services[i].pid[1] = 0 ;
      n++ ;
    }
  }
  
  services[i].flagactive = 1 ;

  if (services[i].flaglog && !services[i].pid[1])
  {
    if (!tain_future(&services[i].restartafter[1]))
    {
      char tmp[namelen + 5] ;
      byte_copy(tmp, namelen, name) ;
      byte_copy(tmp + namelen, 5, "/log") ;
      trystart(i, tmp, 1) ;
    }
    else if (tain_less(&services[i].restartafter[1], &deadline))
      deadline = services[i].restartafter[1] ;
  }

  if (!services[i].pid[0])
  {
    if (!tain_future(&services[i].restartafter[0]))
      trystart(i, name, 0) ;
    else if (tain_less(&services[i].restartafter[0], &deadline))
      deadline = services[i].restartafter[0] ;
  }
}
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 ;
}
Exemple #8
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 ;
}