lib.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <unistd.h>
  3. #include <stdbool.h>
  4. #include <errno.h>
  5. #include <linux/kernel.h>
  6. #include <internal/lib.h>
  7. unsigned int page_size;
  8. static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
  9. {
  10. void *buf_start = buf;
  11. size_t left = n;
  12. while (left) {
  13. /* buf must be treated as const if !is_read. */
  14. ssize_t ret = is_read ? read(fd, buf, left) :
  15. write(fd, buf, left);
  16. if (ret < 0 && errno == EINTR)
  17. continue;
  18. if (ret <= 0)
  19. return ret;
  20. left -= ret;
  21. buf += ret;
  22. }
  23. BUG_ON((size_t)(buf - buf_start) != n);
  24. return n;
  25. }
  26. /*
  27. * Read exactly 'n' bytes or return an error.
  28. */
  29. ssize_t readn(int fd, void *buf, size_t n)
  30. {
  31. return ion(true, fd, buf, n);
  32. }
  33. ssize_t preadn(int fd, void *buf, size_t n, off_t offs)
  34. {
  35. size_t left = n;
  36. while (left) {
  37. ssize_t ret = pread(fd, buf, left, offs);
  38. if (ret < 0 && errno == EINTR)
  39. continue;
  40. if (ret <= 0)
  41. return ret;
  42. left -= ret;
  43. buf += ret;
  44. offs += ret;
  45. }
  46. return n;
  47. }
  48. /*
  49. * Write exactly 'n' bytes or return an error.
  50. */
  51. ssize_t writen(int fd, const void *buf, size_t n)
  52. {
  53. /* ion does not modify buf. */
  54. return ion(false, fd, (void *)buf, n);
  55. }