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...
15 #include <sys/syscall.h>
18 #ifndef __UCLIBC_HAS_LFS__
19 # define off64_t off_t
23 extern __typeof(pread) __libc_pread;
24 # define __NR___syscall_pread __NR_pread
25 static inline _syscall4(ssize_t, __syscall_pread, int, fd,
26 void *, buf, size_t, count, off64_t, offset);
28 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
30 return(__syscall_pread(fd, buf, count, (off64_t)offset));
32 weak_alias(__libc_pread,pread)
34 # ifdef __UCLIBC_HAS_LFS__
35 extern __typeof(pread64) __libc_pread64;
36 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
38 return(__syscall_pread(fd, buf, count, offset));
40 weak_alias(__libc_pread64,pread64)
41 # endif /* __UCLIBC_HAS_LFS__ */
42 #endif /* __NR_pread */
46 extern __typeof(pwrite) __libc_pwrite;
47 # define __NR___syscall_pwrite __NR_pwrite
48 static inline _syscall4(ssize_t, __syscall_pwrite, int, fd,
49 const void *, buf, size_t, count, off64_t, offset);
51 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
53 return(__syscall_pwrite(fd, buf, count, (off64_t)offset));
55 weak_alias(__libc_pwrite,pwrite)
57 # ifdef __UCLIBC_HAS_LFS__
58 extern __typeof(pwrite64) __libc_pwrite64;
59 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
61 return(__syscall_pwrite(fd, buf, count, offset));
63 weak_alias(__libc_pwrite64,pwrite64)
64 # endif /* __UCLIBC_HAS_LFS__ */
65 #endif /* __NR_pwrite */
69 #if ! defined __NR_pread || ! defined __NR_pwrite
70 libc_hidden_proto(read)
71 libc_hidden_proto(write)
72 libc_hidden_proto(lseek)
74 static ssize_t __fake_pread_write(int fd, void *buf,
75 size_t count, off_t offset, int do_pwrite)
81 /* Since we must not change the file pointer preserve the
82 * value so that we can restore it later. */
83 if ((old_offset=lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
86 /* Set to wanted position. */
87 if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
92 result = write(fd, buf, count);
95 result = read(fd, buf, count);
98 /* Now we have to restore the position. If this fails we
99 * have to return this as an error. */
101 if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
104 __set_errno(save_errno);
107 __set_errno(save_errno);
111 # ifdef __UCLIBC_HAS_LFS__
112 libc_hidden_proto(lseek64)
114 static ssize_t __fake_pread_write64(int fd, void *buf,
115 size_t count, off64_t offset, int do_pwrite)
121 /* Since we must not change the file pointer preserve the
122 * value so that we can restore it later. */
123 if ((old_offset=lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1)
126 /* Set to wanted position. */
127 if (lseek64(fd, offset, SEEK_SET) == (off64_t) -1)
131 /* Write the data. */
132 result = write(fd, buf, count);
135 result = read(fd, buf, count);
138 /* Now we have to restore the position. */
140 if (lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1) {
142 __set_errno (save_errno);
145 __set_errno (save_errno);
148 # endif /* __UCLIBC_HAS_LFS__ */
149 #endif /* ! defined __NR_pread || ! defined __NR_pwrite */
152 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
154 return(__fake_pread_write(fd, buf, count, offset, 0));
156 weak_alias(__libc_pread,pread)
158 # ifdef __UCLIBC_HAS_LFS__
159 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
161 return(__fake_pread_write64(fd, buf, count, offset, 0));
163 weak_alias(__libc_pread64,pread64)
164 # endif /* __UCLIBC_HAS_LFS__ */
165 #endif /* ! __NR_pread */
169 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
171 return(__fake_pread_write(fd, (void*)buf, count, offset, 1));
173 weak_alias(__libc_pwrite,pwrite)
175 # ifdef __UCLIBC_HAS_LFS__
176 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
178 return(__fake_pread_write64(fd, (void*)buf, count, offset, 1));
180 weak_alias(__libc_pwrite64,pwrite64)
181 # endif /* __UCLIBC_HAS_LFS__ */
182 #endif /* ! __NR_pwrite */