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 | #include "stdio.h"␊ |
39 | #include "errno.h"␊ |
40 | #include "namespace.h"␊ |
41 | #include <limits.h>␊ |
42 | #include "stat.h"␊ |
43 | ␊ |
44 | #include "un-namespace.h"␊ |
45 | #include "local.h"␊ |
46 | #include "saio_types.h"␊ |
47 | ␊ |
48 | #define OFF_MIN␉␉LLONG_MIN␉/* min value for an off_t */␊ |
49 | #define OFF_MAX␉␉LLONG_MAX␉/* max value for an off_t */␊ |
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 (b_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 = get_errno();␊ |
130 | ␉␉if (_sseek(fp, (fpos_t)0, SEEK_END) == -1 &&␊ |
131 | ␉␉ (fp->_flags & __SOPT))␊ |
132 | ␉␉␉return (-1);␊ |
133 | set_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 = get_errno();␊ |
160 | ␉set_errno(0);␊ |
161 | ␉ret = (*fp->_seek)(fp->_cookie, offset, whence);␊ |
162 | errret = get_errno();␊ |
163 | if (get_errno() == 0)␊ |
164 | ␉␉set_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 | set_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 | int␊ |
193 | fstat(int fildes, struct stat *buf)␊ |
194 | {␊ |
195 | struct stat *st =(struct stat *)buf;␊ |
196 | ␊ |
197 | st->st_size = file_size(fildes);␊ |
198 | ␊ |
199 | return 0;␊ |
200 | }␊ |
201 | ␊ |
202 | void Libstdio_start(void);␊ |
203 | void Libstdio_start(void)␊ |
204 | {␊ |
205 | ␊ |
206 | }␊ |
207 | ␊ |
208 | |