1 | /* POSIX compatible FILE stream read function.
|
---|
2 | Copyright (C) 2008-2022 Free Software Foundation, Inc.
|
---|
3 | Written by Bruno Haible <[email protected]>, 2011.
|
---|
4 |
|
---|
5 | This file is free software: you can redistribute it and/or modify
|
---|
6 | it under the terms of the GNU Lesser General Public License as
|
---|
7 | published by the Free Software Foundation; either version 2.1 of the
|
---|
8 | License, or (at your option) any later version.
|
---|
9 |
|
---|
10 | This file is distributed in the hope that it will be useful,
|
---|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | GNU Lesser General Public License for more details.
|
---|
14 |
|
---|
15 | You should have received a copy of the GNU Lesser General Public License
|
---|
16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
---|
17 |
|
---|
18 | #include <config.h>
|
---|
19 |
|
---|
20 | /* Specification. */
|
---|
21 | #include <stdio.h>
|
---|
22 |
|
---|
23 | /* Replace these functions only if module 'nonblocking' is requested. */
|
---|
24 | #if GNULIB_NONBLOCKING
|
---|
25 |
|
---|
26 | /* On native Windows platforms, when read() is called on a non-blocking pipe
|
---|
27 | with an empty buffer, ReadFile() fails with error GetLastError() =
|
---|
28 | ERROR_NO_DATA, and read() in consequence fails with error EINVAL. This
|
---|
29 | read() function is at the basis of the function which fills the buffer of
|
---|
30 | a FILE stream. */
|
---|
31 |
|
---|
32 | # if defined _WIN32 && ! defined __CYGWIN__
|
---|
33 |
|
---|
34 | # include <errno.h>
|
---|
35 | # include <io.h>
|
---|
36 |
|
---|
37 | # define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
---|
38 | # include <windows.h>
|
---|
39 |
|
---|
40 | # if GNULIB_MSVC_NOTHROW
|
---|
41 | # include "msvc-nothrow.h"
|
---|
42 | # else
|
---|
43 | # include <io.h>
|
---|
44 | # endif
|
---|
45 |
|
---|
46 | /* Don't assume that UNICODE is not defined. */
|
---|
47 | # undef GetNamedPipeHandleState
|
---|
48 | # define GetNamedPipeHandleState GetNamedPipeHandleStateA
|
---|
49 |
|
---|
50 | # define CALL_WITH_ERRNO_FIX(RETTYPE, EXPRESSION, FAILED) \
|
---|
51 | if (ferror (stream)) \
|
---|
52 | return (EXPRESSION); \
|
---|
53 | else \
|
---|
54 | { \
|
---|
55 | RETTYPE ret; \
|
---|
56 | SetLastError (0); \
|
---|
57 | ret = (EXPRESSION); \
|
---|
58 | if (FAILED) \
|
---|
59 | { \
|
---|
60 | if (GetLastError () == ERROR_NO_DATA && ferror (stream)) \
|
---|
61 | { \
|
---|
62 | int fd = fileno (stream); \
|
---|
63 | if (fd >= 0) \
|
---|
64 | { \
|
---|
65 | HANDLE h = (HANDLE) _get_osfhandle (fd); \
|
---|
66 | if (GetFileType (h) == FILE_TYPE_PIPE) \
|
---|
67 | { \
|
---|
68 | /* h is a pipe or socket. */ \
|
---|
69 | DWORD state; \
|
---|
70 | if (GetNamedPipeHandleState (h, &state, NULL, NULL, \
|
---|
71 | NULL, NULL, 0) \
|
---|
72 | && (state & PIPE_NOWAIT) != 0) \
|
---|
73 | /* h is a pipe in non-blocking mode. \
|
---|
74 | Change errno from EINVAL to EAGAIN. */ \
|
---|
75 | errno = EAGAIN; \
|
---|
76 | } \
|
---|
77 | } \
|
---|
78 | } \
|
---|
79 | } \
|
---|
80 | return ret; \
|
---|
81 | }
|
---|
82 |
|
---|
83 | /* Enable this function definition only if gnulib's <stdio.h> has prepared it.
|
---|
84 | Otherwise we get a function definition conflict with mingw64's <stdio.h>. */
|
---|
85 | # if GNULIB_SCANF
|
---|
86 | int
|
---|
87 | scanf (const char *format, ...)
|
---|
88 | {
|
---|
89 | int retval;
|
---|
90 | va_list args;
|
---|
91 |
|
---|
92 | va_start (args, format);
|
---|
93 | retval = vfscanf (stdin, format, args);
|
---|
94 | va_end (args);
|
---|
95 |
|
---|
96 | return retval;
|
---|
97 | }
|
---|
98 | # endif
|
---|
99 |
|
---|
100 | /* Enable this function definition only if gnulib's <stdio.h> has prepared it.
|
---|
101 | Otherwise we get a function definition conflict with mingw64's <stdio.h>. */
|
---|
102 | # if GNULIB_FSCANF
|
---|
103 | int
|
---|
104 | fscanf (FILE *stream, const char *format, ...)
|
---|
105 | {
|
---|
106 | int retval;
|
---|
107 | va_list args;
|
---|
108 |
|
---|
109 | va_start (args, format);
|
---|
110 | retval = vfscanf (stream, format, args);
|
---|
111 | va_end (args);
|
---|
112 |
|
---|
113 | return retval;
|
---|
114 | }
|
---|
115 | # endif
|
---|
116 |
|
---|
117 | /* Enable this function definition only if gnulib's <stdio.h> has prepared it.
|
---|
118 | Otherwise we get a function definition conflict with mingw64's <stdio.h>. */
|
---|
119 | # if GNULIB_VSCANF
|
---|
120 | int
|
---|
121 | vscanf (const char *format, va_list args)
|
---|
122 | {
|
---|
123 | return vfscanf (stdin, format, args);
|
---|
124 | }
|
---|
125 | # endif
|
---|
126 |
|
---|
127 | /* Enable this function definition only if gnulib's <stdio.h> has prepared it.
|
---|
128 | Otherwise we get a function definition conflict with mingw64's <stdio.h>. */
|
---|
129 | # if GNULIB_VFSCANF
|
---|
130 | int
|
---|
131 | vfscanf (FILE *stream, const char *format, va_list args)
|
---|
132 | #undef vfscanf
|
---|
133 | {
|
---|
134 | CALL_WITH_ERRNO_FIX (int, vfscanf (stream, format, args), ret == EOF)
|
---|
135 | }
|
---|
136 | # endif
|
---|
137 |
|
---|
138 | int
|
---|
139 | getchar (void)
|
---|
140 | {
|
---|
141 | return fgetc (stdin);
|
---|
142 | }
|
---|
143 |
|
---|
144 | int
|
---|
145 | fgetc (FILE *stream)
|
---|
146 | #undef fgetc
|
---|
147 | {
|
---|
148 | CALL_WITH_ERRNO_FIX (int, fgetc (stream), ret == EOF)
|
---|
149 | }
|
---|
150 |
|
---|
151 | char *
|
---|
152 | fgets (char *s, int n, FILE *stream)
|
---|
153 | #undef fgets
|
---|
154 | {
|
---|
155 | CALL_WITH_ERRNO_FIX (char *, fgets (s, n, stream), ret == NULL)
|
---|
156 | }
|
---|
157 |
|
---|
158 | /* We intentionally don't bother to fix gets. */
|
---|
159 |
|
---|
160 | size_t
|
---|
161 | fread (void *ptr, size_t s, size_t n, FILE *stream)
|
---|
162 | #undef fread
|
---|
163 | {
|
---|
164 | CALL_WITH_ERRNO_FIX (size_t, fread (ptr, s, n, stream), ret < n)
|
---|
165 | }
|
---|
166 |
|
---|
167 | # endif
|
---|
168 | #endif
|
---|