]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/iofopncook.c
Fix i386 build for lll_unlock_elision change.
[thirdparty/glibc.git] / libio / iofopncook.c
CommitLineData
b168057a 1/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
40a55d20 3
41bdb6e2
AJ
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
40a55d20 8
41bdb6e2
AJ
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
40a55d20 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
40a55d20 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>.
40a55d20 17
41bdb6e2
AJ
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
96aa2d94
RM
26
27#include <libioP.h>
fa0bc87c 28#include <stdio.h>
96aa2d94 29#include <stdlib.h>
5d1fba6d 30#include <shlib-compat.h>
fa0bc87c
RM
31
32/* Prototyped for local functions. */
2e09a79a 33static _IO_ssize_t _IO_cookie_read (_IO_FILE* fp, void* buf,
572705e4 34 _IO_ssize_t size);
2e09a79a 35static _IO_ssize_t _IO_cookie_write (_IO_FILE* fp,
572705e4
UD
36 const void* buf, _IO_ssize_t size);
37static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir);
f9f7fcbe
RM
38static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
39 int dir, int mode);
572705e4 40static int _IO_cookie_close (_IO_FILE* fp);
96aa2d94
RM
41
42static _IO_ssize_t
43_IO_cookie_read (fp, buf, size)
40a55d20
UD
44 _IO_FILE *fp;
45 void *buf;
96aa2d94
RM
46 _IO_ssize_t size;
47{
48 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
49
542f5e01 50 if (cfile->__io_functions.read == NULL)
96aa2d94
RM
51 return -1;
52
542f5e01 53 return cfile->__io_functions.read (cfile->__cookie, buf, size);
96aa2d94
RM
54}
55
56static _IO_ssize_t
57_IO_cookie_write (fp, buf, size)
40a55d20
UD
58 _IO_FILE *fp;
59 const void *buf;
96aa2d94
RM
60 _IO_ssize_t size;
61{
62 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
63
542f5e01 64 if (cfile->__io_functions.write == NULL)
32053042
UD
65 {
66 fp->_flags |= _IO_ERR_SEEN;
67 return 0;
68 }
69
70 _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
71 if (n < size)
72 fp->_flags |= _IO_ERR_SEEN;
96aa2d94 73
32053042 74 return n;
96aa2d94
RM
75}
76
d64b6ad0 77static _IO_off64_t
96aa2d94
RM
78_IO_cookie_seek (fp, offset, dir)
79 _IO_FILE *fp;
dfd2257a 80 _IO_off64_t offset;
96aa2d94
RM
81 int dir;
82{
83 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
96aa2d94 84
b4e54243 85 return ((cfile->__io_functions.seek == NULL
9658516a 86 || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir)
de153e7f
UD
87 == -1)
88 || offset == (_IO_off64_t) -1)
b4e54243 89 ? _IO_pos_BAD : offset);
96aa2d94
RM
90}
91
92static int
93_IO_cookie_close (fp)
40a55d20 94 _IO_FILE *fp;
96aa2d94
RM
95{
96 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
97
542f5e01 98 if (cfile->__io_functions.close == NULL)
96aa2d94
RM
99 return 0;
100
542f5e01 101 return cfile->__io_functions.close (cfile->__cookie);
96aa2d94
RM
102}
103
104
1e7cceb9
UD
105static _IO_off64_t
106_IO_cookie_seekoff (fp, offset, dir, mode)
107 _IO_FILE *fp;
108 _IO_off64_t offset;
109 int dir;
110 int mode;
111{
112 /* We must force the fileops code to always use seek to determine
113 the position. */
114 fp->_offset = _IO_pos_BAD;
d18ea0c5 115 return _IO_file_seekoff (fp, offset, dir, mode);
1e7cceb9
UD
116}
117
118
b2637a22 119static const struct _IO_jump_t _IO_cookie_jumps = {
96aa2d94 120 JUMP_INIT_DUMMY,
d18ea0c5
AS
121 JUMP_INIT(finish, _IO_file_finish),
122 JUMP_INIT(overflow, _IO_file_overflow),
123 JUMP_INIT(underflow, _IO_file_underflow),
124 JUMP_INIT(uflow, _IO_default_uflow),
125 JUMP_INIT(pbackfail, _IO_default_pbackfail),
126 JUMP_INIT(xsputn, _IO_file_xsputn),
127 JUMP_INIT(xsgetn, _IO_default_xsgetn),
1e7cceb9 128 JUMP_INIT(seekoff, _IO_cookie_seekoff),
96aa2d94 129 JUMP_INIT(seekpos, _IO_default_seekpos),
d18ea0c5
AS
130 JUMP_INIT(setbuf, _IO_file_setbuf),
131 JUMP_INIT(sync, _IO_file_sync),
132 JUMP_INIT(doallocate, _IO_file_doallocate),
96aa2d94
RM
133 JUMP_INIT(read, _IO_cookie_read),
134 JUMP_INIT(write, _IO_cookie_write),
135 JUMP_INIT(seek, _IO_cookie_seek),
136 JUMP_INIT(close, _IO_cookie_close),
dfd2257a
UD
137 JUMP_INIT(stat, _IO_default_stat),
138 JUMP_INIT(showmanyc, _IO_default_showmanyc),
139 JUMP_INIT(imbue, _IO_default_imbue),
96aa2d94
RM
140};
141
142
b4e54243
RM
143void
144_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
145 void *cookie, _IO_cookie_io_functions_t io_functions)
146{
d18ea0c5 147 _IO_init (&cfile->__fp.file, 0);
2ca8b1ee 148 _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
b4e54243
RM
149
150 cfile->__cookie = cookie;
151 cfile->__io_functions = io_functions;
152
d18ea0c5 153 _IO_file_init (&cfile->__fp);
b4e54243 154
817328ee
AS
155 _IO_mask_flags (&cfile->__fp.file, read_write,
156 _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
b4e54243
RM
157
158 /* We use a negative number different from -1 for _fileno to mark that
159 this special stream is not associated with a real file, but still has
160 to be treated as such. */
2ca8b1ee 161 cfile->__fp.file._fileno = -2;
b4e54243
RM
162}
163
164
96aa2d94 165_IO_FILE *
5d1fba6d 166_IO_fopencookie (cookie, mode, io_functions)
96aa2d94
RM
167 void *cookie;
168 const char *mode;
169 _IO_cookie_io_functions_t io_functions;
170{
171 int read_write;
edf5b2d7
UD
172 struct locked_FILE
173 {
174 struct _IO_cookie_file cfile;
499e7464 175#ifdef _IO_MTSAFE_IO
edf5b2d7 176 _IO_lock_t lock;
499e7464 177#endif
edf5b2d7 178 } *new_f;
96aa2d94
RM
179
180 switch (*mode++)
181 {
182 case 'r':
183 read_write = _IO_NO_WRITES;
184 break;
185 case 'w':
186 read_write = _IO_NO_READS;
187 break;
188 case 'a':
189 read_write = _IO_NO_READS|_IO_IS_APPENDING;
190 break;
191 default:
2d8e36e6 192 __set_errno (EINVAL);
96aa2d94
RM
193 return NULL;
194 }
195 if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
196 read_write &= _IO_IS_APPENDING;
197
edf5b2d7
UD
198 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
199 if (new_f == NULL)
96aa2d94 200 return NULL;
499e7464 201#ifdef _IO_MTSAFE_IO
2ca8b1ee 202 new_f->cfile.__fp.file._lock = &new_f->lock;
499e7464 203#endif
96aa2d94 204
b4e54243 205 _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions);
110215a9 206
2ca8b1ee 207 return (_IO_FILE *) &new_f->cfile.__fp;
96aa2d94 208}
5d1fba6d
AJ
209
210versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2);
211
212#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
213
214static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset,
215 int dir);
216_IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode,
217 _IO_cookie_io_functions_t io_functions);
218
219static _IO_off64_t
4a381a81 220attribute_compat_text_section
5d1fba6d
AJ
221_IO_old_cookie_seek (fp, offset, dir)
222 _IO_FILE *fp;
223 _IO_off64_t offset;
224 int dir;
225{
226 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
227 int (*seek) (_IO_FILE *, _IO_off_t, int);
228 int ret;
229
230 seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;
231 if (seek == NULL)
232 return _IO_pos_BAD;
233
234 ret = seek (cfile->__cookie, offset, dir);
235
236 return (ret == -1) ? _IO_pos_BAD : ret;
237}
238
b2637a22 239static const struct _IO_jump_t _IO_old_cookie_jumps = {
5d1fba6d 240 JUMP_INIT_DUMMY,
d18ea0c5
AS
241 JUMP_INIT(finish, _IO_file_finish),
242 JUMP_INIT(overflow, _IO_file_overflow),
243 JUMP_INIT(underflow, _IO_file_underflow),
244 JUMP_INIT(uflow, _IO_default_uflow),
245 JUMP_INIT(pbackfail, _IO_default_pbackfail),
246 JUMP_INIT(xsputn, _IO_file_xsputn),
247 JUMP_INIT(xsgetn, _IO_default_xsgetn),
1e7cceb9 248 JUMP_INIT(seekoff, _IO_cookie_seekoff),
5d1fba6d 249 JUMP_INIT(seekpos, _IO_default_seekpos),
d18ea0c5
AS
250 JUMP_INIT(setbuf, _IO_file_setbuf),
251 JUMP_INIT(sync, _IO_file_sync),
252 JUMP_INIT(doallocate, _IO_file_doallocate),
5d1fba6d
AJ
253 JUMP_INIT(read, _IO_cookie_read),
254 JUMP_INIT(write, _IO_cookie_write),
255 JUMP_INIT(seek, _IO_old_cookie_seek),
256 JUMP_INIT(close, _IO_cookie_close),
257 JUMP_INIT(stat, _IO_default_stat),
258 JUMP_INIT(showmanyc, _IO_default_showmanyc),
259 JUMP_INIT(imbue, _IO_default_imbue),
260};
261
262_IO_FILE *
4a381a81 263attribute_compat_text_section
5d1fba6d
AJ
264_IO_old_fopencookie (cookie, mode, io_functions)
265 void *cookie;
266 const char *mode;
267 _IO_cookie_io_functions_t io_functions;
268{
269 _IO_FILE *ret;
270
271 ret = _IO_fopencookie (cookie, mode, io_functions);
272 if (ret != NULL)
e69dcccb 273 _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps;
5d1fba6d
AJ
274
275 return ret;
276}
277
278compat_symbol (libc, _IO_old_fopencookie, fopencookie, GLIBC_2_0);
279
280#endif