nohup.c 2.5 KB

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