1 | /*-␊ |
2 | * Copyright (c) 1990, 1993␊ |
3 | *␉The Regents of the University of California. All rights reserved.␊ |
4 | *␊ |
5 | * This code is derived from software contributed to Berkeley by␊ |
6 | * Chris Torek.␊ |
7 | *␊ |
8 | * Redistribution and use in source and binary forms, with or without␊ |
9 | * modification, are permitted provided that the following conditions␊ |
10 | * are met:␊ |
11 | * 1. Redistributions of source code must retain the above copyright␊ |
12 | * notice, this list of conditions and the following disclaimer.␊ |
13 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
14 | * notice, this list of conditions and the following disclaimer in the␊ |
15 | * documentation and/or other materials provided with the distribution.␊ |
16 | * 4. Neither the name of the University nor the names of its contributors␊ |
17 | * may be used to endorse or promote products derived from this software␊ |
18 | * without specific prior written permission.␊ |
19 | *␊ |
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
30 | * SUCH DAMAGE.␊ |
31 | */␊ |
32 | ␊ |
33 | #if defined(LIBC_SCCS) && !defined(lint)␊ |
34 | static char sccsid[] = "@(#)stdio.c␉8.1 (Berkeley) 6/4/93";␊ |
35 | #endif /* LIBC_SCCS and not lint */␊ |
36 | #include <sys/cdefs.h>␊ |
37 | __FBSDID("$FreeBSD: src/lib/libc/stdio/stdio.c,v 1.28 2008/05/05 16:14:02 jhb Exp $");␊ |
38 | ␊ |
39 | #include "namespace.h"␊ |
40 | #include <errno.h>␊ |
41 | #include <fcntl.h>␊ |
42 | #include <limits.h>␊ |
43 | #include <stdio.h>␊ |
44 | #include <stdlib.h>␊ |
45 | #include <unistd.h>␊ |
46 | #include "un-namespace.h"␊ |
47 | #include "local.h"␊ |
48 | #include <sys/stat.h>␊ |
49 | ␊ |
50 | ␊ |
51 | /*␊ |
52 | * Small standard I/O/seek/close functions.␊ |
53 | */␊ |
54 | int␊ |
55 | __sread(cookie, buf, n)␊ |
56 | void *cookie;␊ |
57 | char *buf;␊ |
58 | int n;␊ |
59 | {␊ |
60 | ␉FILE *fp = cookie;␊ |
61 | ␉␊ |
62 | ␉return(read(fp->_file, buf, (size_t)n));␊ |
63 | }␊ |
64 | ␊ |
65 | int␊ |
66 | __swrite(cookie, buf, n)␊ |
67 | void *cookie;␊ |
68 | char const *buf;␊ |
69 | int n;␊ |
70 | {␊ |
71 | ␉FILE *fp = cookie;␊ |
72 | ␉␊ |
73 | ␉return (write(fp->_file, buf, (size_t)n));␊ |
74 | }␊ |
75 | ␊ |
76 | fpos_t␊ |
77 | __sseek(cookie, offset, whence)␊ |
78 | void *cookie;␊ |
79 | fpos_t offset;␊ |
80 | int whence;␊ |
81 | {␊ |
82 | ␉FILE *fp = cookie;␊ |
83 | ␉␊ |
84 | ␉return (lseek(fp->_file, (off_t)offset, whence));␊ |
85 | }␊ |
86 | ␊ |
87 | int␊ |
88 | __sclose(cookie)␊ |
89 | void *cookie;␊ |
90 | {␊ |
91 | ␉␊ |
92 | ␉return (close(((FILE *)cookie)->_file));␊ |
93 | }␊ |
94 | ␊ |
95 | /*␊ |
96 | * Higher level wrappers.␊ |
97 | */␊ |
98 | int␊ |
99 | _sread(fp, buf, n)␊ |
100 | FILE *fp;␊ |
101 | char *buf;␊ |
102 | int n;␊ |
103 | {␊ |
104 | ␉int ret;␊ |
105 | ␉␊ |
106 | ␉ret = (*fp->_read)(fp->_cookie, buf, n);␊ |
107 | ␉if (ret > 0) {␊ |
108 | ␉␉if (fp->_flags & __SOFF) {␊ |
109 | ␉␉␉if (fp->_offset <= OFF_MAX - ret)␊ |
110 | ␉␉␉␉fp->_offset += ret;␊ |
111 | ␉␉␉else␊ |
112 | ␉␉␉␉fp->_flags &= ~__SOFF;␊ |
113 | ␉␉}␊ |
114 | ␉} else if (ret < 0)␊ |
115 | ␉␉fp->_flags &= ~__SOFF;␊ |
116 | ␉return (ret);␊ |
117 | }␊ |
118 | ␊ |
119 | int␊ |
120 | _swrite(fp, buf, n)␊ |
121 | FILE *fp;␊ |
122 | char const *buf;␊ |
123 | int n;␊ |
124 | {␊ |
125 | ␉int ret;␊ |
126 | int serrno;␊ |
127 | ␉␊ |
128 | ␉if (fp->_flags & __SAPP) {␊ |
129 | serrno = errno;␊ |
130 | ␉␉if (_sseek(fp, (fpos_t)0, SEEK_END) == -1 &&␊ |
131 | ␉␉ (fp->_flags & __SOPT))␊ |
132 | ␉␉␉return (-1);␊ |
133 | errno = serrno;␊ |
134 | ␉␉␊ |
135 | ␉}␊ |
136 | ␉ret = (*fp->_write)(fp->_cookie, buf, n);␊ |
137 | ␉/* __SOFF removed even on success in case O_APPEND mode is set. */␊ |
138 | ␉if (ret >= 0) {␊ |
139 | ␉␉if ((fp->_flags & (__SAPP|__SOFF)) == (__SAPP|__SOFF) &&␊ |
140 | ␉␉ fp->_offset <= OFF_MAX - ret)␊ |
141 | ␉␉␉fp->_offset += ret;␊ |
142 | ␉␉else␊ |
143 | ␉␉␉fp->_flags &= ~__SOFF;␊ |
144 | ␉␉␊ |
145 | ␉} else if (ret < 0)␊ |
146 | ␉␉fp->_flags &= ~__SOFF;␊ |
147 | ␉return (ret);␊ |
148 | }␊ |
149 | ␊ |
150 | fpos_t␊ |
151 | _sseek(fp, offset, whence)␊ |
152 | FILE *fp;␊ |
153 | fpos_t offset;␊ |
154 | int whence;␊ |
155 | {␊ |
156 | ␉fpos_t ret;␊ |
157 | int serrno, errret;␊ |
158 | ␉␊ |
159 | serrno = errno;␊ |
160 | ␉errno = 0;␊ |
161 | ␉ret = (*fp->_seek)(fp->_cookie, offset, whence);␊ |
162 | errret = errno;␊ |
163 | if (errno == 0)␊ |
164 | ␉␉errno = serrno ;␊ |
165 | ␉/*␊ |
166 | ␉ * Disallow negative seeks per POSIX.␊ |
167 | ␉ * It is needed here to help upper level caller␊ |
168 | ␉ * in the cases it can't detect.␊ |
169 | ␉ */␊ |
170 | ␉if (ret < 0) {␊ |
171 | ␉␉if (errret == 0) {␊ |
172 | ␉␉␉if (offset != 0 || whence != SEEK_CUR) {␊ |
173 | ␉␉␉␉if (HASUB(fp))␊ |
174 | ␉␉␉␉␉FREEUB(fp);␊ |
175 | ␉␉␉␉fp->_p = fp->_bf._base;␊ |
176 | ␉␉␉␉fp->_r = 0;␊ |
177 | ␉␉␉␉fp->_flags &= ~__SEOF;␊ |
178 | ␉␉␉}␊ |
179 | ␉␉␉fp->_flags |= __SERR;␊ |
180 | errno = EINVAL;␊ |
181 | ␉␉} else if (errret == ESPIPE)␊ |
182 | ␉␉␉fp->_flags &= ~__SAPP;␊ |
183 | ␉␉fp->_flags &= ~__SOFF;␊ |
184 | ␉␉ret = -1;␊ |
185 | ␉} else if (fp->_flags & __SOPT) {␊ |
186 | ␉␉fp->_flags |= __SOFF;␊ |
187 | ␉␉fp->_offset = ret;␊ |
188 | ␉}␊ |
189 | ␉return (ret);␊ |
190 | }␊ |
191 | ␊ |
192 | /* WARNING : This implementation of fstat(2) , currently only give the file size */␊ |
193 | int␊ |
194 | fstat(int fildes, struct stat *buf)␊ |
195 | {␊ |
196 | ␉extern int file_size(int fdesc);␊ |
197 | ␉␊ |
198 | struct stat *st =(struct stat *)buf;␊ |
199 | ␊ |
200 | st->st_size = file_size(fildes);␊ |
201 | ␊ |
202 | return 0;␊ |
203 | } |