read.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* POSIX compatible 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 <unistd.h>
  17. #if defined _WIN32 && ! defined __CYGWIN__
  18. # include <errno.h>
  19. # include <io.h>
  20. # define WIN32_LEAN_AND_MEAN /* avoid including junk */
  21. # include <windows.h>
  22. # if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  23. # include "msvc-inval.h"
  24. # endif
  25. # if GNULIB_MSVC_NOTHROW
  26. # include "msvc-nothrow.h"
  27. # else
  28. # include <io.h>
  29. # endif
  30. /* Don't assume that UNICODE is not defined. */
  31. # undef GetNamedPipeHandleState
  32. # define GetNamedPipeHandleState GetNamedPipeHandleStateA
  33. # undef read
  34. # if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  35. static ssize_t
  36. read_nothrow (int fd, void *buf, size_t count)
  37. {
  38. ssize_t result;
  39. TRY_MSVC_INVAL
  40. {
  41. result = _read (fd, buf, count);
  42. }
  43. CATCH_MSVC_INVAL
  44. {
  45. result = -1;
  46. errno = EBADF;
  47. }
  48. DONE_MSVC_INVAL;
  49. return result;
  50. }
  51. # else
  52. # define read_nothrow _read
  53. # endif
  54. ssize_t
  55. rpl_read (int fd, void *buf, size_t count)
  56. {
  57. ssize_t ret = read_nothrow (fd, buf, count);
  58. # if GNULIB_NONBLOCKING
  59. if (ret < 0
  60. && GetLastError () == ERROR_NO_DATA)
  61. {
  62. HANDLE h = (HANDLE) _get_osfhandle (fd);
  63. if (GetFileType (h) == FILE_TYPE_PIPE)
  64. {
  65. /* h is a pipe or socket. */
  66. DWORD state;
  67. if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0)
  68. && (state & PIPE_NOWAIT) != 0)
  69. /* h is a pipe in non-blocking mode.
  70. Change errno from EINVAL to EAGAIN. */
  71. errno = EAGAIN;
  72. }
  73. }
  74. # endif
  75. return ret;
  76. }
  77. #endif