busybox/coreutils/nohup.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * nohup - invoke a utility immune to hangups.
   4 *
   5 * Busybox version based on nohup specification at
   6 * http://www.opengroup.org/onlinepubs/007904975/utilities/nohup.html
   7 *
   8 * Copyright 2006 Rob Landley <rob@landley.net>
   9 * Copyright 2006 Bernhard Reutner-Fischer
  10 *
  11 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  12 */
  13//config:config NOHUP
  14//config:       bool "nohup (2 kb)"
  15//config:       default y
  16//config:       help
  17//config:       run a command immune to hangups, with output to a non-tty.
  18
  19//applet:IF_NOHUP(APPLET_NOEXEC(nohup, nohup, BB_DIR_USR_BIN, BB_SUID_DROP, nohup))
  20
  21//kbuild:lib-$(CONFIG_NOHUP) += nohup.o
  22
  23//usage:#define nohup_trivial_usage
  24//usage:       "PROG ARGS"
  25//usage:#define nohup_full_usage "\n\n"
  26//usage:       "Run PROG immune to hangups, with output to a non-tty"
  27//usage:
  28//usage:#define nohup_example_usage
  29//usage:       "$ nohup make &"
  30
  31#include "libbb.h"
  32
  33/* Compat info: nohup (GNU coreutils 6.8) does this:
  34# nohup true
  35nohup: ignoring input and appending output to 'nohup.out'
  36# nohup true 1>/dev/null
  37nohup: ignoring input and redirecting stderr to stdout
  38# nohup true 2>zz
  39# cat zz
  40nohup: ignoring input and appending output to 'nohup.out'
  41# nohup true 2>zz 1>/dev/null
  42# cat zz
  43nohup: ignoring input
  44# nohup true </dev/null 1>/dev/null
  45nohup: redirecting stderr to stdout
  46# nohup true </dev/null 2>zz 1>/dev/null
  47# cat zz
  48  (nothing)
  49#
  50*/
  51
  52int nohup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  53int nohup_main(int argc UNUSED_PARAM, char **argv)
  54{
  55        const char *nohupout;
  56        char *home;
  57
  58        xfunc_error_retval = 127;
  59
  60        if (!argv[1]) {
  61                bb_show_usage();
  62        }
  63
  64        /* If stdin is a tty, detach from it. */
  65        if (isatty(STDIN_FILENO)) {
  66                /* bb_error_msg("ignoring input"); */
  67                close(STDIN_FILENO);
  68                xopen(bb_dev_null, O_RDONLY); /* will be fd 0 (STDIN_FILENO) */
  69        }
  70
  71        nohupout = "nohup.out";
  72        /* Redirect stdout to nohup.out, either in "." or in "$HOME". */
  73        if (isatty(STDOUT_FILENO)) {
  74                close(STDOUT_FILENO);
  75                if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) {
  76                        home = getenv("HOME");
  77                        if (home) {
  78                                nohupout = concat_path_file(home, nohupout);
  79                                xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
  80                        } else {
  81                                xopen(bb_dev_null, O_RDONLY); /* will be fd 1 */
  82                        }
  83                }
  84                bb_error_msg("appending output to %s", nohupout);
  85        }
  86
  87        /* If we have a tty on stderr, redirect to stdout. */
  88        if (isatty(STDERR_FILENO)) {
  89                /* if (stdout_wasnt_a_tty)
  90                        bb_error_msg("redirecting stderr to stdout"); */
  91                dup2(STDOUT_FILENO, STDERR_FILENO);
  92        }
  93
  94        signal(SIGHUP, SIG_IGN);
  95
  96        argv++;
  97        BB_EXECVP_or_die(argv);
  98}
  99