(linenum→info "unix/slp.c:2238")

coreutils/6.9/lib/close-stream.c

    1: /* Close a stream, with nicer error checking than fclose's.
    2: 
    3:    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free
    4:    Software Foundation, Inc.
    5: 
    6:    This program is free software; you can redistribute it and/or modify
    7:    it under the terms of the GNU General Public License as published by
    8:    the Free Software Foundation; either version 2, or (at your option)
    9:    any later version.
   10: 
   11:    This program is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14:    GNU General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU General Public License
   17:    along with this program; if not, write to the Free Software Foundation,
   18:    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
   19: 
   20: #include <config.h>
   21: 
   22: #include "close-stream.h"
   23: 
   24: #include <errno.h>
   25: #include <stdbool.h>
   26: 
   27: #include "__fpending.h"
   28: 
   29: #if USE_UNLOCKED_IO
   30: # include "unlocked-io.h"
   31: #endif
   32: 
   33: /* Close STREAM.  Return 0 if successful, EOF (setting errno)
   34:    otherwise.  A failure might set errno to 0 if the error number
   35:    cannot be determined.
   36: 
   37:    If a program writes *anything* to STREAM, that program should close
   38:    STREAM and make sure that it succeeds before exiting.  Otherwise,
   39:    suppose that you go to the extreme of checking the return status
   40:    of every function that does an explicit write to STREAM.  The last
   41:    printf can succeed in writing to the internal stream buffer, and yet
   42:    the fclose(STREAM) could still fail (due e.g., to a disk full error)
   43:    when it tries to write out that buffered data.  Thus, you would be
   44:    left with an incomplete output file and the offending program would
   45:    exit successfully.  Even calling fflush is not always sufficient,
   46:    since some file systems (NFS and CODA) buffer written/flushed data
   47:    until an actual close call.
   48: 
   49:    Besides, it's wasteful to check the return value from every call
   50:    that writes to STREAM -- just let the internal stream state record
   51:    the failure.  That's what the ferror test is checking below.  */
   52: 
   53: int
   54: close_stream (FILE *stream)
   55: {
   56:   bool some_pending = (__fpending (stream) != 0);
   57:   bool prev_fail = (ferror (stream) != 0);
   58:   bool fclose_fail = (fclose (stream) != 0);
   59: 
   60:   /* Return an error indication if there was a previous failure or if
   61:      fclose failed, with one exception: ignore an fclose failure if
   62:      there was no previous error, no data remains to be flushed, and
   63:      fclose failed with EBADF.  That can happen when a program like cp
   64:      is invoked like this `cp a b >&-' (i.e., with standard output
   65:      closed) and doesn't generate any output (hence no previous error
   66:      and nothing to be flushed).  */
   67: 
   68:   if (prev_fail || (fclose_fail && (some_pending || errno != EBADF)))
   69:     {
   70:       if (! fclose_fail)
   71:         errno = 0;
   72:       return EOF;
   73:     }
   74: 
   75:   return 0;
   76: }
Syntax (Markdown)