comparison lib/stdio.in.h @ 14583:8b22057e98d2

Support non-blocking pipe I/O in read() on native Windows. * lib/unistd.in.h: Include <sys/types.h> also for 'read'. (read): New declaration. * lib/read.c: New file. * lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT_SCANF, _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM): New macros. (fgetc, fgets, fread, fscanf, getc, getchar, gets, scanf, vfscanf, vscanf): New declarations. * lib/stdio-read.c: New file. * m4/read.m4: New file. * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_READ, REPLACE_READ. * m4/stdio_h.m4 (gl_STDIO_H): Set GNULIB_FGETC, GNULIB_FGETS, GNULIB_FREAD, GNULIB_FSCANF, GNULIB_GETC, GNULIB_GETCHAR, GNULIB_GETS, GNULIB_SCANF, GNULIB_VFSCANF, GNULIB_VSCANF. In non-blocking I/O is desired and needs workarounds, set REPLACE_STDIO_READ_FUNCS. (gl_STDIO_H_DEFAULTS): Initialize GNULIB_FGETC, GNULIB_FGETS, GNULIB_FREAD, GNULIB_FSCANF, GNULIB_GETC, GNULIB_GETCHAR, GNULIB_GETS, GNULIB_SCANF, GNULIB_VFSCANF, GNULIB_VSCANF, REPLACE_STDIO_READ_FUNCS. * modules/read: New file. * modules/nonblocking (Files): Add lib/stdio-read.c. * modules/unistd (Makefile.am): Substitute GNULIB_READ, REPLACE_READ. * modules/stdio (Makefile.am): Substitute GNULIB_FGETC, GNULIB_FGETS, GNULIB_FREAD, GNULIB_FSCANF, GNULIB_GETC, GNULIB_GETCHAR, GNULIB_GETS, GNULIB_SCANF, GNULIB_VFSCANF, GNULIB_VSCANF, REPLACE_STDIO_READ_FUNCS. * modules/pread (Depends-on): Add read. * modules/safe-read (Depends-on): Likewise. * tests/test-stdio-c++.cc (fgetc, fgets, fread, fscanf, getc, getchar, gets, scanf, vfscanf, vscanf): Verify signatures. * doc/posix-functions/read.texi: Mention 'nonblocking' module and problem with non-blocking pipes. * doc/posix-functions/fgetc.texi: Likewise. * doc/posix-functions/fgets.texi: Likewise. * doc/posix-functions/fread.texi: Likewise. * doc/posix-functions/fscanf.texi: Likewise. * doc/posix-functions/getc.texi: Likewise. * doc/posix-functions/getchar.texi: Likewise. * doc/posix-functions/gets.texi: Likewise. * doc/posix-functions/scanf.texi: Likewise. * doc/posix-functions/vfscanf.texi: Likewise. * doc/posix-functions/vscanf.texi: Likewise.
author Bruno Haible <bruno@clisp.org>
date Fri, 15 Apr 2011 01:02:13 +0200
parents 4e83bc0de9e4
children 5f709022a256
comparison
equal deleted inserted replaced
14582:3a41e32d28ab 14583:8b22057e98d2
85 are the ones of the system printf(), rather than the ones standardized by 85 are the ones of the system printf(), rather than the ones standardized by
86 ISO C99 and POSIX. */ 86 ISO C99 and POSIX. */
87 #define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ 87 #define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
88 _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) 88 _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument))
89 89
90 /* _GL_ATTRIBUTE_FORMAT_SCANF
91 indicates to GCC that the function takes a format string and arguments,
92 where the format string directives are the ones standardized by ISO C99
93 and POSIX. */
94 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
95 # define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \
96 _GL_ATTRIBUTE_FORMAT ((__gnu_scanf__, formatstring_parameter, first_argument))
97 #else
98 # define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \
99 _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument))
100 #endif
101
102 /* _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_SCANF,
103 except that it indicates to GCC that the supported format string directives
104 are the ones of the system scanf(), rather than the ones standardized by
105 ISO C99 and POSIX. */
106 #define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \
107 _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument))
108
90 /* Solaris 10 declares renameat in <unistd.h>, not in <stdio.h>. */ 109 /* Solaris 10 declares renameat in <unistd.h>, not in <stdio.h>. */
91 /* But in any case avoid namespace pollution on glibc systems. */ 110 /* But in any case avoid namespace pollution on glibc systems. */
92 #if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ 111 #if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \
93 && ! defined __GLIBC__ 112 && ! defined __GLIBC__
94 # include <unistd.h> 113 # include <unistd.h>
173 /* Assume fflush is always declared. */ 192 /* Assume fflush is always declared. */
174 _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " 193 _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - "
175 "use gnulib module fflush for portable POSIX compliance"); 194 "use gnulib module fflush for portable POSIX compliance");
176 #endif 195 #endif
177 196
178 /* It is very rare that the developer ever has full control of stdin, 197 #if @GNULIB_FGETC@
179 so any use of gets warrants an unconditional warning. Assume it is 198 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
180 always declared, since it is required by C89. */ 199 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
181 #undef gets 200 # undef fgetc
182 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); 201 # define fgetc rpl_fgetc
202 # endif
203 _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1)));
204 _GL_CXXALIAS_RPL (fgetc, int, (FILE *stream));
205 # else
206 _GL_CXXALIAS_SYS (fgetc, int, (FILE *stream));
207 # endif
208 _GL_CXXALIASWARN (fgetc);
209 #endif
210
211 #if @GNULIB_FGETS@
212 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
213 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
214 # undef fgets
215 # define fgets rpl_fgets
216 # endif
217 _GL_FUNCDECL_RPL (fgets, char *, (char *s, int n, FILE *stream)
218 _GL_ARG_NONNULL ((1, 3)));
219 _GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream));
220 # else
221 _GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream));
222 # endif
223 _GL_CXXALIASWARN (fgets);
224 #endif
183 225
184 #if @GNULIB_FOPEN@ 226 #if @GNULIB_FOPEN@
185 # if @REPLACE_FOPEN@ 227 # if @REPLACE_FOPEN@
186 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 228 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
187 # undef fopen 229 # undef fopen
288 _GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); 330 _GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream));
289 # endif 331 # endif
290 _GL_CXXALIASWARN (fputs); 332 _GL_CXXALIASWARN (fputs);
291 #endif 333 #endif
292 334
335 #if @GNULIB_FREAD@
336 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
337 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
338 # undef fread
339 # define fread rpl_fread
340 # endif
341 _GL_FUNCDECL_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)
342 _GL_ARG_NONNULL ((4)));
343 _GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream));
344 # else
345 _GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream));
346 # endif
347 _GL_CXXALIASWARN (fread);
348 #endif
349
293 #if @GNULIB_FREOPEN@ 350 #if @GNULIB_FREOPEN@
294 # if @REPLACE_FREOPEN@ 351 # if @REPLACE_FREOPEN@
295 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 352 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
296 # undef freopen 353 # undef freopen
297 # define freopen rpl_freopen 354 # define freopen rpl_freopen
310 # undef freopen 367 # undef freopen
311 /* Assume freopen is always declared. */ 368 /* Assume freopen is always declared. */
312 _GL_WARN_ON_USE (freopen, 369 _GL_WARN_ON_USE (freopen,
313 "freopen on Win32 platforms is not POSIX compatible - " 370 "freopen on Win32 platforms is not POSIX compatible - "
314 "use gnulib module freopen for portability"); 371 "use gnulib module freopen for portability");
372 #endif
373
374 #if @GNULIB_FSCANF@
375 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
376 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
377 # undef fscanf
378 # define fscanf rpl_fscanf
379 # endif
380 _GL_FUNCDECL_RPL (fscanf, int, (FILE *stream, const char *format, ...)
381 _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3)
382 _GL_ARG_NONNULL ((1, 2)));
383 _GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...));
384 # else
385 _GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...));
386 # endif
387 _GL_CXXALIASWARN (fscanf);
315 #endif 388 #endif
316 389
317 390
318 /* Set up the following warnings, based on which modules are in use. 391 /* Set up the following warnings, based on which modules are in use.
319 GNU Coding Standards discourage the use of fseek, since it imposes 392 GNU Coding Standards discourage the use of fseek, since it imposes
538 # endif 611 # endif
539 # endif 612 # endif
540 _GL_CXXALIASWARN (fwrite); 613 _GL_CXXALIASWARN (fwrite);
541 #endif 614 #endif
542 615
616 #if @GNULIB_GETC@
617 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
618 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
619 # undef getc
620 # define getc rpl_fgetc
621 # endif
622 _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1)));
623 _GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream));
624 # else
625 _GL_CXXALIAS_SYS (getc, int, (FILE *stream));
626 # endif
627 _GL_CXXALIASWARN (getc);
628 #endif
629
630 #if @GNULIB_GETCHAR@
631 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
632 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
633 # undef getchar
634 # define getchar rpl_getchar
635 # endif
636 _GL_FUNCDECL_RPL (getchar, int, (void));
637 _GL_CXXALIAS_RPL (getchar, int, (void));
638 # else
639 _GL_CXXALIAS_SYS (getchar, int, (void));
640 # endif
641 _GL_CXXALIASWARN (getchar);
642 #endif
643
543 #if @GNULIB_GETDELIM@ 644 #if @GNULIB_GETDELIM@
544 /* Read input, up to (and including) the next occurrence of DELIMITER, from 645 /* Read input, up to (and including) the next occurrence of DELIMITER, from
545 STREAM, store it in *LINEPTR (and NUL-terminate it). 646 STREAM, store it in *LINEPTR (and NUL-terminate it).
546 *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE 647 *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
547 bytes of space. It is realloc'd as necessary. 648 bytes of space. It is realloc'd as necessary.
613 # if HAVE_RAW_DECL_GETLINE 714 # if HAVE_RAW_DECL_GETLINE
614 _GL_WARN_ON_USE (getline, "getline is unportable - " 715 _GL_WARN_ON_USE (getline, "getline is unportable - "
615 "use gnulib module getline for portability"); 716 "use gnulib module getline for portability");
616 # endif 717 # endif
617 #endif 718 #endif
719
720 #if @GNULIB_GETS@
721 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
722 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
723 # undef gets
724 # define gets rpl_gets
725 # endif
726 _GL_FUNCDECL_RPL (gets, char *, (char *s) _GL_ARG_NONNULL ((1)));
727 _GL_CXXALIAS_RPL (gets, char *, (char *s));
728 # else
729 _GL_CXXALIAS_SYS (gets, char *, (char *s));
730 # undef gets
731 # endif
732 _GL_CXXALIASWARN (gets);
733 /* It is very rare that the developer ever has full control of stdin,
734 so any use of gets warrants an unconditional warning. Assume it is
735 always declared, since it is required by C89. */
736 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
737 #endif
738
618 739
619 #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ 740 #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
620 struct obstack; 741 struct obstack;
621 /* Grow an obstack with formatted output. Return the number of 742 /* Grow an obstack with formatted output. Return the number of
622 bytes added to OBS. No trailing nul byte is added, and the 743 bytes added to OBS. No trailing nul byte is added, and the
870 _GL_WARN_ON_USE (renameat, "renameat is not portable - " 991 _GL_WARN_ON_USE (renameat, "renameat is not portable - "
871 "use gnulib module renameat for portability"); 992 "use gnulib module renameat for portability");
872 # endif 993 # endif
873 #endif 994 #endif
874 995
996 #if @GNULIB_SCANF@
997 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
998 # if defined __GNUC__
999 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1000 # undef scanf
1001 /* Don't break __attribute__((format(scanf,M,N))). */
1002 # define scanf __scanf__
1003 # endif
1004 _GL_FUNCDECL_RPL_1 (__scanf__, int,
1005 (const char *format, ...)
1006 __asm__ (@ASM_SYMBOL_PREFIX@
1007 _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf))
1008 _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2)
1009 _GL_ARG_NONNULL ((1)));
1010 _GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...));
1011 # else
1012 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1013 # undef scanf
1014 # define scanf rpl_scanf
1015 # endif
1016 _GL_FUNCDECL_RPL (scanf, int, (const char *format, ...)
1017 _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2)
1018 _GL_ARG_NONNULL ((1)));
1019 _GL_CXXALIAS_RPL (scanf, int, (const char *format, ...));
1020 # endif
1021 # else
1022 _GL_CXXALIAS_SYS (scanf, int, (const char *format, ...));
1023 # endif
1024 _GL_CXXALIASWARN (scanf);
1025 #endif
1026
875 #if @GNULIB_SNPRINTF@ 1027 #if @GNULIB_SNPRINTF@
876 # if @REPLACE_SNPRINTF@ 1028 # if @REPLACE_SNPRINTF@
877 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 1029 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
878 # define snprintf rpl_snprintf 1030 # define snprintf rpl_snprintf
879 # endif 1031 # endif
1063 _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " 1215 _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - "
1064 "use gnulib module vfprintf-posix for portable " 1216 "use gnulib module vfprintf-posix for portable "
1065 "POSIX compliance"); 1217 "POSIX compliance");
1066 #endif 1218 #endif
1067 1219
1220 #if @GNULIB_VFSCANF@
1221 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
1222 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1223 # undef vfscanf
1224 # define vfscanf rpl_vfscanf
1225 # endif
1226 _GL_FUNCDECL_RPL (vfscanf, int,
1227 (FILE *stream, const char *format, va_list args)
1228 _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0)
1229 _GL_ARG_NONNULL ((1, 2)));
1230 _GL_CXXALIAS_RPL (vfscanf, int,
1231 (FILE *stream, const char *format, va_list args));
1232 # else
1233 _GL_CXXALIAS_SYS (vfscanf, int,
1234 (FILE *stream, const char *format, va_list args));
1235 # endif
1236 _GL_CXXALIASWARN (vfscanf);
1237 #endif
1238
1068 #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ 1239 #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@
1069 # if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ 1240 # if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \
1070 || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) 1241 || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@))
1071 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 1242 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1072 # define vprintf rpl_vprintf 1243 # define vprintf rpl_vprintf
1098 _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " 1269 _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - "
1099 "use gnulib module vprintf-posix for portable " 1270 "use gnulib module vprintf-posix for portable "
1100 "POSIX compliance"); 1271 "POSIX compliance");
1101 #endif 1272 #endif
1102 1273
1274 #if @GNULIB_VSCANF@
1275 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
1276 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1277 # undef vscanf
1278 # define vscanf rpl_vscanf
1279 # endif
1280 _GL_FUNCDECL_RPL (vscanf, int, (const char *format, va_list args)
1281 _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0)
1282 _GL_ARG_NONNULL ((1)));
1283 _GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args));
1284 # else
1285 _GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args));
1286 # endif
1287 _GL_CXXALIASWARN (vscanf);
1288 #endif
1289
1103 #if @GNULIB_VSNPRINTF@ 1290 #if @GNULIB_VSNPRINTF@
1104 # if @REPLACE_VSNPRINTF@ 1291 # if @REPLACE_VSNPRINTF@
1105 # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 1292 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
1106 # define vsnprintf rpl_vsnprintf 1293 # define vsnprintf rpl_vsnprintf
1107 # endif 1294 # endif