73e5346abe734a5fd8c3f6e08155b8768de46286
[pspp-builds.git] / src / libpspp / freaderror.c
1 /* Detect read error on a stream.
2    Copyright (C) 2003-2005, 2006 Free Software Foundation, Inc.
3    Written by Bruno Haible <bruno@clisp.org>, 2003.
4    Modified by Ben Pfaff <blp@cs.stanford.edu> for PSPP.
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 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 /* Specification.  */
25 #include "freaderror.h"
26
27 #include <errno.h>
28 #include <stdbool.h>
29
30 /* Close the stream FP, and test whether some error occurred on
31    the stream FP.
32    FP must be a stream opened for reading.
33    Return 0 if no error occurred and fclose (fp) succeeded.
34    Return -1 and set errno if there was an error.  The errno value will be 0
35    if the cause of the error cannot be determined. */
36 int
37 freaderror (FILE *fp)
38 {
39   /* Need to
40      1. test the error indicator of the stream,
41      2. flush the buffers both in userland and in the kernel, through fclose,
42         testing for error again.  */
43
44   /* Clear errno, so that on non-POSIX systems the caller doesn't see a
45      wrong value of errno when we return -1.  */
46   errno = 0;
47
48   if (ferror (fp))
49     {
50       /* The stream had an error earlier, but its errno was lost.
51          If the error was not temporary, we can get the same
52          errno by reading one more byte.  */
53       getc (fp);
54       fclose (fp);
55       return -1;
56     }
57
58   if (fclose (fp))
59     return -1; /* errno is set here */
60
61   return 0;
62 }