stdio-read.c 5.9 KB

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