3 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
5 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
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...
16 #define _LARGEFILE64_SOURCE
19 /* We absolutely do _NOT_ want interfaces silently
20 * * * renamed under us or very bad things will happen... */
21 #ifdef __USE_FILE_OFFSET64
22 # undef __USE_FILE_OFFSET64
26 #include <sys/types.h>
27 #include <sys/syscall.h>
30 #if ! defined __UCLIBC_HAS_LFS__
35 #define __NR___syscall_pread __NR_pread
36 static inline _syscall4(ssize_t, __syscall_pread, int, fd,
37 void *, buf, size_t, count, off64_t, offset);
39 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
41 return(__syscall_pread(fd, buf, count, (off64_t)offset));
43 strong_alias(__libc_pread,pread)
45 #if defined __UCLIBC_HAS_LFS__
46 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
48 return(__syscall_pread(fd, buf, count, offset));
50 strong_alias(__libc_pread64,pread64)
51 #endif /* __UCLIBC_HAS_LFS__ */
52 #endif /* __NR_pread */
56 #define __NR___syscall_pwrite __NR_pwrite
57 static inline _syscall4(ssize_t, __syscall_pwrite, int, fd,
58 const void *, buf, size_t, count, off64_t, offset);
60 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
62 return(__syscall_pwrite(fd, buf, count, (off64_t)offset));
64 strong_alias(__libc_pwrite,pwrite)
66 #if defined __UCLIBC_HAS_LFS__
67 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
69 return(__syscall_pwrite(fd, buf, count, offset));
71 strong_alias(__libc_pwrite64,pwrite64)
72 #endif /* __UCLIBC_HAS_LFS__ */
73 #endif /* __NR_pwrite */
77 #if ! defined __NR_pread || ! defined __NR_pwrite
78 libc_hidden_proto(read)
79 libc_hidden_proto(write)
80 libc_hidden_proto(lseek)
81 libc_hidden_proto(lseek64)
83 static ssize_t __fake_pread_write(int fd, void *buf,
84 size_t count, off_t offset, int do_pwrite)
90 /* Since we must not change the file pointer preserve the
91 * value so that we can restore it later. */
92 if ((old_offset=lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
95 /* Set to wanted position. */
96 if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
100 /* Write the data. */
101 result = write(fd, buf, count);
104 result = read(fd, buf, count);
107 /* Now we have to restore the position. If this fails we
108 * have to return this as an error. */
110 if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
113 __set_errno(save_errno);
116 __set_errno(save_errno);
120 #if defined __UCLIBC_HAS_LFS__
121 static ssize_t __fake_pread_write64(int fd, void *buf,
122 size_t count, off64_t offset, int do_pwrite)
128 /* Since we must not change the file pointer preserve the
129 * value so that we can restore it later. */
130 if ((old_offset=lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1)
133 /* Set to wanted position. */
134 if (lseek64(fd, offset, SEEK_SET) == (off64_t) -1)
138 /* Write the data. */
139 result = write(fd, buf, count);
142 result = read(fd, buf, count);
145 /* Now we have to restore the position. */
147 if (lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1) {
149 __set_errno (save_errno);
152 __set_errno (save_errno);
155 #endif /* __UCLIBC_HAS_LFS__ */
156 #endif /* ! defined __NR_pread || ! defined __NR_pwrite */
159 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
161 return(__fake_pread_write(fd, buf, count, offset, 0));
163 strong_alias(__libc_pread,pread)
165 #if defined __UCLIBC_HAS_LFS__
166 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
168 return(__fake_pread_write64(fd, buf, count, offset, 0));
170 strong_alias(__libc_pread64,pread64)
171 #endif /* __UCLIBC_HAS_LFS__ */
172 #endif /* ! __NR_pread */
176 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
178 return(__fake_pread_write(fd, buf, count, offset, 1));
180 strong_alias(__libc_pwrite,pwrite)
182 #if defined __UCLIBC_HAS_LFS__
183 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
185 return(__fake_pread_write64(fd, (void*)buf, count, offset, 1));
187 strong_alias(__libc_pwrite64,pwrite64)
188 #endif /* __UCLIBC_HAS_LFS__ */
189 #endif /* ! __NR_pwrite */