pread_write.c 2.7 KB

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