diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2005-03-19 00:45:48 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2005-03-19 00:45:48 +0000 |
commit | c8f3dc402bbd153c1112a534bb6a7cd567bcccfa (patch) | |
tree | 8ceee99756fb83d7d5e93bbf2f42d743a5d7465e | |
parent | 319ebff684beef8b32009d193feb21d9df238fed (diff) | |
download | coreutils-c8f3dc402bbd153c1112a534bb6a7cd567bcccfa.tar.xz |
(main): nohup now ignores the umask when creating nohup.out.
nohup now closes stderr if it is a terminal and stdout is closed.
Be a little more paranoid about return values;
e.g., check for any negative return from open.
Assume free (NULL) works.
Close file descriptor leak when redirecting standard output to a file.
-rw-r--r-- | src/nohup.c | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/src/nohup.c b/src/nohup.c index e1a3d80b8..ea96aa9bd 100644 --- a/src/nohup.c +++ b/src/nohup.c @@ -1,5 +1,5 @@ /* nohup -- run a command immume to hangups, with output to a non-tty - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -72,9 +72,7 @@ Run COMMAND, ignoring hangup signals.\n\ int main (int argc, char **argv) { - int fd; - int saved_stderr_fd = -1; - bool stderr_isatty; + int saved_stderr_fd = STDERR_FILENO; initialize_main (&argc, &argv); program_name = argv[0]; @@ -104,9 +102,10 @@ main (int argc, char **argv) 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 = open (file, flags, mode); - fd = open (file, flags, mode); - if (fd == -1) + if (fd < 0) { int saved_errno = errno; char const *home = getenv ("HOME"); @@ -115,7 +114,7 @@ main (int argc, char **argv) in_home = path_concat (home, file, NULL); fd = open (in_home, flags, mode); } - if (fd == -1) + if (fd < 0) { int saved_errno2 = errno; error (0, saved_errno, _("failed to open %s"), quote (file)); @@ -127,21 +126,19 @@ main (int argc, char **argv) file = in_home; } + umask (umask_value); + /* Redirect standard output to the file. */ - if (dup2 (fd, STDOUT_FILENO) == -1) + if (fd != STDOUT_FILENO + && (dup2 (fd, STDOUT_FILENO) < 0 || close (fd) != 0)) error (NOHUP_FAILURE, errno, _("failed to redirect standard output")); error (0, 0, _("appending output to %s"), quote (file)); - if (in_home) - free (in_home); - } - else - { - fd = STDOUT_FILENO; + free (in_home); } /* If stderr is on a tty, redirect it to stdout. */ - if ((stderr_isatty = isatty (STDERR_FILENO))) + if (isatty (STDERR_FILENO)) { /* 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 @@ -149,13 +146,18 @@ main (int argc, char **argv) the post-failed-execve diagnostic. */ saved_stderr_fd = dup (STDERR_FILENO); - if (saved_stderr_fd != -1 + if (0 <= saved_stderr_fd && set_cloexec_flag (saved_stderr_fd, true) != 0) error (NOHUP_FAILURE, errno, _("failed to set the copy of stderr to close on exec")); - if (dup2 (fd, STDERR_FILENO) == -1) - error (NOHUP_FAILURE, errno, _("failed to redirect standard error")); + if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0) + { + if (errno != EBADF) + error (NOHUP_FAILURE, errno, + _("failed to redirect standard error")); + close (STDERR_FILENO); + } } signal (SIGHUP, SIG_IGN); @@ -171,13 +173,11 @@ main (int argc, char **argv) /* The execve failed. Output a diagnostic to stderr only if: - stderr was initially redirected to a non-tty, or - - stderr was initially directed to a tty, and we've - just dup2'd it to point back to that same tty. - In other words, output the diagnostic if possible, but not if - it'd go to nohup.out. */ - if ( ! stderr_isatty - || (saved_stderr_fd != -1 - && dup2 (saved_stderr_fd, STDERR_FILENO) != -1)) + - stderr was initially directed to a tty, and we + can dup2 it to point back to that same tty. + In other words, output the diagnostic if possible, but only if + it will go to the original stderr. */ + if (dup2 (saved_stderr_fd, STDERR_FILENO) == STDERR_FILENO) error (0, saved_errno, _("cannot run command %s"), quote (*cmd)); exit (exit_status); |