OpenCoverage

nohup.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/src/nohup.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* nohup -- run a command immune to hangups, with output to a non-tty-
2 Copyright (C) 2003-2018 Free Software Foundation, Inc.-
3-
4 This program is free software: you can redistribute it and/or modify-
5 it under the terms of the GNU General Public License as published by-
6 the Free Software Foundation, either version 3 of the License, or-
7 (at your option) any later version.-
8-
9 This program is distributed in the hope that it will be useful,-
10 but WITHOUT ANY WARRANTY; without even the implied warranty of-
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
12 GNU General Public License for more details.-
13-
14 You should have received a copy of the GNU General Public License-
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
16-
17/* Written by Jim Meyering */-
18-
19#include <config.h>-
20#include <getopt.h>-
21#include <stdio.h>-
22#include <sys/types.h>-
23#include <signal.h>-
24-
25#include "system.h"-
26-
27#include "error.h"-
28#include "filenamecat.h"-
29#include "fd-reopen.h"-
30#include "long-options.h"-
31#include "unistd--.h"-
32-
33#define PROGRAM_NAME "nohup"-
34-
35#define AUTHORS proper_name ("Jim Meyering")-
36-
37static struct option const long_options[] =-
38{-
39 {NULL, 0, NULL, 0}-
40};-
41-
42/* Exit statuses. */-
43enum-
44 {-
45 /* 'nohup' itself failed. */-
46 POSIX_NOHUP_FAILURE = 127-
47 };-
48-
49void-
50usage (int status)-
51{-
52 if (status != EXIT_SUCCESS)
status != 0Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • nohup
FALSEevaluated 3 times by 1 test
Evaluated by:
  • nohup
3-5
53 emit_try_help ();
executed 5 times by 1 test: end of block
Executed by:
  • nohup
5
54 else-
55 {-
56 printf (_("\-
57Usage: %s COMMAND [ARG]...\n\-
58 or: %s OPTION\n\-
59"),-
60 program_name, program_name);-
61-
62 fputs (_("\-
63Run COMMAND, ignoring hangup signals.\n\-
64\n\-
65"), stdout);-
66 fputs (HELP_OPTION_DESCRIPTION, stdout);-
67 fputs (VERSION_OPTION_DESCRIPTION, stdout);-
68 printf (_("\n\-
69If standard input is a terminal, redirect it from an unreadable file.\n\-
70If standard output is a terminal, append output to 'nohup.out' if possible,\n\-
71'$HOME/nohup.out' otherwise.\n\-
72If standard error is a terminal, redirect it to standard output.\n\-
73To save output to FILE, use '%s COMMAND > FILE'.\n"),-
74 program_name);-
75 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);-
76 emit_ancillary_info (PROGRAM_NAME);-
77 }
executed 3 times by 1 test: end of block
Executed by:
  • nohup
3
78 exit (status);
executed 8 times by 1 test: exit (status);
Executed by:
  • nohup
8
79}-
80-
81int-
82main (int argc, char **argv)-
83{-
84 int out_fd = STDOUT_FILENO;-
85 int saved_stderr_fd = STDERR_FILENO;-
86 bool ignoring_input;-
87 bool redirecting_stdout;-
88 bool stdout_is_closed;-
89 bool redirecting_stderr;-
90 int exit_internal_failure;-
91-
92 initialize_main (&argc, &argv);-
93 set_program_name (argv[0]);-
94 setlocale (LC_ALL, "");-
95 bindtextdomain (PACKAGE, LOCALEDIR);-
96 textdomain (PACKAGE);-
97-
98 /* POSIX 2008 requires that internal failure give status 127; unlike-
99 for env, exec, nice, time, and xargs where it requires internal-
100 failure give something in the range 1-125. For consistency with-
101 other tools, fail with EXIT_CANCELED unless POSIXLY_CORRECT. */-
102 exit_internal_failure = (getenv ("POSIXLY_CORRECT")
getenv ("POSIXLY_CORRECT")Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • nohup
FALSEevaluated 14 times by 1 test
Evaluated by:
  • nohup
1-14
103 ? POSIX_NOHUP_FAILURE : EXIT_CANCELED);-
104 initialize_exit_failure (exit_internal_failure);-
105 atexit (close_stdout);-
106-
107 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,-
108 usage, AUTHORS, (char const *) NULL);-
109 if (getopt_long (argc, argv, "+", long_options, NULL) != -1)
getopt_long (a...d *)0) ) != -1Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • nohup
FALSEevaluated 4 times by 1 test
Evaluated by:
  • nohup
3-4
110 usage (exit_internal_failure);
executed 3 times by 1 test: usage (exit_internal_failure);
Executed by:
  • nohup
3
111-
112 if (argc <= optind)
argc <= optindDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • nohup
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
2
113 {-
114 error (0, 0, _("missing operand"));-
115 usage (exit_internal_failure);-
116 }
never executed: end of block
0
117-
118 ignoring_input = isatty (STDIN_FILENO);-
119 redirecting_stdout = isatty (STDOUT_FILENO);-
120 stdout_is_closed = (!redirecting_stdout && errno == EBADF);
!redirecting_stdoutDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • nohup
FALSEnever evaluated
(*__errno_location ()) == 9Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
0-2
121 redirecting_stderr = isatty (STDERR_FILENO);-
122-
123 /* If standard input is a tty, replace it with /dev/null if possible.-
124 Note that it is deliberately opened for *writing*,-
125 to ensure any read evokes an error. */-
126 if (ignoring_input)
ignoring_inputDescription
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
0-2
127 {-
128 if (fd_reopen (STDIN_FILENO, "/dev/null", O_WRONLY, 0) < 0)
fd_reopen ( 0 ...", 01 , 0) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
129 error (exit_internal_failure, errno,
never executed: error (exit_internal_failure, (*__errno_location ()) , dcgettext (((void *)0), "failed to render standard input unusable" , 5) );
0
130 _("failed to render standard input unusable"));
never executed: error (exit_internal_failure, (*__errno_location ()) , dcgettext (((void *)0), "failed to render standard input unusable" , 5) );
0
131 if (!redirecting_stdout && !redirecting_stderr)
!redirecting_stdoutDescription
TRUEnever evaluated
FALSEnever evaluated
!redirecting_stderrDescription
TRUEnever evaluated
FALSEnever evaluated
0
132 error (0, 0, _("ignoring input"));
never executed: error (0, 0, dcgettext (((void *)0), "ignoring input" , 5) );
0
133 }
never executed: end of block
0
134-
135 /* If standard output is a tty, redirect it (appending) to a file.-
136 First try nohup.out, then $HOME/nohup.out. If standard error is-
137 a tty and standard output is closed, open nohup.out or-
138 $HOME/nohup.out without redirecting anything. */-
139 if (redirecting_stdout || (redirecting_stderr && stdout_is_closed))
redirecting_stdoutDescription
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
redirecting_stderrDescription
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
stdout_is_closedDescription
TRUEnever evaluated
FALSEnever evaluated
0-2
140 {-
141 char *in_home = NULL;-
142 char const *file = "nohup.out";-
143 int flags = O_CREAT | O_WRONLY | O_APPEND;-
144 mode_t mode = S_IRUSR | S_IWUSR;-
145 mode_t umask_value = umask (~mode);-
146 out_fd = (redirecting_stdout
redirecting_stdoutDescription
TRUEnever evaluated
FALSEnever evaluated
0
147 ? fd_reopen (STDOUT_FILENO, file, flags, mode)-
148 : open (file, flags, mode));-
149-
150 if (out_fd < 0)
out_fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
151 {-
152 int saved_errno = errno;-
153 char const *home = getenv ("HOME");-
154 if (home)
homeDescription
TRUEnever evaluated
FALSEnever evaluated
0
155 {-
156 in_home = file_name_concat (home, file, NULL);-
157 out_fd = (redirecting_stdout
redirecting_stdoutDescription
TRUEnever evaluated
FALSEnever evaluated
0
158 ? fd_reopen (STDOUT_FILENO, in_home, flags, mode)-
159 : open (in_home, flags, mode));-
160 }
never executed: end of block
0
161 if (out_fd < 0)
out_fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
162 {-
163 int saved_errno2 = errno;-
164 error (0, saved_errno, _("failed to open %s"), quoteaf (file));-
165 if (in_home)
in_homeDescription
TRUEnever evaluated
FALSEnever evaluated
0
166 error (0, saved_errno2, _("failed to open %s"),
never executed: error (0, saved_errno2, dcgettext (((void *)0), "failed to open %s" , 5) , quotearg_style (shell_escape_always_quoting_style, in_home));
0
167 quoteaf (in_home));
never executed: error (0, saved_errno2, dcgettext (((void *)0), "failed to open %s" , 5) , quotearg_style (shell_escape_always_quoting_style, in_home));
0
168 return exit_internal_failure;
never executed: return exit_internal_failure;
0
169 }-
170 file = in_home;-
171 }
never executed: end of block
0
172-
173 umask (umask_value);-
174 error (0, 0,-
175 _(ignoring_input-
176 ? N_("ignoring input and appending output to %s")-
177 : N_("appending output to %s")),-
178 quoteaf (file));-
179 free (in_home);-
180 }
never executed: end of block
0
181-
182 /* If standard error is a tty, redirect it. */-
183 if (redirecting_stderr)
redirecting_stderrDescription
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
0-2
184 {-
185 /* Save a copy of stderr before redirecting, so we can use the original-
186 if execve fails. It's no big deal if this dup fails. It might-
187 not change anything, and at worst, it'll lead to suppression of-
188 the post-failed-execve diagnostic. */-
189 saved_stderr_fd = fcntl (STDERR_FILENO, F_DUPFD_CLOEXEC,-
190 STDERR_FILENO + 1);-
191-
192 if (!redirecting_stdout)
!redirecting_stdoutDescription
TRUEnever evaluated
FALSEnever evaluated
0
193 error (0, 0,
never executed: error (0, 0, dcgettext (((void *)0), ignoring_input ? "ignoring input and redirecting stderr to stdout" : "redirecting stderr to stdout" , 5) );
0
194 _(ignoring_input
never executed: error (0, 0, dcgettext (((void *)0), ignoring_input ? "ignoring input and redirecting stderr to stdout" : "redirecting stderr to stdout" , 5) );
0
195 ? N_("ignoring input and redirecting stderr to stdout")
never executed: error (0, 0, dcgettext (((void *)0), ignoring_input ? "ignoring input and redirecting stderr to stdout" : "redirecting stderr to stdout" , 5) );
0
196 : N_("redirecting stderr to stdout")));
never executed: error (0, 0, dcgettext (((void *)0), ignoring_input ? "ignoring input and redirecting stderr to stdout" : "redirecting stderr to stdout" , 5) );
0
197-
198 if (dup2 (out_fd, STDERR_FILENO) < 0)
dup2 (out_fd, 2 ) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
199 error (exit_internal_failure, errno,
never executed: error (exit_internal_failure, (*__errno_location ()) , dcgettext (((void *)0), "failed to redirect standard error" , 5) );
0
200 _("failed to redirect standard error"));
never executed: error (exit_internal_failure, (*__errno_location ()) , dcgettext (((void *)0), "failed to redirect standard error" , 5) );
0
201-
202 if (stdout_is_closed)
stdout_is_closedDescription
TRUEnever evaluated
FALSEnever evaluated
0
203 close (out_fd);
never executed: close (out_fd);
0
204 }
never executed: end of block
0
205-
206 /* error() flushes stderr, but does not check for write failure.-
207 Normally, we would catch this via our atexit() hook of-
208 close_stdout, but execvp() gets in the way. If stderr-
209 encountered a write failure, there is no need to try calling-
210 error() again, particularly since we may have just changed the-
211 underlying fd out from under stderr. */-
212 if (ferror (stderr))
ferror_unlocked ( stderr )Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • nohup
0-2
213 return exit_internal_failure;
never executed: return exit_internal_failure;
0
214-
215 signal (SIGHUP, SIG_IGN);-
216-
217 char **cmd = argv + optind;-
218 execvp (*cmd, cmd);-
219 int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
(*__errno_location ()) == 2Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • nohup
FALSEevaluated 1 time by 1 test
Evaluated by:
  • nohup
1
220 int saved_errno = errno;-
221-
222 /* The execve failed. Output a diagnostic to stderr only if:-
223 - stderr was initially redirected to a non-tty, or-
224 - stderr was initially directed to a tty, and we-
225 can dup2 it to point back to that same tty.-
226 In other words, output the diagnostic if possible, but only if-
227 it will go to the original stderr. */-
228 if (dup2 (saved_stderr_fd, STDERR_FILENO) == STDERR_FILENO)
dup2 (saved_st...r_fd, 2 ) == 2Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • nohup
FALSEnever evaluated
0-2
229 error (0, saved_errno, _("failed to run command %s"), quoteaf (*cmd));
executed 2 times by 1 test: error (0, saved_errno, dcgettext (((void *)0), "failed to run command %s" , 5) , quotearg_style (shell_escape_always_quoting_style, *cmd));
Executed by:
  • nohup
2
230-
231 return exit_status;
executed 2 times by 1 test: return exit_status;
Executed by:
  • nohup
2
232}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2