OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[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 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/syscall.h>
39 #include <unistd.h>
40
41 #if ! defined __UCLIBC_HAS_LFS__ 
42 #define off64_t off_t
43 #endif
44
45 #ifdef __NR_pread
46 #define __NR___syscall_pread __NR_pread 
47 static inline _syscall4(ssize_t, __syscall_pread, int, fd, 
48                 void *, buf, size_t, count, off64_t, offset);
49
50 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
51
52         return(__syscall_pread(fd, buf, count, (off64_t)offset));
53 }
54 strong_alias(__libc_pread,pread)
55
56 #if defined __UCLIBC_HAS_LFS__ 
57 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
58
59         return(__syscall_pread(fd, buf, count, offset));
60 }
61 strong_alias(__libc_pread64,pread64)
62 #endif /* __UCLIBC_HAS_LFS__  */
63 #endif /* __NR_pread */
64
65
66 #ifdef __NR_pwrite
67 #define __NR___syscall_pwrite __NR_pwrite 
68 static inline _syscall4(ssize_t, __syscall_pwrite, int, fd, 
69                 const void *, buf, size_t, count, off64_t, offset);
70
71 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
72
73         return(__syscall_pwrite(fd, buf, count, (off64_t)offset));
74 }
75 strong_alias(__libc_pwrite,pwrite)
76
77 #if defined __UCLIBC_HAS_LFS__ 
78 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
79
80         return(__syscall_pwrite(fd, buf, count, offset));
81 }
82 strong_alias(__libc_pwrite64,pwrite64)
83 #endif /* __UCLIBC_HAS_LFS__  */
84 #endif /* __NR_pwrite */
85
86
87
88 #if ! defined __NR_pread || ! defined __NR_pwrite
89 libc_hidden_proto(lseek)
90 libc_hidden_proto(lseek64)
91 libc_hidden_proto(read)
92 libc_hidden_proto(write)
93
94 static ssize_t __fake_pread_write(int fd, void *buf, 
95                 size_t count, off_t offset, int do_pwrite)
96 {
97         int save_errno;
98         ssize_t result;
99         off_t old_offset;
100
101         /* Since we must not change the file pointer preserve the 
102          * value so that we can restore it later.  */
103         if ((old_offset=lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
104                 return -1;
105
106         /* Set to wanted position.  */
107         if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
108                 return -1;
109
110         if (do_pwrite==1) {
111                 /* Write the data.  */
112                 result = write(fd, buf, count);
113         } else {
114                 /* Read the data.  */
115                 result = read(fd, buf, count);
116         }
117
118         /* Now we have to restore the position.  If this fails we 
119          * have to return this as an error.  */
120         save_errno = errno;
121         if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
122         {
123                 if (result == -1)
124                         __set_errno(save_errno);
125                 return -1;
126         }
127         __set_errno(save_errno);
128         return(result);
129 }
130
131 #if defined __UCLIBC_HAS_LFS__ 
132 static ssize_t __fake_pread_write64(int fd, void *buf, 
133                 size_t count, off64_t offset, int do_pwrite)
134 {
135         int save_errno;
136         ssize_t result;
137         off64_t old_offset;
138
139         /* Since we must not change the file pointer preserve the 
140          * value so that we can restore it later.  */
141         if ((old_offset=lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1)
142                 return -1;
143
144         /* Set to wanted position.  */
145         if (lseek64(fd, offset, SEEK_SET) == (off64_t) -1) 
146                 return -1;                               
147
148         if (do_pwrite==1) {
149                 /* Write the data.  */
150                 result = write(fd, buf, count);
151         } else {
152                 /* Read the data.  */
153                 result = read(fd, buf, count);
154         }
155
156         /* Now we have to restore the position. */
157         save_errno = errno;
158         if (lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1) {
159                 if (result == -1)
160                         __set_errno (save_errno);
161                 return -1;
162         }
163         __set_errno (save_errno);
164         return result;
165 }
166 #endif /* __UCLIBC_HAS_LFS__  */
167 #endif /*  ! defined __NR_pread || ! defined __NR_pwrite */
168
169 #ifndef __NR_pread
170 ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
171 {
172         return(__fake_pread_write(fd, buf, count, offset, 0));
173 }
174 strong_alias(__libc_pread,pread)
175
176 #if defined __UCLIBC_HAS_LFS__ 
177 ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
178
179         return(__fake_pread_write64(fd, buf, count, offset, 0));
180 }
181 strong_alias(__libc_pread64,pread64)
182 #endif /* __UCLIBC_HAS_LFS__  */
183 #endif /* ! __NR_pread */
184
185
186 #ifndef __NR_pwrite
187 ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
188 {
189         return(__fake_pread_write(fd, buf, count, offset, 1));
190 }
191 strong_alias(__libc_pwrite,pwrite)
192
193 #if defined __UCLIBC_HAS_LFS__ 
194 ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
195
196         return(__fake_pread_write64(fd, (void*)buf, count, offset, 1));
197 }
198 strong_alias(__libc_pwrite64,pwrite64)
199 #endif /* __UCLIBC_HAS_LFS__  */
200 #endif /* ! __NR_pwrite */