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 
16 #include <sys/syscall.h>
17 #include <unistd.h>
18 #include <endian.h>
19 #include <bits/wordsize.h>
20 #include <cancel.h>
21 
22 #ifdef __NR_pread64
23 # undef __NR_pread
24 # define __NR_pread __NR_pread64
25 #endif
26 #ifdef __NR_pwrite64
27 # undef __NR_pwrite
28 # define __NR_pwrite __NR_pwrite64
29 #endif
30 
31 #ifndef MY_PREAD
32 # ifdef __NR_pread
33 #  define __NR___syscall_pread __NR_pread
34 #  if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
_syscall6(ssize_t,__syscall_pread,int,fd,void *,buf,size_t,count,int,dummy,off_t,offset_hi,off_t,offset_lo)35 static _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
36 		 size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
37 #   define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF_HI_LO(offset))
38 #   define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF64_HI_LO(offset))
39 #  elif __WORDSIZE == 32
40 static _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
41 		 size_t, count, off_t, offset_hi, off_t, offset_lo)
42 #   define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF_HI_LO(offset))
43 #   define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF64_HI_LO(offset))
44 #  else
45 static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf,
46 		 size_t, count, off_t, offset)
47 #   define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
48 #   define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset)
49 #  endif
50 # endif
51 #endif
52 
53 #ifndef MY_PWRITE
54 # ifdef __NR_pwrite
55 #  define __NR___syscall_pwrite __NR_pwrite
56 #  if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__)
57 static _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
58 		 size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo)
59 #   define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF_HI_LO(offset))
60 #   define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF64_HI_LO(offset))
61 #  elif __WORDSIZE == 32
62 static _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
63 		 size_t, count, off_t, offset_hi, off_t, offset_lo)
64 #   define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF_HI_LO(offset))
65 #   define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF64_HI_LO(offset))
66 #  else
67 static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
68 		 size_t, count, off_t, offset)
69 #   define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
70 #   define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset)
71 #  endif
72 # endif
73 #endif
74 
75 static ssize_t __NC(pread)(int fd, void *buf, size_t count, off_t offset)
76 {
77 	return MY_PREAD(fd, buf, count, offset);
78 }
79 CANCELLABLE_SYSCALL(ssize_t, pread, (int fd, void *buf, size_t count, off_t offset),
80 		    (fd, buf, count, offset))
81 
__NC(pwrite)82 static ssize_t __NC(pwrite)(int fd, const void *buf, size_t count, off_t offset)
83 {
84 	return MY_PWRITE(fd, buf, count, offset);
85 }
86 CANCELLABLE_SYSCALL(ssize_t, pwrite, (int fd, const void *buf, size_t count, off_t offset),
87 		    (fd, buf, count, offset))
88 
89 #ifdef __UCLIBC_HAS_LFS__
90 # if __WORDSIZE == 32
__NC(pread64)91 static ssize_t __NC(pread64)(int fd, void *buf, size_t count, off64_t offset)
92 {
93 	return MY_PREAD64(fd, buf, count, offset);
94 }
95 CANCELLABLE_SYSCALL(ssize_t, pread64, (int fd, void *buf, size_t count, off64_t offset),
96 		    (fd, buf, count, offset))
97 
__NC(pwrite64)98 static ssize_t __NC(pwrite64)(int fd, const void *buf, size_t count, off64_t offset)
99 {
100 	return MY_PWRITE64(fd, buf, count, offset);
101 }
102 CANCELLABLE_SYSCALL(ssize_t, pwrite64, (int fd, const void *buf, size_t count, off64_t offset),
103 		    (fd, buf, count, offset))
104 # else
105 #  ifdef __LINUXTHREADS_OLD__
106 weak_alias(pread,pread64)
107 weak_alias(pwrite,pwrite64)
108 lt_strong_alias(pread64)
109 lt_strong_alias(pwrite64)
110 #  else
111 strong_alias_untyped(pread,pread64)
112 strong_alias_untyped(pwrite,pwrite64)
113 #  endif
114 # endif
115 #endif
116