/* oneit.c - tiny init replacement to launch a single child process.
 *
 * Copyright 2005, 2007 by Rob Landley <rob@landley.net>.

USE_ONEIT(NEWTOY(oneit, "^<1nc:p3[!pn]", TOYFLAG_SBIN))

config ONEIT
  bool "oneit"
  default y
  help
    usage: oneit [-p] [-c /dev/tty0] command [...]

    Simple init program that runs a single supplied command line with a
    controlling tty (so CTRL-C can kill it).

    -c	Which console device to use (/dev/console doesn't do CTRL-C, etc)
    -p	Power off instead of rebooting when command exits
    -r	Restart child when it exits
    -3	Write 32 bit PID of each exiting reparented process to fd 3 of child
    	(Blocking writes, child must read to avoid eventual deadlock.)

    Spawns a single child process (because PID 1 has signals blocked)
    in its own session, reaps zombies until the child exits, then
    reboots the system (or powers off with -p, or restarts the child with -r).

    Responds to SIGUSR1 by halting the system, SIGUSR2 by powering off,
    and SIGTERM or SIGINT reboot.
*/

#define FOR_oneit
#include "toys.h"
#include <sys/reboot.h>

GLOBALS(
  char *console;
)

// The minimum amount of work necessary to get ctrl-c and such to work is:
//
// - Fork a child (PID 1 is special: can't exit, has various signals blocked).
// - Do a setsid() (so we have our own session).
// - In the child, attach stdio to /dev/tty0 (/dev/console is special)
// - Exec the rest of the command line.
//
// PID 1 then reaps zombies until the child process it spawned exits, at which
// point it calls sync() and reboot().  I could stick a kill -1 in there.

// Perform actions in response to signals. (Only root can send us signals.)
static void oneit_signaled(int signal)
{
  int action = RB_AUTOBOOT;

  toys.signal = signal;
  if (signal == SIGUSR1) action = RB_HALT_SYSTEM;
  if (signal == SIGUSR2) action = RB_POWER_OFF;

  // PID 1 can't call reboot() because it kills the task that calls it,
  // which causes the kernel to panic before the actual reboot happens.
  sync();
  if (!vfork()) reboot(action);
}

void oneit_main(void)
{
  int i, pid, pipes[] = {SIGUSR1, SIGUSR2, SIGTERM, SIGINT};

  // Setup signal handlers for signals of interest
  for (i = 0; i<ARRAY_LEN(pipes); i++) xsignal(pipes[i], oneit_signaled);

  if (toys.optflags & FLAG_3) {
    // Ensure next available filehandles are #3 and #4
    while (xopen_stdio("/", 0) < 3);
    close(3);
    close(4);
    xpipe(pipes);
    fcntl(4, F_SETFD, FD_CLOEXEC);
  }

  while (!toys.signal) {

    // Create a new child process.
    pid = XVFORK();
    if (pid) {

      // pid 1 reaps zombies until it gets its child, then halts system.
      // We ignore the return value of write (what would we do with it?)
      // but save it in a variable we never read to make fortify shut up.
      // (Real problem is if pid2 never reads, write() fills pipe and blocks.)
      while (pid != wait(&i)) if (toys.optflags & FLAG_3) i = write(4, &pid, 4);
      if (toys.optflags & FLAG_n) continue;

      oneit_signaled((toys.optflags & FLAG_p) ? SIGUSR2 : SIGTERM);
    } else {
      // Redirect stdio to /dev/tty0, with new session ID, so ctrl-c works.
      setsid();
      for (i=0; i<3; i++) {
        close(i);
        // Remember, O_CLOEXEC is backwards for xopen()
        xopen_stdio(TT.console ? TT.console : "/dev/tty0", O_RDWR|O_CLOEXEC);
      }

      // Can't xexec() here, we vforked so we don't want to error_exit().
      toy_exec(toys.optargs);
      execvp(*toys.optargs, toys.optargs);
      perror_msg("%s not in PATH=%s", *toys.optargs, getenv("PATH"));

      break;
    }
  }

  // Give reboot() time to kick in, or avoid rapid spinning if exec failed
  sleep(5);
  _exit(127);
}
