read.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* POSIX compatible read() function.
  2. Copyright (C) 2008-2013 Free Software Foundation, Inc.
  3. Written by Bruno Haible <bruno@clisp.org>, 2011.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program 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 <http://www.gnu.org/licenses/>. */
  14. #include <config.h>
  15. /* Specification. */
  16. #include <unistd.h>
  17. #if (defined _WIN32 || 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. # include "msvc-inval.h"
  23. # include "msvc-nothrow.h"
  24. # undef read
  25. # if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  26. static ssize_t
  27. read_nothrow (int fd, void *buf, size_t count)
  28. {
  29. ssize_t result;
  30. TRY_MSVC_INVAL
  31. {
  32. result = read (fd, buf, count);
  33. }
  34. CATCH_MSVC_INVAL
  35. {
  36. result = -1;
  37. errno = EBADF;
  38. }
  39. DONE_MSVC_INVAL;
  40. return result;
  41. }
  42. # else
  43. # define read_nothrow read
  44. # endif
  45. ssize_t
  46. rpl_read (int fd, void *buf, size_t count)
  47. {
  48. ssize_t ret = read_nothrow (fd, buf, count);
  49. # if GNULIB_NONBLOCKING
  50. if (ret < 0
  51. && GetLastError () == ERROR_NO_DATA)
  52. {
  53. HANDLE h = (HANDLE) _get_osfhandle (fd);
  54. if (GetFileType (h) == FILE_TYPE_PIPE)
  55. {
  56. /* h is a pipe or socket. */
  57. DWORD state;
  58. if (GetNamedPipeHandleState (h, &state, NULL, NULL, 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. # endif
  66. return ret;
  67. }
  68. #endif