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