toybox/toys/other/setsid.c
<<
>>
Prefs
   1/* setsid.c - Run program in a new session ID.
   2 *
   3 * Copyright 2006 Rob Landley <rob@landley.net>
   4
   5USE_SETSID(NEWTOY(setsid, "^<1wcd[!dc]", TOYFLAG_USR|TOYFLAG_BIN))
   6
   7config SETSID
   8  bool "setsid"
   9  default y
  10  help
  11    usage: setsid [-cdw] command [args...]
  12
  13    Run process in a new session.
  14
  15    -d  Detach from tty
  16    -c  Control tty (become foreground process & receive keyboard signals)
  17    -w  Wait for child (and exit with its status)
  18*/
  19
  20#define FOR_setsid
  21#include "toys.h"
  22
  23void setsid_main(void)
  24{
  25  int i;
  26
  27  // This must be before vfork() or tcsetpgrp() will hang waiting for parent.
  28  setpgid(0, 0);
  29
  30  // setsid() fails if we're already session leader, ala "exec setsid" from sh.
  31  // Second call can't fail, so loop won't continue endlessly.
  32  while (setsid()<0) {
  33    pid_t pid = XVFORK();
  34
  35    if (pid) {
  36      i = 0;
  37      if (FLAG(w)) {
  38        i = 127;
  39        if (pid>0) i = xwaitpid(pid);
  40      }
  41      _exit(i);
  42    }
  43  }
  44
  45  if (FLAG(c)) tcsetpgrp(0, getpid());
  46  if (FLAG(d) && (i = open("/dev/tty", O_RDONLY)) != -1) {
  47    ioctl(i, TIOCNOTTY);
  48    close(i);
  49  }
  50  xexec(toys.optargs);
  51}
  52