1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include <libioP.h>
30: #include <stdio.h>
31: #include <stdlib.h>
32: #include <shlib-compat.h>
33:
34:
35: static _IO_ssize_t _IO_cookie_read (register _IO_FILE* fp, void* buf,
36: _IO_ssize_t size);
37: static _IO_ssize_t _IO_cookie_write (register _IO_FILE* fp,
38: const void* buf, _IO_ssize_t size);
39: static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir);
40: static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
41: int dir, int mode);
42: static int _IO_cookie_close (_IO_FILE* fp);
43:
44: static _IO_ssize_t
45: _IO_cookie_read (fp, buf, size)
46: _IO_FILE *fp;
47: void *buf;
48: _IO_ssize_t size;
49: {
50: struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
51:
52: if (cfile->__io_functions.read == NULL)
53: return -1;
54:
55: return cfile->__io_functions.read (cfile->__cookie, buf, size);
56: }
57:
58: static _IO_ssize_t
59: _IO_cookie_write (fp, buf, size)
60: _IO_FILE *fp;
61: const void *buf;
62: _IO_ssize_t size;
63: {
64: struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
65:
66: if (cfile->__io_functions.write == NULL)
67: {
68: fp->_flags |= _IO_ERR_SEEN;
69: return 0;
70: }
71:
72: _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
73: if (n < size)
74: fp->_flags |= _IO_ERR_SEEN;
75:
76: return n;
77: }
78:
79: static _IO_off64_t
80: _IO_cookie_seek (fp, offset, dir)
81: _IO_FILE *fp;
82: _IO_off64_t offset;
83: int dir;
84: {
85: struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
86:
87: return ((cfile->__io_functions.seek == NULL
88: || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir)
89: == -1)
90: || offset == (_IO_off64_t) -1)
91: ? _IO_pos_BAD : offset);
92: }
93:
94: static int
95: _IO_cookie_close (fp)
96: _IO_FILE *fp;
97: {
98: struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
99:
100: if (cfile->__io_functions.close == NULL)
101: return 0;
102:
103: return cfile->__io_functions.close (cfile->__cookie);
104: }
105:
106:
107: static _IO_off64_t
108: _IO_cookie_seekoff (fp, offset, dir, mode)
109: _IO_FILE *fp;
110: _IO_off64_t offset;
111: int dir;
112: int mode;
113: {
114:
115:
116: fp->_offset = _IO_pos_BAD;
117: return INTUSE(_IO_file_seekoff) (fp, offset, dir, mode);
118: }
119:
120:
121: static const struct _IO_jump_t _IO_cookie_jumps = {
122: JUMP_INIT_DUMMY,
123: JUMP_INIT(finish, INTUSE(_IO_file_finish)),
124: JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
125: JUMP_INIT(underflow, INTUSE(_IO_file_underflow)),
126: JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
127: JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
128: JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
129: JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
130: JUMP_INIT(seekoff, _IO_cookie_seekoff),
131: JUMP_INIT(seekpos, _IO_default_seekpos),
132: JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)),
133: JUMP_INIT(sync, INTUSE(_IO_file_sync)),
134: JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
135: JUMP_INIT(read, _IO_cookie_read),
136: JUMP_INIT(write, _IO_cookie_write),
137: JUMP_INIT(seek, _IO_cookie_seek),
138: JUMP_INIT(close, _IO_cookie_close),
139: JUMP_INIT(stat, _IO_default_stat),
140: JUMP_INIT(showmanyc, _IO_default_showmanyc),
141: JUMP_INIT(imbue, _IO_default_imbue),
142: };
143:
144:
145: void
146: _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
147: void *cookie, _IO_cookie_io_functions_t io_functions)
148: {
149: INTUSE(_IO_init) (&cfile->__fp.file, 0);
150: _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
151:
152: cfile->__cookie = cookie;
153: cfile->__io_functions = io_functions;
154:
155: INTUSE(_IO_file_init) (&cfile->__fp);
156:
157: cfile->__fp.file._IO_file_flags =
158: _IO_mask_flags (&cfile->__fp.file, read_write,
159: _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
160:
161:
162:
163:
164: cfile->__fp.file._fileno = -2;
165: }
166:
167:
168: _IO_FILE *
169: _IO_fopencookie (cookie, mode, io_functions)
170: void *cookie;
171: const char *mode;
172: _IO_cookie_io_functions_t io_functions;
173: {
174: int read_write;
175: struct locked_FILE
176: {
177: struct _IO_cookie_file cfile;
178: #ifdef _IO_MTSAFE_IO
179: _IO_lock_t lock;
180: #endif
181: } *new_f;
182:
183: switch (*mode++)
184: {
185: case 'r':
186: read_write = _IO_NO_WRITES;
187: break;
188: case 'w':
189: read_write = _IO_NO_READS;
190: break;
191: case 'a':
192: read_write = _IO_NO_READS|_IO_IS_APPENDING;
193: break;
194: default:
195: return NULL;
196: }
197: if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
198: read_write &= _IO_IS_APPENDING;
199:
200: new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
201: if (new_f == NULL)
202: return NULL;
203: #ifdef _IO_MTSAFE_IO
204: new_f->cfile.__fp.file._lock = &new_f->lock;
205: #endif
206:
207: _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions);
208:
209: return (_IO_FILE *) &new_f->cfile.__fp;
210: }
211:
212: versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2);
213:
214: #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
215:
216: static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset,
217: int dir);
218: _IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode,
219: _IO_cookie_io_functions_t io_functions);
220:
221: static _IO_off64_t
222: attribute_compat_text_section
223: _IO_old_cookie_seek (fp, offset, dir)
224: _IO_FILE *fp;
225: _IO_off64_t offset;
226: int dir;
227: {
228: struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
229: int (*seek) (_IO_FILE *, _IO_off_t, int);
230: int ret;
231:
232: seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;
233: if (seek == NULL)
234: return _IO_pos_BAD;
235:
236: ret = seek (cfile->__cookie, offset, dir);
237:
238: return (ret == -1) ? _IO_pos_BAD : ret;
239: }
240:
241: static const struct _IO_jump_t _IO_old_cookie_jumps = {
242: JUMP_INIT_DUMMY,
243: JUMP_INIT(finish, INTUSE(_IO_file_finish)),
244: JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
245: JUMP_INIT(underflow, INTUSE(_IO_file_underflow)),
246: JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
247: JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
248: JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
249: JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
250: JUMP_INIT(seekoff, _IO_cookie_seekoff),
251: JUMP_INIT(seekpos, _IO_default_seekpos),
252: JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)),
253: JUMP_INIT(sync, INTUSE(_IO_file_sync)),
254: JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
255: JUMP_INIT(read, _IO_cookie_read),
256: JUMP_INIT(write, _IO_cookie_write),
257: JUMP_INIT(seek, _IO_old_cookie_seek),
258: JUMP_INIT(close, _IO_cookie_close),
259: JUMP_INIT(stat, _IO_default_stat),
260: JUMP_INIT(showmanyc, _IO_default_showmanyc),
261: JUMP_INIT(imbue, _IO_default_imbue),
262: };
263:
264: _IO_FILE *
265: attribute_compat_text_section
266: _IO_old_fopencookie (cookie, mode, io_functions)
267: void *cookie;
268: const char *mode;
269: _IO_cookie_io_functions_t io_functions;
270: {
271: _IO_FILE *ret;
272:
273: ret = _IO_fopencookie (cookie, mode, io_functions);
274: if (ret != NULL)
275: _IO_JUMPS ((struct _IO_FILE_plus *) ret) = &_IO_old_cookie_jumps;
276:
277: return ret;
278: }
279:
280: compat_symbol (libc, _IO_old_fopencookie, fopencookie, GLIBC_2_0);
281:
282: #endif