Line data Source code
1 : /* Set the error indicator of a stream. 2 : Copyright (C) 2007-2025 Free Software Foundation, Inc. 3 : 4 : This file is free software: you can redistribute it and/or modify 5 : it under the terms of the GNU Lesser General Public License as 6 : published by the Free Software Foundation; either version 2.1 of the 7 : License, or (at your option) any later version. 8 : 9 : This file 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 Lesser General Public License for more details. 13 : 14 : You should have received a copy of the GNU Lesser General Public License 15 : along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 : 17 : #include <config.h> 18 : 19 : /* Specification. */ 20 : #include "fseterr.h" 21 : 22 : #include <errno.h> 23 : 24 : #include "stdio-impl.h" 25 : 26 : /* This file is not used on systems that have the __fseterr function, 27 : namely OpenBSD >= 7.6, musl libc, Haiku >= hrev58760. */ 28 : 29 : void 30 0 : fseterr (FILE *fp) 31 : { 32 : /* Most systems provide FILE as a struct and the necessary bitmask in 33 : <stdio.h>, because they need it for implementing getc() and putc() as 34 : fast macros. */ 35 : #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 36 : /* GNU libc, BeOS, Haiku, Linux libc5 */ 37 0 : fp->_flags |= _IO_ERR_SEEN; 38 : #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ 39 : /* FreeBSD, NetBSD, OpenBSD < 7.6, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ 40 : fp_->_flags |= __SERR; 41 : #elif defined __EMX__ /* emx+gcc */ 42 : fp->_flags |= _IOERR; 43 : #elif defined __minix /* Minix */ 44 : fp->_flags |= _IOERR; 45 : #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ 46 : fp_->_flag |= _IOERR; 47 : #elif defined __UCLIBC__ /* uClibc */ 48 : fp->__modeflags |= __FLAG_ERROR; 49 : #elif defined __QNX__ /* QNX */ 50 : fp->_Mode |= 0x200 /* _MERR */; 51 : #elif defined __MINT__ /* Atari FreeMiNT */ 52 : fp->__error = 1; 53 : #elif defined EPLAN9 /* Plan9 */ 54 : if (fp->state != 0 /* CLOSED */) 55 : fp->state = 5 /* ERR */; 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 : }