split: port ‘split -n N /dev/null’ better to macOS
[coreutils.git] / src / tee.c
blob4fc6722d4b2c0d909d7f7265fa4211e6fda10d35
1 /* tee - read from standard input and write to standard output and files.
2 Copyright (C) 1985-2023 Free Software Foundation, Inc.
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.
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.
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/>. */
17 /* Mike Parker, Richard M. Stallman, and David MacKenzie */
19 #include <config.h>
20 #include <sys/types.h>
21 #include <signal.h>
22 #include <getopt.h>
24 #include "system.h"
25 #include "argmatch.h"
26 #include "die.h"
27 #include "error.h"
28 #include "fadvise.h"
29 #include "stdio--.h"
30 #include "xbinary-io.h"
31 #include "iopoll.h"
33 /* The official name of this program (e.g., no 'g' prefix). */
34 #define PROGRAM_NAME "tee"
36 #define AUTHORS \
37 proper_name ("Mike Parker"), \
38 proper_name ("Richard M. Stallman"), \
39 proper_name ("David MacKenzie")
41 static bool tee_files (int nfiles, char **files, bool);
43 /* If true, append to output files rather than truncating them. */
44 static bool append;
46 /* If true, ignore interrupts. */
47 static bool ignore_interrupts;
49 enum output_error
51 output_error_sigpipe, /* traditional behavior, sigpipe enabled. */
52 output_error_warn, /* warn on EPIPE, but continue. */
53 output_error_warn_nopipe, /* ignore EPIPE, continue. */
54 output_error_exit, /* exit on any output error. */
55 output_error_exit_nopipe /* exit on any output error except EPIPE. */
58 static enum output_error output_error;
60 static struct option const long_options[] =
62 {"append", no_argument, NULL, 'a'},
63 {"ignore-interrupts", no_argument, NULL, 'i'},
64 {"output-error", optional_argument, NULL, 'p'},
65 {GETOPT_HELP_OPTION_DECL},
66 {GETOPT_VERSION_OPTION_DECL},
67 {NULL, 0, NULL, 0}
70 static char const *const output_error_args[] =
72 "warn", "warn-nopipe", "exit", "exit-nopipe", NULL
74 static enum output_error const output_error_types[] =
76 output_error_warn, output_error_warn_nopipe,
77 output_error_exit, output_error_exit_nopipe
79 ARGMATCH_VERIFY (output_error_args, output_error_types);
81 void
82 usage (int status)
84 if (status != EXIT_SUCCESS)
85 emit_try_help ();
86 else
88 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
89 fputs (_("\
90 Copy standard input to each FILE, and also to standard output.\n\
91 \n\
92 -a, --append append to the given FILEs, do not overwrite\n\
93 -i, --ignore-interrupts ignore interrupt signals\n\
94 "), stdout);
95 fputs (_("\
96 -p operate in a more appropriate MODE with pipes.\n\
97 --output-error[=MODE] set behavior on write error. See MODE below\n\
98 "), stdout);
99 fputs (HELP_OPTION_DESCRIPTION, stdout);
100 fputs (VERSION_OPTION_DESCRIPTION, stdout);
101 fputs (_("\
103 MODE determines behavior with write errors on the outputs:\n\
104 warn diagnose errors writing to any output\n\
105 warn-nopipe diagnose errors writing to any output not a pipe\n\
106 exit exit on error writing to any output\n\
107 exit-nopipe exit on error writing to any output not a pipe\n\
108 The default MODE for the -p option is 'warn-nopipe'.\n\
109 With \"nopipe\" MODEs, exit immediately if all outputs become broken pipes.\n\
110 The default operation when --output-error is not specified, is to\n\
111 exit immediately on error writing to a pipe, and diagnose errors\n\
112 writing to non pipe outputs.\n\
113 "), stdout);
114 emit_ancillary_info (PROGRAM_NAME);
116 exit (status);
120 main (int argc, char **argv)
122 initialize_main (&argc, &argv);
123 set_program_name (argv[0]);
124 setlocale (LC_ALL, "");
125 bindtextdomain (PACKAGE, LOCALEDIR);
126 textdomain (PACKAGE);
128 atexit (close_stdout);
130 append = false;
131 ignore_interrupts = false;
133 int optc;
134 while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
136 switch (optc)
138 case 'a':
139 append = true;
140 break;
142 case 'i':
143 ignore_interrupts = true;
144 break;
146 case 'p':
147 if (optarg)
148 output_error = XARGMATCH ("--output-error", optarg,
149 output_error_args, output_error_types);
150 else
151 output_error = output_error_warn_nopipe;
152 break;
154 case_GETOPT_HELP_CHAR;
156 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
158 default:
159 usage (EXIT_FAILURE);
163 if (ignore_interrupts)
164 signal (SIGINT, SIG_IGN);
166 if (output_error != output_error_sigpipe)
167 signal (SIGPIPE, SIG_IGN);
169 /* Whether to detect and close a broken pipe output.
170 There is no need if the input is always ready for reading. */
171 bool pipe_check = ((output_error == output_error_warn_nopipe
172 || output_error == output_error_exit_nopipe)
173 && iopoll_input_ok (STDIN_FILENO));
175 /* Do *not* warn if tee is given no file arguments.
176 POSIX requires that it work when given no arguments. */
178 bool ok = tee_files (argc - optind, &argv[optind], pipe_check);
179 if (close (STDIN_FILENO) != 0)
180 die (EXIT_FAILURE, errno, "%s", _("standard input"));
182 return ok ? EXIT_SUCCESS : EXIT_FAILURE;
186 /* Return the index of the first non-NULL descriptor after idx,
187 or -1 if all are NULL. */
189 static int
190 get_next_out (FILE **descriptors, int nfiles, int idx)
192 for (idx++; idx <= nfiles; idx++)
193 if (descriptors[idx])
194 return idx;
195 return -1; /* no outputs remaining */
198 /* Remove descriptors[i] due to write failure or broken pipe.
199 Return true if this indicates a reportable error. */
201 static bool
202 fail_output (FILE **descriptors, char **files, int i)
204 int w_errno = errno;
205 bool fail = errno != EPIPE
206 || output_error == output_error_exit
207 || output_error == output_error_warn;
208 if (descriptors[i] == stdout)
209 clearerr (stdout); /* Avoid redundant close_stdout diagnostic. */
210 if (fail)
212 error (output_error == output_error_exit
213 || output_error == output_error_exit_nopipe,
214 w_errno, "%s", quotef (files[i]));
216 descriptors[i] = NULL;
217 return fail;
221 /* Copy the standard input into each of the NFILES files in FILES
222 and into the standard output. As a side effect, modify FILES[-1].
223 Return true if successful. */
225 static bool
226 tee_files (int nfiles, char **files, bool pipe_check)
228 size_t n_outputs = 0;
229 FILE **descriptors;
230 bool *out_pollable;
231 char buffer[BUFSIZ];
232 ssize_t bytes_read = 0;
233 int i;
234 int first_out = 0; /* idx of first non-NULL output in descriptors */
235 bool ok = true;
236 char const *mode_string =
237 (O_BINARY
238 ? (append ? "ab" : "wb")
239 : (append ? "a" : "w"));
241 xset_binary_mode (STDIN_FILENO, O_BINARY);
242 xset_binary_mode (STDOUT_FILENO, O_BINARY);
243 fadvise (stdin, FADVISE_SEQUENTIAL);
245 /* Set up FILES[0 .. NFILES] and DESCRIPTORS[0 .. NFILES].
246 In both arrays, entry 0 corresponds to standard output. */
248 descriptors = xnmalloc (nfiles + 1, sizeof *descriptors);
249 if (pipe_check)
250 out_pollable = xnmalloc (nfiles + 1, sizeof *out_pollable);
251 files--;
252 descriptors[0] = stdout;
253 if (pipe_check)
254 out_pollable[0] = iopoll_output_ok (fileno (descriptors[0]));
255 files[0] = bad_cast (_("standard output"));
256 setvbuf (stdout, NULL, _IONBF, 0);
257 n_outputs++;
259 for (i = 1; i <= nfiles; i++)
261 /* Do not treat "-" specially - as mandated by POSIX. */
262 descriptors[i] = fopen (files[i], mode_string);
263 if (pipe_check)
264 out_pollable[i] = iopoll_output_ok (fileno (descriptors[i]));
265 if (descriptors[i] == NULL)
267 error (output_error == output_error_exit
268 || output_error == output_error_exit_nopipe,
269 errno, "%s", quotef (files[i]));
270 ok = false;
272 else
274 setvbuf (descriptors[i], NULL, _IONBF, 0);
275 n_outputs++;
279 while (n_outputs)
281 if (pipe_check && out_pollable[first_out])
283 /* Monitor for input, or errors on first valid output. */
284 int err = iopoll (STDIN_FILENO, fileno (descriptors[first_out]),
285 true);
287 /* Close the output if it became a broken pipe. */
288 if (err == IOPOLL_BROKEN_OUTPUT)
290 errno = EPIPE; /* behave like write produced EPIPE */
291 if (fail_output (descriptors, files, first_out))
292 ok = false;
293 n_outputs--;
294 first_out = get_next_out (descriptors, nfiles, first_out);
295 continue;
297 else if (err == IOPOLL_ERROR)
299 error (0, errno, _("iopoll error"));
300 ok = false;
304 bytes_read = read (STDIN_FILENO, buffer, sizeof buffer);
305 if (bytes_read < 0 && errno == EINTR)
306 continue;
307 if (bytes_read <= 0)
308 break;
310 /* Write to all NFILES + 1 descriptors.
311 Standard output is the first one. */
312 for (i = 0; i <= nfiles; i++)
313 if (descriptors[i]
314 && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
316 if (fail_output (descriptors, files, i))
317 ok = false;
318 n_outputs--;
319 if (i == first_out)
320 first_out = get_next_out (descriptors, nfiles, first_out);
324 if (bytes_read == -1)
326 error (0, errno, _("read error"));
327 ok = false;
330 /* Close the files, but not standard output. */
331 for (i = 1; i <= nfiles; i++)
332 if (descriptors[i] && fclose (descriptors[i]) != 0)
334 error (0, errno, "%s", quotef (files[i]));
335 ok = false;
338 free (descriptors);
339 if (pipe_check)
340 free (out_pollable);
342 return ok;