1*95b7b453SJohn Marino /* Close standard output and standard error, exiting with a diagnostic on error. 2*95b7b453SJohn Marino 3*95b7b453SJohn Marino Copyright (C) 1998-2002, 2004, 2006, 2008-2010 Free Software Foundation, 4*95b7b453SJohn Marino Inc. 5*95b7b453SJohn Marino 6*95b7b453SJohn Marino This program is free software: you can redistribute it and/or modify 7*95b7b453SJohn Marino it under the terms of the GNU General Public License as published by 8*95b7b453SJohn Marino the Free Software Foundation; either version 3 of the License, or 9*95b7b453SJohn Marino (at your option) any later version. 10*95b7b453SJohn Marino 11*95b7b453SJohn Marino This program is distributed in the hope that it will be useful, 12*95b7b453SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 13*95b7b453SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*95b7b453SJohn Marino GNU General Public License for more details. 15*95b7b453SJohn Marino 16*95b7b453SJohn Marino You should have received a copy of the GNU General Public License 17*95b7b453SJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18*95b7b453SJohn Marino 19*95b7b453SJohn Marino #include <config.h> 20*95b7b453SJohn Marino 21*95b7b453SJohn Marino #include "closeout.h" 22*95b7b453SJohn Marino 23*95b7b453SJohn Marino #include <errno.h> 24*95b7b453SJohn Marino #include <stdbool.h> 25*95b7b453SJohn Marino #include <stdio.h> 26*95b7b453SJohn Marino #include <unistd.h> 27*95b7b453SJohn Marino 28*95b7b453SJohn Marino #include "gettext.h" 29*95b7b453SJohn Marino #define _(msgid) gettext (msgid) 30*95b7b453SJohn Marino 31*95b7b453SJohn Marino #include "close-stream.h" 32*95b7b453SJohn Marino #include "error.h" 33*95b7b453SJohn Marino #include "exitfail.h" 34*95b7b453SJohn Marino #include "quotearg.h" 35*95b7b453SJohn Marino 36*95b7b453SJohn Marino static const char *file_name; 37*95b7b453SJohn Marino 38*95b7b453SJohn Marino /* Set the file name to be reported in the event an error is detected 39*95b7b453SJohn Marino by close_stdout. */ 40*95b7b453SJohn Marino void 41*95b7b453SJohn Marino close_stdout_set_file_name (const char *file) 42*95b7b453SJohn Marino { 43*95b7b453SJohn Marino file_name = file; 44*95b7b453SJohn Marino } 45*95b7b453SJohn Marino 46*95b7b453SJohn Marino static bool ignore_EPIPE /* = false */; 47*95b7b453SJohn Marino 48*95b7b453SJohn Marino /* Specify the reaction to an EPIPE error during the closing of stdout: 49*95b7b453SJohn Marino - If ignore = true, it shall be ignored. 50*95b7b453SJohn Marino - If ignore = false, it shall evoke a diagnostic, along with a nonzero 51*95b7b453SJohn Marino exit status. 52*95b7b453SJohn Marino The default is ignore = false. 53*95b7b453SJohn Marino 54*95b7b453SJohn Marino This setting matters only if the SIGPIPE signal is ignored (i.e. its 55*95b7b453SJohn Marino handler set to SIG_IGN) or blocked. Only particular programs need to 56*95b7b453SJohn Marino temporarily ignore SIGPIPE. If SIGPIPE is ignored or blocked because 57*95b7b453SJohn Marino it was ignored or blocked in the parent process when it created the 58*95b7b453SJohn Marino child process, it usually is a bug in the parent process: It is bad 59*95b7b453SJohn Marino practice to have SIGPIPE ignored or blocked while creating a child 60*95b7b453SJohn Marino process. 61*95b7b453SJohn Marino 62*95b7b453SJohn Marino EPIPE occurs when writing to a pipe or socket that has no readers now, 63*95b7b453SJohn Marino when SIGPIPE is ignored or blocked. 64*95b7b453SJohn Marino 65*95b7b453SJohn Marino The ignore = false setting is suitable for a scenario where it is normally 66*95b7b453SJohn Marino guaranteed that the pipe writer terminates before the pipe reader. In 67*95b7b453SJohn Marino this case, an EPIPE is an indication of a premature termination of the 68*95b7b453SJohn Marino pipe reader and should lead to a diagnostic and a nonzero exit status. 69*95b7b453SJohn Marino 70*95b7b453SJohn Marino The ignore = true setting is suitable for a scenario where you don't know 71*95b7b453SJohn Marino ahead of time whether the pipe writer or the pipe reader will terminate 72*95b7b453SJohn Marino first. In this case, an EPIPE is an indication that the pipe writer can 73*95b7b453SJohn Marino stop doing useless write() calls; this is what close_stdout does anyway. 74*95b7b453SJohn Marino EPIPE is part of the normal pipe/socket shutdown protocol in this case, 75*95b7b453SJohn Marino and should not lead to a diagnostic message. */ 76*95b7b453SJohn Marino 77*95b7b453SJohn Marino void 78*95b7b453SJohn Marino close_stdout_set_ignore_EPIPE (bool ignore) 79*95b7b453SJohn Marino { 80*95b7b453SJohn Marino ignore_EPIPE = ignore; 81*95b7b453SJohn Marino } 82*95b7b453SJohn Marino 83*95b7b453SJohn Marino /* Close standard output. On error, issue a diagnostic and _exit 84*95b7b453SJohn Marino with status 'exit_failure'. 85*95b7b453SJohn Marino 86*95b7b453SJohn Marino Also close standard error. On error, _exit with status 'exit_failure'. 87*95b7b453SJohn Marino 88*95b7b453SJohn Marino Since close_stdout is commonly registered via 'atexit', POSIX 89*95b7b453SJohn Marino and the C standard both say that it should not call 'exit', 90*95b7b453SJohn Marino because the behavior is undefined if 'exit' is called more than 91*95b7b453SJohn Marino once. So it calls '_exit' instead of 'exit'. If close_stdout 92*95b7b453SJohn Marino is registered via atexit before other functions are registered, 93*95b7b453SJohn Marino the other functions can act before this _exit is invoked. 94*95b7b453SJohn Marino 95*95b7b453SJohn Marino Applications that use close_stdout should flush any streams 96*95b7b453SJohn Marino other than stdout and stderr before exiting, since the call to 97*95b7b453SJohn Marino _exit will bypass other buffer flushing. Applications should 98*95b7b453SJohn Marino be flushing and closing other streams anyway, to check for I/O 99*95b7b453SJohn Marino errors. Also, applications should not use tmpfile, since _exit 100*95b7b453SJohn Marino can bypass the removal of these files. 101*95b7b453SJohn Marino 102*95b7b453SJohn Marino It's important to detect such failures and exit nonzero because many 103*95b7b453SJohn Marino tools (most notably `make' and other build-management systems) depend 104*95b7b453SJohn Marino on being able to detect failure in other tools via their exit status. */ 105*95b7b453SJohn Marino 106*95b7b453SJohn Marino void 107*95b7b453SJohn Marino close_stdout (void) 108*95b7b453SJohn Marino { 109*95b7b453SJohn Marino if (close_stream (stdout) != 0 110*95b7b453SJohn Marino && !(ignore_EPIPE && errno == EPIPE)) 111*95b7b453SJohn Marino { 112*95b7b453SJohn Marino char const *write_error = _("write error"); 113*95b7b453SJohn Marino if (file_name) 114*95b7b453SJohn Marino error (0, errno, "%s: %s", quotearg_colon (file_name), 115*95b7b453SJohn Marino write_error); 116*95b7b453SJohn Marino else 117*95b7b453SJohn Marino error (0, errno, "%s", write_error); 118*95b7b453SJohn Marino 119*95b7b453SJohn Marino _exit (exit_failure); 120*95b7b453SJohn Marino } 121*95b7b453SJohn Marino 122*95b7b453SJohn Marino if (close_stream (stderr) != 0) 123*95b7b453SJohn Marino _exit (exit_failure); 124*95b7b453SJohn Marino } 125