]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/iofopncook.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / libio / iofopncook.c
CommitLineData
f7a9f785 1/* Copyright (C) 1993-2016 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
9d46370c 43_IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
96aa2d94
RM
44{
45 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
46
542f5e01 47 if (cfile->__io_functions.read == NULL)
96aa2d94
RM
48 return -1;
49
542f5e01 50 return cfile->__io_functions.read (cfile->__cookie, buf, size);
96aa2d94
RM
51}
52
53static _IO_ssize_t
9d46370c 54_IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size)
96aa2d94
RM
55{
56 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
57
542f5e01 58 if (cfile->__io_functions.write == NULL)
32053042
UD
59 {
60 fp->_flags |= _IO_ERR_SEEN;
61 return 0;
62 }
63
64 _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
65 if (n < size)
66 fp->_flags |= _IO_ERR_SEEN;
96aa2d94 67
32053042 68 return n;
96aa2d94
RM
69}
70
d64b6ad0 71static _IO_off64_t
9d46370c 72_IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
96aa2d94
RM
73{
74 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
96aa2d94 75
b4e54243 76 return ((cfile->__io_functions.seek == NULL
9658516a 77 || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir)
de153e7f
UD
78 == -1)
79 || offset == (_IO_off64_t) -1)
b4e54243 80 ? _IO_pos_BAD : offset);
96aa2d94
RM
81}
82
83static int
9d46370c 84_IO_cookie_close (_IO_FILE *fp)
96aa2d94
RM
85{
86 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
87
542f5e01 88 if (cfile->__io_functions.close == NULL)
96aa2d94
RM
89 return 0;
90
542f5e01 91 return cfile->__io_functions.close (cfile->__cookie);
96aa2d94
RM
92}
93
94
1e7cceb9 95static _IO_off64_t
9d46370c 96_IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
1e7cceb9
UD
97{
98 /* We must force the fileops code to always use seek to determine
99 the position. */
100 fp->_offset = _IO_pos_BAD;
d18ea0c5 101 return _IO_file_seekoff (fp, offset, dir, mode);
1e7cceb9
UD
102}
103
104
b2637a22 105static const struct _IO_jump_t _IO_cookie_jumps = {
96aa2d94 106 JUMP_INIT_DUMMY,
d18ea0c5
AS
107 JUMP_INIT(finish, _IO_file_finish),
108 JUMP_INIT(overflow, _IO_file_overflow),
109 JUMP_INIT(underflow, _IO_file_underflow),
110 JUMP_INIT(uflow, _IO_default_uflow),
111 JUMP_INIT(pbackfail, _IO_default_pbackfail),
112 JUMP_INIT(xsputn, _IO_file_xsputn),
113 JUMP_INIT(xsgetn, _IO_default_xsgetn),
1e7cceb9 114 JUMP_INIT(seekoff, _IO_cookie_seekoff),
96aa2d94 115 JUMP_INIT(seekpos, _IO_default_seekpos),
d18ea0c5
AS
116 JUMP_INIT(setbuf, _IO_file_setbuf),
117 JUMP_INIT(sync, _IO_file_sync),
118 JUMP_INIT(doallocate, _IO_file_doallocate),
96aa2d94
RM
119 JUMP_INIT(read, _IO_cookie_read),
120 JUMP_INIT(write, _IO_cookie_write),
121 JUMP_INIT(seek, _IO_cookie_seek),
122 JUMP_INIT(close, _IO_cookie_close),
dfd2257a
UD
123 JUMP_INIT(stat, _IO_default_stat),
124 JUMP_INIT(showmanyc, _IO_default_showmanyc),
125 JUMP_INIT(imbue, _IO_default_imbue),
96aa2d94
RM
126};
127
128
b4e54243
RM
129void
130_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
131 void *cookie, _IO_cookie_io_functions_t io_functions)
132{
d18ea0c5 133 _IO_init (&cfile->__fp.file, 0);
2ca8b1ee 134 _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
b4e54243
RM
135
136 cfile->__cookie = cookie;
137 cfile->__io_functions = io_functions;
138
d18ea0c5 139 _IO_file_init (&cfile->__fp);
b4e54243 140
817328ee
AS
141 _IO_mask_flags (&cfile->__fp.file, read_write,
142 _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
b4e54243
RM
143
144 /* We use a negative number different from -1 for _fileno to mark that
145 this special stream is not associated with a real file, but still has
146 to be treated as such. */
2ca8b1ee 147 cfile->__fp.file._fileno = -2;
b4e54243
RM
148}
149
150
96aa2d94 151_IO_FILE *
f63f2bfd
JM
152_IO_fopencookie (void *cookie, const char *mode,
153 _IO_cookie_io_functions_t io_functions)
96aa2d94
RM
154{
155 int read_write;
edf5b2d7
UD
156 struct locked_FILE
157 {
158 struct _IO_cookie_file cfile;
499e7464 159#ifdef _IO_MTSAFE_IO
edf5b2d7 160 _IO_lock_t lock;
499e7464 161#endif
edf5b2d7 162 } *new_f;
96aa2d94
RM
163
164 switch (*mode++)
165 {
166 case 'r':
167 read_write = _IO_NO_WRITES;
168 break;
169 case 'w':
170 read_write = _IO_NO_READS;
171 break;
172 case 'a':
173 read_write = _IO_NO_READS|_IO_IS_APPENDING;
174 break;
175 default:
2d8e36e6 176 __set_errno (EINVAL);
96aa2d94
RM
177 return NULL;
178 }
179 if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
180 read_write &= _IO_IS_APPENDING;
181
edf5b2d7
UD
182 new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
183 if (new_f == NULL)
96aa2d94 184 return NULL;
499e7464 185#ifdef _IO_MTSAFE_IO
2ca8b1ee 186 new_f->cfile.__fp.file._lock = &new_f->lock;
499e7464 187#endif
96aa2d94 188
b4e54243 189 _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions);
110215a9 190
2ca8b1ee 191 return (_IO_FILE *) &new_f->cfile.__fp;
96aa2d94 192}
5d1fba6d
AJ
193
194versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2);
195
196#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
197
198static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset,
199 int dir);
200_IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode,
201 _IO_cookie_io_functions_t io_functions);
202
203static _IO_off64_t
4a381a81 204attribute_compat_text_section
9d46370c 205_IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
5d1fba6d
AJ
206{
207 struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
208 int (*seek) (_IO_FILE *, _IO_off_t, int);
209 int ret;
210
211 seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;
212 if (seek == NULL)
213 return _IO_pos_BAD;
214
215 ret = seek (cfile->__cookie, offset, dir);
216
217 return (ret == -1) ? _IO_pos_BAD : ret;
218}
219
b2637a22 220static const struct _IO_jump_t _IO_old_cookie_jumps = {
5d1fba6d 221 JUMP_INIT_DUMMY,
d18ea0c5
AS
222 JUMP_INIT(finish, _IO_file_finish),
223 JUMP_INIT(overflow, _IO_file_overflow),
224 JUMP_INIT(underflow, _IO_file_underflow),
225 JUMP_INIT(uflow, _IO_default_uflow),
226 JUMP_INIT(pbackfail, _IO_default_pbackfail),
227 JUMP_INIT(xsputn, _IO_file_xsputn),
228 JUMP_INIT(xsgetn, _IO_default_xsgetn),
1e7cceb9 229 JUMP_INIT(seekoff, _IO_cookie_seekoff),
5d1fba6d 230 JUMP_INIT(seekpos, _IO_default_seekpos),
d18ea0c5
AS
231 JUMP_INIT(setbuf, _IO_file_setbuf),
232 JUMP_INIT(sync, _IO_file_sync),
233 JUMP_INIT(doallocate, _IO_file_doallocate),
5d1fba6d
AJ
234 JUMP_INIT(read, _IO_cookie_read),
235 JUMP_INIT(write, _IO_cookie_write),
236 JUMP_INIT(seek, _IO_old_cookie_seek),
237 JUMP_INIT(close, _IO_cookie_close),
238 JUMP_INIT(stat, _IO_default_stat),
239 JUMP_INIT(showmanyc, _IO_default_showmanyc),
240 JUMP_INIT(imbue, _IO_default_imbue),
241};
242
243_IO_FILE *
4a381a81 244attribute_compat_text_section
f63f2bfd
JM
245_IO_old_fopencookie (void *cookie, const char *mode,
246 _IO_cookie_io_functions_t io_functions)
5d1fba6d
AJ
247{
248 _IO_FILE *ret;
249
250 ret = _IO_fopencookie (cookie, mode, io_functions);
251 if (ret != NULL)
e69dcccb 252 _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps;
5d1fba6d
AJ
253
254 return ret;
255}
256
257compat_symbol (libc, _IO_old_fopencookie, fopencookie, GLIBC_2_0);
258
259#endif