Change license from GPLv2+ to GPLv3+.
[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 3 of the License, or
9    (at your option) 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, see <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 /* Specification.  */
24 #include "freaderror.h"
25
26 #include <errno.h>
27 #include <stdbool.h>
28
29 /* Close the stream FP, and test whether some error occurred on
30    the stream FP.
31    FP must be a stream opened for reading.
32    Return 0 if no error occurred and fclose (fp) succeeded.
33    Return -1 and set errno if there was an error.  The errno value will be 0
34    if the cause of the error cannot be determined. */
35 int
36 freaderror (FILE *fp)
37 {
38   /* Need to
39      1. test the error indicator of the stream,
40      2. flush the buffers both in userland and in the kernel, through fclose,
41         testing for error again.  */
42
43   /* Clear errno, so that on non-POSIX systems the caller doesn't see a
44      wrong value of errno when we return -1.  */
45   errno = 0;
46
47   if (ferror (fp))
48     {
49       /* The stream had an error earlier, but its errno was lost.
50          If the error was not temporary, we can get the same
51          errno by reading one more byte.  */
52       getc (fp);
53       fclose (fp);
54       return -1;
55     }
56
57   if (fclose (fp))
58     return -1; /* errno is set here */
59
60   return 0;
61 }