OSDN Git Service

Convert all users of earlier hiddens
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / powerpc / pread_write.c
1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org>
4  * Based in part on the files
5  *              ./sysdeps/unix/sysv/linux/pwrite.c,
6  *              ./sysdeps/unix/sysv/linux/pread.c, 
7  *              sysdeps/posix/pread.c
8  *              sysdeps/posix/pwrite.c
9  * from GNU libc 2.2.5, but reworked considerably...
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU Library General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at your
14  * option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
19  * for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  */
25
26 #define _GNU_SOURCE
27 #define _LARGEFILE64_SOURCE
28 #include <features.h>
29 #undef __OPTIMIZE__
30 /* We absolutely do _NOT_ want interfaces silently
31  *  *  * renamed under us or very bad things will happen... */
32 #ifdef __USE_FILE_OFFSET64
33 # undef __USE_FILE_OFFSET64
34 #endif
35
36
37 #include <errno.h>
38 #include <sys/types.h>
39 #include <sys/syscall.h>
40 #include <unistd.h>
41
42 #if ! defined __UCLIBC_HAS_LFS__ 
43 #define off64_t off_t
44 #endif
45
46 #ifdef __NR_pread
47 #define __NR___syscall_pread __NR_pread 
48 static inline _syscall4(ssize_t, __syscall_pread, int, fd, 
49                 void *, buf, size_t, count, off64_t, offset);
50
51 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
52
53         return(__syscall_pread(fd, buf, count, (off64_t)offset));
54 }
55 weak_alias (__libc_pread, pread)
56
57 #if defined __UCLIBC_HAS_LFS__ 
58 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
59
60         return(__syscall_pread(fd, buf, count, offset));
61 }
62 weak_alias (__libc_pread64, pread64)
63 #endif /* __UCLIBC_HAS_LFS__  */
64 #endif /* __NR_pread */
65
66
67 #ifdef __NR_pwrite
68 #define __NR___syscall_pwrite __NR_pwrite 
69 static inline _syscall4(ssize_t, __syscall_pwrite, int, fd, 
70                 const void *, buf, size_t, count, off64_t, offset);
71
72 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
73
74         return(__syscall_pwrite(fd, buf, count, (off64_t)offset));
75 }
76 weak_alias (__libc_pwrite, pwrite)
77
78 #if defined __UCLIBC_HAS_LFS__ 
79 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
80
81         return(__syscall_pwrite(fd, buf, count, offset));
82 }
83 weak_alias (__libc_pwrite64, pwrite64)
84 #endif /* __UCLIBC_HAS_LFS__  */
85 #endif /* __NR_pwrite */
86
87
88
89 #if ! defined __NR_pread || ! defined __NR_pwrite
90 static ssize_t __fake_pread_write(int fd, void *buf, 
91                 size_t count, off_t offset, int do_pwrite)
92 {
93         int save_errno;
94         ssize_t result;
95         off_t old_offset;
96
97         /* Since we must not change the file pointer preserve the 
98          * value so that we can restore it later.  */
99         if ((old_offset=__lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
100                 return -1;
101
102         /* Set to wanted position.  */
103         if (__lseek (fd, offset, SEEK_SET) == (off_t) -1)
104                 return -1;
105
106         if (do_pwrite==1) {
107                 /* Write the data.  */
108                 result = write(fd, buf, count);
109         } else {
110                 /* Read the data.  */
111                 result = read(fd, buf, count);
112         }
113
114         /* Now we have to restore the position.  If this fails we 
115          * have to return this as an error.  */
116         save_errno = errno;
117         if (__lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
118         {
119                 if (result == -1)
120                         __set_errno(save_errno);
121                 return -1;
122         }
123         __set_errno(save_errno);
124         return(result);
125 }
126
127 #if defined __UCLIBC_HAS_LFS__ 
128 static ssize_t __fake_pread_write64(int fd, void *buf, 
129                 size_t count, off64_t offset, int do_pwrite)
130 {
131         int save_errno;
132         ssize_t result;
133         off64_t old_offset;
134
135         /* Since we must not change the file pointer preserve the 
136          * value so that we can restore it later.  */
137         if ((old_offset=__lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1)
138                 return -1;
139
140         /* Set to wanted position.  */
141         if (__lseek64(fd, offset, SEEK_SET) == (off64_t) -1) 
142                 return -1;                               
143
144         if (do_pwrite==1) {
145                 /* Write the data.  */
146                 result = write(fd, buf, count);
147         } else {
148                 /* Read the data.  */
149                 result = read(fd, buf, count);
150         }
151
152         /* Now we have to restore the position. */
153         save_errno = errno;
154         if (__lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1) {
155                 if (result == -1)
156                         __set_errno (save_errno);
157                 return -1;
158         }
159         __set_errno (save_errno);
160         return result;
161 }
162 #endif /* __UCLIBC_HAS_LFS__  */
163 #endif /*  ! defined __NR_pread || ! defined __NR_pwrite */
164
165 #ifndef __NR_pread
166 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
167 {
168         return(__fake_pread_write(fd, buf, count, offset, 0));
169 }
170 weak_alias (__libc_pread, pread)
171
172 #if defined __UCLIBC_HAS_LFS__ 
173 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
174
175         return(__fake_pread_write64(fd, buf, count, offset, 0));
176 }
177 weak_alias (__libc_pread64, pread64)
178 #endif /* __UCLIBC_HAS_LFS__  */
179 #endif /* ! __NR_pread */
180
181
182 #ifndef __NR_pwrite
183 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
184 {
185         return(__fake_pread_write(fd, buf, count, offset, 1));
186 }
187 weak_alias (__libc_pwrite, pwrite)
188
189 #if defined __UCLIBC_HAS_LFS__ 
190 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
191
192         return(__fake_pread_write64(fd, (void*)buf, count, offset, 1));
193 }
194 weak_alias (__libc_pwrite64, pwrite64)
195 #endif /* __UCLIBC_HAS_LFS__  */
196 #endif /* ! __NR_pwrite */
197