Line data Source code
1 : /* Set the error indicator of a stream.
2 : Copyright (C) 2007-2008 Free Software Foundation, Inc.
3 :
4 : This program is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation; either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : This program is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 :
17 : #include <config.h>
18 :
19 : /* Specification. */
20 : #include "fseterr.h"
21 :
22 : #include <errno.h>
23 :
24 : void
25 0 : fseterr (FILE *fp)
26 : {
27 : /* Most systems provide FILE as a struct and the necessary bitmask in
28 : <stdio.h>, because they need it for implementing getc() and putc() as
29 : fast macros. */
30 : #if defined _IO_ferror_unlocked || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Linux libc5 */
31 0 : fp->_flags |= _IO_ERR_SEEN;
32 : #elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
33 : fp->_flags |= __SERR;
34 : #elif defined __EMX__ /* emx+gcc */
35 : fp->_flags |= _IOERR;
36 : #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
37 : # if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
38 : # define fp_ ((struct { unsigned char *_ptr; \
39 : unsigned char *_base; \
40 : unsigned char *_end; \
41 : long _cnt; \
42 : int _file; \
43 : unsigned int _flag; \
44 : } *) fp)
45 : fp_->_flag |= _IOERR;
46 : # else
47 : # if defined _SCO_DS /* OpenServer */
48 : # define _flag __flag
49 : # endif
50 : fp->_flag |= _IOERR;
51 : # endif
52 : #elif defined __UCLIBC__ /* uClibc */
53 : fp->__modeflags |= __FLAG_ERROR;
54 : #elif defined __QNX__ /* QNX */
55 : fp->_Mode |= 0x200 /* _MERR */;
56 : #elif 0 /* unknown */
57 : /* Portable fallback, based on an idea by Rich Felker.
58 : Wow! 6 system calls for something that is just a bit operation!
59 : Not activated on any system, because there is no way to repair FP when
60 : the sequence of system calls fails, and library code should not call
61 : abort(). */
62 : int saved_errno;
63 : int fd;
64 : int fd2;
65 :
66 : saved_errno = errno;
67 : fflush (fp);
68 : fd = fileno (fp);
69 : fd2 = dup (fd);
70 : if (fd2 >= 0)
71 : {
72 : close (fd);
73 : fputc ('\0', fp); /* This should set the error indicator. */
74 : fflush (fp); /* Or this. */
75 : if (dup2 (fd2, fd) < 0)
76 : /* Whee... we botched the stream and now cannot restore it! */
77 : abort ();
78 : close (fd2);
79 : }
80 : errno = saved_errno;
81 : #else
82 : #error "Please port gnulib fseterr.c to your platform! Look at the definitions of ferror and clearerr on your system, then report this to bug-gnulib."
83 : #endif
84 0 : }
|