bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

nohup changes in response to Open Group XCU ERN 71


From: Paul Eggert
Subject: nohup changes in response to Open Group XCU ERN 71
Date: Thu, 23 Mar 2006 15:57:36 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

I installed this.  It makes 'nohup' conform to the draft resolution of
Open Group XCU ERN 71
<http://www.opengroup.org/austin/aardvark/latest/xcubug2.txt>, which
makes coreutils nohup's behavior more compatible with the rest of the
Unix world.

On the other hand the situation is now complicated enough that I felt
it wise to have nohup issue a more-informative diagnostic when it
redirects I/O, which makes the wording of nohup's diagnostics less
compatible with traditional Unix.

2006-03-23  Paul Eggert  <address@hidden>

        * NEWS: nohup diagnostics are now more precise, and nohup now
        redirects stderr to nohup.out if stdout is closed and stderr is a tty.
        * doc/coreutils.texi (nohup invocation): nohup now redirects stderr to
        nohup.out if stdout is closed and stderr is a tty.
        * src/nohup.c (main): Implement this.
        * tests/misc/nohup: Test the new behavior.

Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.364
diff -p -u -r1.364 NEWS
--- NEWS        10 Mar 2006 21:44:30 -0000      1.364
+++ NEWS        23 Mar 2006 23:33:50 -0000
@@ -26,12 +26,18 @@ GNU coreutils NEWS                      
   if your locale settings appear to be messed up.  This change
   attempts to have the default be the best of both worlds.
 
-  rm --interactive now takes an optional argument, although the
-  default of using no argument still acts like -i.
-
   mkfifo and mknod no longer set special mode bits (setuid, setgid,
   and sticky) with the -m option.
 
+  nohup's usual diagnostic now more precisely specifies the I/O
+  redirections, e.g., "ignoring input and appending output to
+  nohup.out".  Also, nohup now redirects stderr to nohup.out (or
+  $HOME/nohup.out) if stdout is closed and stderr is a tty; this is in
+  response to Open Group XCU ERN 71.
+
+  rm --interactive now takes an optional argument, although the
+  default of using no argument still acts like -i.
+
   sort now reports incompatible options (e.g., -i and -n) rather than
   silently ignoring one of them.
 
Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.316
diff -p -u -r1.316 coreutils.texi
--- doc/coreutils.texi  6 Mar 2006 07:21:40 -0000       1.316
+++ doc/coreutils.texi  23 Mar 2006 23:33:52 -0000
@@ -12936,8 +12936,11 @@ Any @file{nohup.out} or @file{$HOME/nohu
 @command{nohup} is made readable and writable only to the user,
 regardless of the current umask settings.
 
-If standard error is a terminal, it is redirected to the same file
+If standard error is a terminal, it is normally redirected to the same file
 descriptor as the (possibly-redirected) standard output.
+However, if standard output is closed, standard error terminal output
+is instead appended to the file @file{nohup.out} or
address@hidden/nohup.out} as above.
 
 @command{nohup} does not automatically put the command it runs in the
 background; you must do that explicitly, by ending the command line
Index: src/nohup.c
===================================================================
RCS file: /fetish/cu/src/nohup.c,v
retrieving revision 1.33
retrieving revision 1.35
diff -p -u -r1.33 -r1.35
--- src/nohup.c 12 Aug 2005 08:25:52 -0000      1.33
+++ src/nohup.c 23 Mar 2006 23:56:34 -0000      1.35
@@ -75,7 +75,12 @@ Run COMMAND, ignoring hangup signals.\n\
 int
 main (int argc, char **argv)
 {
+  int out_fd = STDOUT_FILENO;
   int saved_stderr_fd = STDERR_FILENO;
+  bool ignoring_input;
+  bool redirecting_stdout;
+  bool stdout_is_closed;
+  bool redirecting_stderr;
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
@@ -97,33 +102,48 @@ main (int argc, char **argv)
       usage (NOHUP_FAILURE);
     }
 
-  /* If standard input is a tty, replace it with /dev/null.
+  ignoring_input = isatty (STDIN_FILENO);
+  redirecting_stdout = isatty (STDOUT_FILENO);
+  stdout_is_closed = (!redirecting_stdout && errno == EBADF);
+  redirecting_stderr = isatty (STDERR_FILENO);
+
+  /* If standard input is a tty, replace it with /dev/null if possible.
      Note that it is deliberately opened for *writing*,
      to ensure any read evokes an error.  */
-  if (isatty (STDIN_FILENO))
-    fd_reopen (STDIN_FILENO, "/dev/null", O_WRONLY, 0);
+  if (ignoring_input)
+    {
+      fd_reopen (STDIN_FILENO, "/dev/null", O_WRONLY, 0);
+      if (!redirecting_stdout && !redirecting_stderr)
+       error (0, 0, _("ignoring input"));
+    }
 
   /* If standard output is a tty, redirect it (appending) to a file.
-     First try nohup.out, then $HOME/nohup.out.  */
-  if (isatty (STDOUT_FILENO))
+     First try nohup.out, then $HOME/nohup.out.  If standard error is
+     a tty and standard output is closed, open nohup.out or
+     $HOME/nohup.out without redirecting anything.  */
+  if (redirecting_stdout || (redirecting_stderr && stdout_is_closed))
     {
       char *in_home = NULL;
       char const *file = "nohup.out";
       int flags = O_CREAT | O_WRONLY | O_APPEND;
       mode_t mode = S_IRUSR | S_IWUSR;
       mode_t umask_value = umask (~mode);
-      int fd = fd_reopen (STDOUT_FILENO, file, flags, mode);
+      out_fd = (redirecting_stdout
+               ? fd_reopen (STDOUT_FILENO, file, flags, mode)
+               : open (file, flags, mode));
 
-      if (fd < 0)
+      if (out_fd < 0)
        {
          int saved_errno = errno;
          char const *home = getenv ("HOME");
          if (home)
            {
              in_home = file_name_concat (home, file, NULL);
-             fd = fd_reopen (STDOUT_FILENO, in_home, flags, mode);
+             out_fd = (redirecting_stdout
+                       ? fd_reopen (STDOUT_FILENO, in_home, flags, mode)
+                       : open (in_home, flags, mode));
            }
-         if (fd < 0)
+         if (out_fd < 0)
            {
              int saved_errno2 = errno;
              error (0, saved_errno, _("failed to open %s"), quote (file));
@@ -136,12 +156,16 @@ main (int argc, char **argv)
        }
 
       umask (umask_value);
-      error (0, 0, _("appending output to %s"), quote (file));
+      error (0, 0,
+            _(ignoring_input
+              ? "ignoring input and appending output to %s"
+              : "appending output to %s"),
+            quote (file));
       free (in_home);
     }
 
-  /* If standard error is a tty, redirect it to stdout.  */
-  if (isatty (STDERR_FILENO))
+  /* If standard error is a tty, redirect it.  */
+  if (redirecting_stderr)
     {
       /* Save a copy of stderr before redirecting, so we can use the original
         if execve fails.  It's no big deal if this dup fails.  It might
@@ -154,13 +178,17 @@ main (int argc, char **argv)
        error (NOHUP_FAILURE, errno,
               _("failed to set the copy of stderr to close on exec"));
 
-      if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0)
-       {
-         if (errno != EBADF)
-           error (NOHUP_FAILURE, errno,
-                  _("failed to redirect standard error"));
-         close (STDERR_FILENO);
-       }
+      if (!redirecting_stdout)
+       error (0, 0,
+              _(ignoring_input
+                ? "ignoring input and redirecting stderr to stdout"
+                : "redirecting stderr to stdout"));
+
+      if (dup2 (out_fd, STDERR_FILENO) < 0)
+       error (NOHUP_FAILURE, errno, _("failed to redirect standard error"));
+
+      if (stdout_is_closed)
+       close (out_fd);
     }
 
   signal (SIGHUP, SIG_IGN);
Index: tests/misc/nohup
===================================================================
RCS file: /fetish/cu/tests/misc/nohup,v
retrieving revision 1.4
diff -p -u -r1.4 nohup
--- tests/misc/nohup    19 Dec 2003 16:13:28 -0000      1.4
+++ tests/misc/nohup    23 Mar 2006 23:33:52 -0000
@@ -28,20 +28,24 @@ fail=0
 nohup sh -c 'echo stdout; echo stderr 1>&2' 2>err || fail=1
 
 # Be careful.  The results of the above nohup command
-# change depending on whether stdout is redirected.
+# change depending on whether stdin and stdout are redirected.
 if test -t 1; then
   test "`cat nohup.out`" = stdout || fail=1
-  cat <<\EOF > exp || fail=1
-nohup: appending output to `nohup.out'
-stderr
-EOF
+  if test -t 0; then
+    echo 'nohup: ignoring input and appending output to `nohup.out'\'
+  else
+    echo 'nohup: appending output to `nohup.out'\'
+  fi >exp || fail=1
 else
   # Here it should not even exist.
   test -f nohup.out && fail=1
-  cat <<\EOF > exp || fail=1
-stderr
-EOF
+  if test -t 0; then
+    echo 'nohup: ignoring input' >exp
+  else
+    rm -f exp
+  fi || fail=1
 fi
+echo 'stderr' >> exp || fail=1
 
 cmp exp err || fail=1
 test $fail = 1 && diff exp err 2> /dev/null




reply via email to

[Prev in Thread] Current Thread [Next in Thread]