Exemplo n.º 1
0
static void trystart (void)
{
  int p[2] ;
  pid_t pid ;
  if (pipecoe(p) < 0)
  {
    settimeout(60) ;
    strerr_warnwu1sys("pipecoe (waiting 60 seconds)") ;
    return ;
  }
  pid = fork() ;
  if (pid < 0)
  {
    settimeout(60) ;
    strerr_warnwu1sys("fork (waiting 60 seconds)") ;
    fd_close(p[1]) ; fd_close(p[0]) ;
    return ;
  }
  else if (!pid)
  {
    char const *cargv[2] = { "run", 0 } ;
    PROG = "s6-supervise (child)" ;
    selfpipe_finish() ;
    fd_close(p[0]) ;
    if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT)
      strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ;
    if (flagsetsid) setsid() ;
    execve("./run", (char *const *)cargv, (char *const *)environ) ;
    fd_write(p[1], "", 1) ;
    strerr_dieexec(127, "run") ;
  }
  fd_close(p[1]) ;
  {
    char c ;
    switch (fd_read(p[0], &c, 1))
    {
      case -1 :
        fd_close(p[0]) ;
        settimeout(60) ;
        strerr_warnwu1sys("read pipe (waiting 60 seconds)") ;
        kill(pid, SIGKILL) ;
        return ;
      case 1 :
      {
        fd_close(p[0]) ;
        settimeout(10) ;
        strerr_warnwu1x("spawn ./run - waiting 10 seconds") ;
        return ;
      }
    }
  }
  fd_close(p[0]) ;
  settimeout_infinite() ;
  state = UP ;
  status.pid = pid ;
  tain_copynow(&status.stamp) ;
  announce() ;
  ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ;
}
Exemplo n.º 2
0
static void panicnosp (char const *errmsg)
{
  char const *eargv[2] = { CRASH_PROG, 0 } ;
  strerr_warnwu1sys(errmsg) ;
  strerr_warnw2x("executing into ", eargv[0]) ;
  execve(eargv[0], (char *const *)eargv, (char *const *)environ) ;
 /* and if that execve fails, screw it and just die */
  strerr_dieexec(111, eargv[0]) ;
}
Exemplo n.º 3
0
static void scan (void)
{
  unsigned int i = 0 ;
  DIR *dir ;
  if (!wantscan) return ;
  wantscan = 0 ;
  dir = opendir(".") ;
  if (!dir)
  {
    strerr_warnwu1sys("opendir .") ;
    retrydirlater() ;
    return ;
  }
  for (; i < n ; i++) services[i].flagactive = 0 ;
  for (;;)
  {
    direntry *d ;
    errno = 0 ;
    d = readdir(dir) ;
    if (!d) break ;
    check(d->d_name) ;
  }
  if (errno)
  {
    strerr_warnwu1sys("readdir .") ;
    retrydirlater() ;
  }
  dir_close(dir) ;
  for (i = 0 ; i < n ; i++) if (!services[i].flagactive && !services[i].pid[0])
  {
    if (services[i].flaglog)
    {
      if (services[i].pid[1]) continue ;
      if (services[i].p[0] >= 0)
      {
        fd_close(services[i].p[1]) ; services[i].p[1] = -1 ;
        fd_close(services[i].p[0]) ; services[i].p[0] = -1 ;
      }
    }
    services[i] = services[--n] ;
  }
}
Exemplo n.º 4
0
static void uplastup_z (int islast)
{
  status.wstat = status.pid ;
  status.pid = 0 ;
  tain_copynow(&status.stamp) ;
  tryfinish(islast) ;
  announce() ;
  ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "d", 1) ;
  if (unlink(S6_SUPERVISE_READY_FILENAME) < 0 && errno != ENOENT)
    strerr_warnwu1sys("unlink " S6_SUPERVISE_READY_FILENAME) ;
  settimeout(5) ;
}
Exemplo n.º 5
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] ;
  }
}
static int doit (char const *s, unsigned int len)
{
  if (delimlen)
  {
    if (!len--)
    {
      switch (strictness)
      {
        case 1 :
        case 2 :
          strerr_warnw1x("empty line") ;
          break ;
        case 3 :
          buffer_flush(buffer_1) ;
          strerr_dief1x(100, "empty line") ;
        default : break ;
      }
      return 1 ;
    }
    if (byte_chr(delim, delimlen, *s) >= delimlen)
    {
      switch (strictness)
      {
        case 0 : return 0 ;
        case 1 :
        {
          strerr_warnw1x("invalid starting quote character") ;
          return 0 ;
        }
        case 2 :
        {
          char fmt[40] ;
          unsigned int n = len < 39 ? len+1 : 36 ;
          byte_copy(fmt, n, s) ;
          if (len >= 39)
          {
            byte_copy(fmt+n, 3, "...") ;
            n += 3 ;
          }
          fmt[n] = 0 ;
          strerr_warnw3x("invalid starting quote character", " in line: ", fmt) ;
          return 0 ;
        }
        case 3 :
        {
          buffer_flush(buffer_1) ;
          strerr_dief1x(100, "invalid starting quote character") ;
        }
        default : strerr_dief1x(101, "can't happen: unknown strictness") ;
      }
    }
  }
  {
    unsigned int r, w ;
    char d[len] ;
    if (!string_unquote_withdelim(d, &w, s + !!delimlen, len, &r, delim, delimlen))
    {
      switch (strictness)
      {
        case 0 : return 0 ;
        case 1 :
        {
          strerr_warnwu1sys("unquote") ;
          return 0 ;
        }
        case 2 :
        {
          char fmt[40] ;
          unsigned int n = (len + !!delimlen) < 40 ? (len + !!delimlen) : 36 ;
          byte_copy(fmt, n, s) ;
          if ((len + !!delimlen) >= 40)
          {
            byte_copy(fmt+n, 3, "...") ;
            n += 3 ;
          }
          fmt[n] = 0 ;
          strerr_warnwu3sys("unquote", " line: ", fmt) ;
          return 0 ;
        }
        case 3 :
        {
          int e = errno ;
          buffer_flush(buffer_1) ;
          errno = e ;
          strerr_diefu1sys(100, "unquote") ;
        }
        default : strerr_dief1x(101, "can't happen: unknown strictness") ;
      }
    }
    if (delimlen)
    {
      if (r == len)
      {
        switch (strictness)
        {
          case 0 : return 0 ;
          case 1 :
          {
            strerr_warnwu2x("unquote", ": no ending quote character") ;
            return 0 ;
          }
          case 2 :
          {
            char fmt[40] ;
            unsigned int n = len < 40 ? len : 36 ;
            byte_copy(fmt, n, s) ;
            if (len >= 40)
            {
              byte_copy(fmt+n, 3, "...") ;
              n += 3 ;
            }
            fmt[n] = 0 ;
            strerr_warnwu5x("unquote", ": no ending quote character", " in ", "line: ", fmt) ;
            return 0 ;
          }
          case 3 :
          {
            int e = errno ;
            buffer_flush(buffer_1) ;
            errno = e ;
            strerr_diefu2x(100, "unquote", ": no ending quote character") ;
          }
          default : strerr_dief1x(101, "can't happen: unknown strictness") ;
        }
      }
      else if ((r < len-1) && (strictness >= 2))
      {
        char fmtnum[UINT_FMT] ;
        char fmtden[UINT_FMT] ;
        char fmt[40] ;
        unsigned int n = len < 39 ? len+1 : 36 ;
        byte_copy(fmt, n, s) ;
        if (len >= 39)
        {
          byte_copy(fmt+n, 3, "...") ;
          n += 3 ;
        }
        fmt[n] = 0 ;
        fmtnum[uint_fmt(fmtnum, r+1)] = 0 ;
        fmtden[uint_fmt(fmtden, len)] = 0 ;
        strerr_warnw7x("found ending quote character at position ", fmtnum, "/", fmtden, ", ignoring remainder of ", "line: ", fmt) ;
      }
    }
    if (buffer_putalign(buffer_1, d, w) < (int)w)
      strerr_diefu1sys(111, "write to stdout") ;
  }
  return 1 ;
}
Exemplo n.º 7
0
static inline void announce (void)
{
  if (!s6_svstatus_write(".", &status))
    strerr_warnwu1sys("write status file") ;
}