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  // setsid() fails if we're already session leader, ala "exec setsid" from sh.
  28  // Second call can't fail, so loop won't continue endlessly.
  29  while (setsid()<0) {
  30    pid_t pid;
  31
  32    // This must be before vfork() or tcsetpgrp() will hang waiting for parent.
  33    setpgid(0, 0);
  34
  35    pid = XVFORK();
  36    if (pid) {
  37      i = 0;
  38      if (FLAG(w)) {
  39        i = 127;
  40        if (pid>0) i = xwaitpid(pid);
  41      }
  42      _exit(i);
  43    }
  44  }
  45
  46  if (FLAG(c)) tcsetpgrp(0, getpid());
  47  if (FLAG(d) && (i = open("/dev/tty", O_RDONLY)) != -1) {
  48    ioctl(i, TIOCNOTTY);
  49    close(i);
  50  }
  51  xexec(toys.optargs);
  52}
  53