safe-read.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* An interface to read and write that retries after interrupts.
  2. Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2021 Free Software
  3. Foundation, Inc.
  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. #ifdef SAFE_WRITE
  17. # include "safe-write.h"
  18. #else
  19. # include "safe-read.h"
  20. #endif
  21. /* Get ssize_t. */
  22. #include <sys/types.h>
  23. #include <unistd.h>
  24. #include <errno.h>
  25. #ifdef EINTR
  26. # define IS_EINTR(x) ((x) == EINTR)
  27. #else
  28. # define IS_EINTR(x) 0
  29. #endif
  30. #include "sys-limits.h"
  31. #ifdef SAFE_WRITE
  32. # define safe_rw safe_write
  33. # define rw write
  34. #else
  35. # define safe_rw safe_read
  36. # define rw read
  37. # undef const
  38. # define const /* empty */
  39. #endif
  40. /* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
  41. interrupted. Return the actual number of bytes read(written), zero for EOF,
  42. or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */
  43. size_t
  44. safe_rw (int fd, void const *buf, size_t count)
  45. {
  46. for (;;)
  47. {
  48. ssize_t result = rw (fd, buf, count);
  49. if (0 <= result)
  50. return result;
  51. else if (IS_EINTR (errno))
  52. continue;
  53. else if (errno == EINVAL && SYS_BUFSIZE_MAX < count)
  54. count = SYS_BUFSIZE_MAX;
  55. else
  56. return result;
  57. }
  58. }