pread_write.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. /*
  7. * Based in part on the files
  8. * ./sysdeps/unix/sysv/linux/pwrite.c,
  9. * ./sysdeps/unix/sysv/linux/pread.c,
  10. * sysdeps/posix/pread.c
  11. * sysdeps/posix/pwrite.c
  12. * from GNU libc 2.2.5, but reworked considerably...
  13. */
  14. #include <sys/syscall.h>
  15. #include <unistd.h>
  16. #include <endian.h>
  17. #include <bits/wordsize.h>
  18. #include <cancel.h>
  19. #ifdef __NR_pread64
  20. # undef __NR_pread
  21. # define __NR_pread __NR_pread64
  22. #endif
  23. #ifdef __NR_pwrite64
  24. # undef __NR_pwrite
  25. # define __NR_pwrite __NR_pwrite64
  26. #endif
  27. #ifndef MY_PREAD
  28. # ifdef __NR_pread
  29. # define __NR___syscall_pread __NR_pread
  30. # if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
  31. static _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
  32. size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
  33. # define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF_HI_LO(offset))
  34. # define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF64_HI_LO(offset))
  35. # elif __WORDSIZE == 32
  36. static _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
  37. size_t, count, off_t, offset_hi, off_t, offset_lo)
  38. # define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF_HI_LO(offset))
  39. # define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF64_HI_LO(offset))
  40. # else
  41. static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf,
  42. size_t, count, off_t, offset)
  43. # define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
  44. # define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
  45. # endif
  46. # endif
  47. #endif
  48. #ifndef MY_PWRITE
  49. # ifdef __NR_pwrite
  50. # define __NR___syscall_pwrite __NR_pwrite
  51. # if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
  52. static _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
  53. size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
  54. # define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF_HI_LO(offset))
  55. # define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF64_HI_LO(offset))
  56. # elif __WORDSIZE == 32
  57. static _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
  58. size_t, count, off_t, offset_hi, off_t, offset_lo)
  59. # define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF_HI_LO(offset))
  60. # define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF64_HI_LO(offset))
  61. # else
  62. static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
  63. size_t, count, off_t, offset)
  64. # define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
  65. # define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
  66. # endif
  67. # endif
  68. #endif
  69. static ssize_t __NC(pread)(int fd, void *buf, size_t count, off_t offset)
  70. {
  71. return MY_PREAD(fd, buf, count, offset);
  72. }
  73. CANCELLABLE_SYSCALL(ssize_t, pread, (int fd, void *buf, size_t count, off_t offset),
  74. (fd, buf, count, offset))
  75. static ssize_t __NC(pwrite)(int fd, const void *buf, size_t count, off_t offset)
  76. {
  77. return MY_PWRITE(fd, buf, count, offset);
  78. }
  79. CANCELLABLE_SYSCALL(ssize_t, pwrite, (int fd, const void *buf, size_t count, off_t offset),
  80. (fd, buf, count, offset))
  81. #if __WORDSIZE == 32
  82. static ssize_t __NC(pread64)(int fd, void *buf, size_t count, off64_t offset)
  83. {
  84. return MY_PREAD64(fd, buf, count, offset);
  85. }
  86. CANCELLABLE_SYSCALL(ssize_t, pread64, (int fd, void *buf, size_t count, off64_t offset),
  87. (fd, buf, count, offset))
  88. static ssize_t __NC(pwrite64)(int fd, const void *buf, size_t count, off64_t offset)
  89. {
  90. return MY_PWRITE64(fd, buf, count, offset);
  91. }
  92. CANCELLABLE_SYSCALL(ssize_t, pwrite64, (int fd, const void *buf, size_t count, off64_t offset),
  93. (fd, buf, count, offset))
  94. #else
  95. # ifdef __UCLIBC_HAS_LINUXTHREADS__
  96. weak_alias(pread,pread64)
  97. weak_alias(pwrite,pwrite64)
  98. lt_strong_alias(pread64)
  99. lt_strong_alias(pwrite64)
  100. # else
  101. strong_alias_untyped(pread,pread64)
  102. strong_alias_untyped(pwrite,pwrite64)
  103. # endif
  104. #endif