예제 #1
0
int main (int argc, char const *const *argv)
{
  PROG = "s6-rename" ;
  if (argc < 3) strerr_dieusage(100, USAGE) ;
  if (rename(argv[1], argv[2]) == -1)
    strerr_diefu4sys(111, "rename ", argv[1], " to ", argv[2]) ;
  return 0 ;
}
예제 #2
0
int main (int argc, char const *const *argv, char const *const *envp)
{
  int fd, fd2 ;
  unsigned int flags = 0 ;
  int what = -1 ;
  int changemode = 0 ;
  PROG = "redirfd" ;
  {
    subgetopt_t l = SUBGETOPT_ZERO ;
    for (;;)
    {
      register int opt = subgetopt_r(argc, argv, "rwuacxnb", &l) ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 'r' : what = O_RDONLY ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'w' : what = O_WRONLY ; flags |= O_CREAT|O_TRUNC ; flags &= ~(O_APPEND|O_EXCL) ; break ;
        case 'u' : what = O_RDWR ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'a' : what = O_WRONLY ; flags |= O_CREAT|O_APPEND ; flags &= ~(O_TRUNC|O_EXCL) ; break ;
        case 'c' : what = O_WRONLY ; flags |= O_APPEND ; flags &= ~(O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'x' : what = O_WRONLY ; flags |= O_CREAT|O_EXCL ; flags &= ~(O_APPEND|O_TRUNC) ; break ;
        case 'n' : flags |= O_NONBLOCK ; break ;
        case 'b' : changemode = 1 ; break ;
        default : dieusage() ;
      }
    }
    argc -= l.ind ; argv += l.ind ;
  }
  if ((argc < 3) || (what == -1)) dieusage() ;
  if (!uint0_scan(argv[0], (unsigned int *)&fd)) dieusage() ;
  flags |= what ;
  fd2 = open3(argv[1], flags, 0666) ;
  if ((fd2 == -1) && (what == O_WRONLY) && (errno == ENXIO))
  {
    register int e ;
    int fdr = open_read(argv[1]) ;
    if (fdr == -1) strerr_diefu2sys(111, "open_read ", argv[1]) ;
    fd2 = open3(argv[1], flags, 0666) ;
    e = errno ;
    fd_close(fdr) ;
    errno = e ;
  }
  if (fd2 == -1) strerr_diefu2sys(111, "open ", argv[1]) ;
  if (fd_move(fd, fd2) == -1)
  {
    char fmt[UINT_FMT] ;
    fmt[uint_fmt(fmt, fd2)] = 0 ;
    strerr_diefu4sys(111, "move fd ", fmt, " to fd ", argv[0]) ;
  }
  if (changemode)
  {
    if (((flags & O_NONBLOCK) ? ndelay_off(fd) : ndelay_on(fd)) < 0)
      strerr_diefu1sys(111, "change blocking mode") ;
  }
  pathexec_run(argv[2], argv+2, envp) ;
  strerr_dieexec(111, argv[2]) ;
}
예제 #3
0
파일: s6-ftrig-wait.c 프로젝트: 8l/s6
int main (int argc, char const *const *argv)
{
  tain_t deadline, tto ;
  ftrigr_t a = FTRIGR_ZERO ;
  uint16 id ;
  char pack[2] = " \n" ;
  PROG = "s6-ftrig-wait" ;
  {
    unsigned int t = 0 ;
    for (;;)
    {
      register int opt = subgetopt(argc, argv, "t:") ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
        default : strerr_dieusage(100, USAGE) ;
      }
    }
    if (t) tain_from_millisecs(&tto, t) ;
    else tto = tain_infinite_relative ;
    argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
  }
  if (argc < 2) strerr_dieusage(100, USAGE) ;

  tain_now_g() ;
  tain_add_g(&deadline, &tto) ;

  if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ;
  id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ;
  if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;
  if (ftrigr_wait_or_g(&a, &id, 1, &deadline, &pack[0]) == -1)
    strerr_diefu2sys((errno == ETIMEDOUT) ? 1 : 111, "match regexp on ", argv[1]) ;
  if (allwrite(1, pack, 2) < 2) strerr_diefu1sys(111, "write to stdout") ;
  return 0 ;
}
예제 #4
0
파일: s6-rc-init.c 프로젝트: skarnet/s6-rc
int main (int argc, char const *const *argv)
{
  tain_t deadline, tto ;
  unsigned int dirlen ;
  char const *live = S6RC_LIVE_BASE ;
  char const *compiled = S6RC_COMPILED_BASE ;
  PROG = "s6-rc-init" ;
  {
    unsigned int t = 0 ;
    subgetopt_t l = SUBGETOPT_ZERO ;
    for (;;)
    {
      register int opt = subgetopt_r(argc, argv, "c:l:t:", &l) ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 'c' : compiled = l.arg ; break ;
        case 'l' : live = l.arg ; break ;
        case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
        default : dieusage() ;
      }
    }
    argc -= l.ind ; argv += l.ind ;
    if (t) tain_from_millisecs(&tto, t) ;
    else tto = tain_infinite_relative ;
  }
  if (!argc) dieusage() ;

  if (compiled[0] != '/')
    strerr_dief2x(100, compiled, " is not an absolute path") ;
  if (live[0] != '/')
    strerr_dief2x(100, live, " is not an absolute path") ;
  if (argv[0][0] != '/')
    strerr_dief2x(100, argv[0], " is not an absolute path") ;

  tain_now_g() ;
  tain_add_g(&deadline, &tto) ;

  if (!s6rc_sanitize_dir(&satmp, live, &dirlen)) dienomem() ;
  llen = satmp.len ;
  if (!stralloc_cats(&satmp, ":initial") || !stralloc_0(&satmp))
    strerr_diefu1sys(111, "stralloc_catb") ;

  {
    int fdlock ;
    int fdcompiled ;
    int ok ;
    s6rc_db_t db ;
    unsigned int n ;
    char lfn[llen + 13] ;
    char cfn[llen + 23] ;


   /* Create the real dir, lock it, symlink */

    unlink(live) ;
    rm_rf(satmp.s) ;
    if (mkdir(satmp.s, 0755) < 0) strerr_diefu2sys(111, "mkdir ", satmp.s) ;
    if (!s6rc_lock(satmp.s, 2, &fdlock, 0, 0, 0))
    {
      char tmp[satmp.len] ;
      byte_copy(tmp, satmp.len, satmp.s) ;
      cleanup() ;
      strerr_diefu2sys(111, "take lock on ", tmp) ;
    }
    byte_copy(lfn, llen, satmp.s) ;
    lfn[llen] = 0 ;
    if (symlink(satmp.s + dirlen, lfn) < 0)
    {
      char tmp[satmp.len - dirlen] ;
      byte_copy(tmp, satmp.len - dirlen, satmp.s + dirlen) ;
      cleanup() ;
      strerr_diefu4sys(111, "symlink ", tmp, " to ", lfn) ;
    }
    

   /* compiled */

    fdcompiled = open_readb(compiled) ;
    if (fdcompiled < 0)
    {
      cleanup() ;
      strerr_diefu2sys(111, "open ", compiled) ;
    }
    byte_copy(lfn + llen, 10, "/compiled") ;
    if (symlink(compiled, lfn) < 0)
    {
      cleanup() ;
      strerr_diefu4sys(111, "symlink ", compiled, " to ", lfn) ;
    }


   /* scandir */

    byte_copy(lfn + llen + 1, 8, "scandir") ;
    if (symlink(argv[0], lfn) < 0)
    {
      cleanup() ;
      strerr_diefu4sys(111, "symlink ", argv[0], " to ", lfn) ;
    }


   /* state */

    byte_copy(lfn + llen + 1, 6, "state") ;
    {
      register int r = s6rc_db_read_sizes(fdcompiled, &db) ;
      if (r <= 0)
      {
        cleanup() ;
        if (r < 0) strerr_diefu2sys(111, "read database size in ", compiled) ;
        else strerr_dief2x(4, "invalid database size in ", compiled) ;
      }
      close(fdcompiled) ;
      n = db.nshort + db.nlong ;
      {
        char zero[n] ;
        byte_zero(zero, n) ;
        if (!openwritenclose_unsafe(lfn, zero, n))
        {
          cleanup() ;
          strerr_diefu2sys(111, "write ", lfn) ;
        }
      }
    }


   /* servicedirs */

    byte_copy(lfn + llen + 1, 12, "servicedirs") ;
    byte_copy(cfn, llen + 1, lfn) ;
    byte_copy(cfn + llen + 1, 21, "compiled/servicedirs") ;
    if (!hiercopy(cfn, lfn))
    {
      cleanup() ;
      strerr_diefu4sys(111, "recursively copy ", cfn, " to ", lfn) ;
    }


   /* start the supervisors */

    lfn[llen] = 0 ;
    ok = s6rc_servicedir_manage_g(lfn, &deadline) ;
    if (!ok)
    {
      cleanup() ;
      strerr_diefu3sys(111, "supervise service directories in ", lfn, "/servicedirs") ;
    }
    if (ok & 2)
      strerr_warnw3x("s6-svscan not running on ", lfn, "/scandir") ;
  }  
  return 0 ;
}
예제 #5
0
파일: s6-ftrig-listen.c 프로젝트: 8l/s6
int main (int argc, char const **argv, char const *const *envp)
{
  iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ;
  tain_t deadline, tto ;
  ftrigr_t a = FTRIGR_ZERO ;
  int argc1 ;
  unsigned int i = 0 ;
  char or = 0 ;
  PROG = "s6-ftrig-listen" ;
  {
    unsigned int t = 0 ;
    for (;;)
    {
      register int opt = subgetopt(argc, argv, "aot:") ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 'a' : or = 0 ; break ;
        case 'o' : or = 1 ; break ;
        case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
        default : dieusage() ;
      }
    }
    if (t) tain_from_millisecs(&tto, t) ; else tto = tain_infinite_relative ;
    argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
  }
  if (argc < 4) dieusage() ;
  argc1 = el_semicolon(argv) ;
  if (!argc1 || (argc1 & 1) || (argc == argc1 + 1)) dieusage() ;
  if (argc1 >= argc) strerr_dief1x(100, "unterminated fifodir+regex block") ;
  tain_now_g() ;
  tain_add_g(&deadline, &tto) ;
  x[0].fd = selfpipe_init() ;
  if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
  if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
  if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ;

  if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ;
  x[1].fd = ftrigr_fd(&a) ;

  {
    int pid = 0 ;
    unsigned int idlen = argc1 >> 1 ;
    uint16 ids[idlen] ;
    for (; i < idlen ; i++)
    {
      ids[i] = ftrigr_subscribe_g(&a, argv[i<<1], argv[(i<<1)+1], 0, &deadline) ;
      if (!ids[i]) strerr_diefu4sys(111, "subscribe to ", argv[i<<1], " with regexp ", argv[(i<<1)+1]) ;
    }

    pid = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ;
    if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;

    for (;;)
    {
      register int r ;
      i = 0 ;
      while (i < idlen)
      {
        char dummy ;
        r = ftrigr_check(&a, ids[i], &dummy) ;
        if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
        else if (!r) i++ ;
        else if (or) idlen = 0 ;
        else ids[i] = ids[--idlen] ;
      }
      if (!idlen) break ;
      r = iopause_g(x, 2, &deadline) ;
      if (r < 0) strerr_diefu1sys(111, "iopause") ;
      else if (!r)
      {
        errno = ETIMEDOUT ;
        strerr_diefu1sys(1, "get expected event") ;
      }
      if (x[0].revents & IOPAUSE_READ) handle_signals() ;
      if (x[1].revents & IOPAUSE_READ)
      {
        if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
      }
    }
  }
  return 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 ;
}
int main (int argc, char const *const *argv, char const *const *envp)
{
  iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ;
  struct taia deadline, tto ;
  ftrigr_t a = FTRIGR_ZERO ;
  int pid ;
  uint16 id ;
  PROG = "s6-ftrig-listen1" ;
  {
    unsigned int t = 0 ;
    for (;;)
    {
      register int opt = subgetopt(argc, argv, "t:") ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ;
        default : strerr_dieusage(100, USAGE) ;
      }
    }
    if (t) taia_from_millisecs(&tto, t) ;
    else tto = infinitetto ;
    argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
  }
  if (argc < 3) strerr_dieusage(100, USAGE) ;

  taia_now_g() ;
  taia_add_g(&deadline, &tto) ;

  if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ;
  id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ;
  if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ;

  x[0].fd = selfpipe_init() ;
  if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
  if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ;
  if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ;
  x[1].fd = ftrigr_fd(&a) ;

  pid = fork() ;
  switch (pid)
  {
    case -1 : strerr_diefu1sys(111, "fork") ;
    case 0  :
    {
      PROG = "s6-ftrig-listen1 (child)" ;
      pathexec_run(argv[2], argv+2, envp) ;
      strerr_dieexec(111, argv[2]) ;
    }
  }

  for (;;)
  {
    char dummy ;
    register int r = ftrigr_check(&a, id, &dummy) ;
    if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;
    if (r) break ;
    r = iopause_g(x, 2, &deadline) ;
    if (r < 0) strerr_diefu1sys(111, "iopause") ;
    else if (!r)
    {
      errno = ETIMEDOUT ;
      strerr_diefu1sys(1, "get expected event") ;
    }
    if (x[0].revents & IOPAUSE_READ) handle_signals() ;
    if (x[1].revents & IOPAUSE_READ)
    {
      if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ;
    }
  }

  return 0 ;
}