105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Close a stream, with nicer error checking than fclose's. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 1998-2002, 2004, 2006-2012 Free Software Foundation, Inc. 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3 of the License, or 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "close-stream.h" 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <errno.h> 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdbool.h> 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "fpending.h" 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_UNLOCKED_IO 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include "unlocked-io.h" 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Close STREAM. Return 0 if successful, EOF (setting errno) 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang otherwise. A failure might set errno to 0 if the error number 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang cannot be determined. 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang A failure with errno set to EPIPE may or may not indicate an error 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang situation worth signaling to the user. See the documentation of the 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang close_stdout_set_ignore_EPIPE function for details. 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang If a program writes *anything* to STREAM, that program should close 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang STREAM and make sure that it succeeds before exiting. Otherwise, 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang suppose that you go to the extreme of checking the return status 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang of every function that does an explicit write to STREAM. The last 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang printf can succeed in writing to the internal stream buffer, and yet 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang the fclose(STREAM) could still fail (due e.g., to a disk full error) 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang when it tries to write out that buffered data. Thus, you would be 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang left with an incomplete output file and the offending program would 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang exit successfully. Even calling fflush is not always sufficient, 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang since some file systems (NFS and CODA) buffer written/flushed data 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang until an actual close call. 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang Besides, it's wasteful to check the return value from every call 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang that writes to STREAM -- just let the internal stream state record 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang the failure. That's what the ferror test is checking below. */ 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wangint 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wangclose_stream (FILE *stream) 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang const bool some_pending = (__fpending (stream) != 0); 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang const bool prev_fail = (ferror (stream) != 0); 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang const bool fclose_fail = (fclose (stream) != 0); 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Return an error indication if there was a previous failure or if 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang fclose failed, with one exception: ignore an fclose failure if 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang there was no previous error, no data remains to be flushed, and 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang fclose failed with EBADF. That can happen when a program like cp 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang is invoked like this 'cp a b >&-' (i.e., with standard output 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang closed) and doesn't generate any output (hence no previous error 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang and nothing to be flushed). */ 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (! fclose_fail) 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang errno = 0; 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return EOF; 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 79