nohup.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. //applet:IF_NOHUP(APPLET_NOEXEC(nohup, nohup, BB_DIR_USR_BIN, BB_SUID_DROP, nohup))
  19. //kbuild:lib-$(CONFIG_NOHUP) += nohup.o
  20. //usage:#define nohup_trivial_usage
  21. //usage: "PROG ARGS"
  22. //usage:#define nohup_full_usage "\n\n"
  23. //usage: "Run PROG immune to hangups, with output to a non-tty"
  24. //usage:
  25. //usage:#define nohup_example_usage
  26. //usage: "$ nohup make &"
  27. #include "libbb.h"
  28. /* Compat info: nohup (GNU coreutils 6.8) does this:
  29. # nohup true
  30. nohup: ignoring input and appending output to 'nohup.out'
  31. # nohup true 1>/dev/null
  32. nohup: ignoring input and redirecting stderr to stdout
  33. # nohup true 2>zz
  34. # cat zz
  35. nohup: ignoring input and appending output to 'nohup.out'
  36. # nohup true 2>zz 1>/dev/null
  37. # cat zz
  38. nohup: ignoring input
  39. # nohup true </dev/null 1>/dev/null
  40. nohup: redirecting stderr to stdout
  41. # nohup true </dev/null 2>zz 1>/dev/null
  42. # cat zz
  43. (nothing)
  44. #
  45. */
  46. int nohup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  47. int nohup_main(int argc UNUSED_PARAM, char **argv)
  48. {
  49. const char *nohupout;
  50. char *home;
  51. xfunc_error_retval = 127;
  52. if (!argv[1]) {
  53. bb_show_usage();
  54. }
  55. /* If stdin is a tty, detach from it. */
  56. if (isatty(STDIN_FILENO)) {
  57. /* bb_error_msg("ignoring input"); */
  58. close(STDIN_FILENO);
  59. xopen(bb_dev_null, O_RDONLY); /* will be fd 0 (STDIN_FILENO) */
  60. }
  61. nohupout = "nohup.out";
  62. /* Redirect stdout to nohup.out, either in "." or in "$HOME". */
  63. if (isatty(STDOUT_FILENO)) {
  64. close(STDOUT_FILENO);
  65. if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) {
  66. home = getenv("HOME");
  67. if (home) {
  68. nohupout = concat_path_file(home, nohupout);
  69. xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);
  70. } else {
  71. xopen(bb_dev_null, O_RDONLY); /* will be fd 1 */
  72. }
  73. }
  74. bb_error_msg("appending output to %s", nohupout);
  75. }
  76. /* If we have a tty on stderr, redirect to stdout. */
  77. if (isatty(STDERR_FILENO)) {
  78. /* if (stdout_wasnt_a_tty)
  79. bb_error_msg("redirecting stderr to stdout"); */
  80. dup2(STDOUT_FILENO, STDERR_FILENO);
  81. }
  82. signal(SIGHUP, SIG_IGN);
  83. argv++;
  84. BB_EXECVP_or_die(argv);
  85. }