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:
30:
31: #ifndef _POSIX_SOURCE
32: # define _POSIX_SOURCE
33: #endif
34: #include "libioP.h"
35: #include <assert.h>
36: #include <fcntl.h>
37: #include <sys/param.h>
38: #include <sys/types.h>
39: #include <sys/stat.h>
40: #include <string.h>
41: #include <errno.h>
42: #include <unistd.h>
43: #ifdef __STDC__
44: #include <stdlib.h>
45: #endif
46: #if _LIBC
47: # include "../wcsmbs/wcsmbsload.h"
48: # include "../iconv/gconv_charset.h"
49: # include "../iconv/gconv_int.h"
50: # include <shlib-compat.h>
51: # include <not-cancel.h>
52: #endif
53: #ifndef errno
54: extern int errno;
55: #endif
56: #ifndef __set_errno
57: # define __set_errno(Val) errno = (Val)
58: #endif
59:
60:
61: #ifdef _LIBC
62: # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
63: # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
64: # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
65: # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
66: # define _IO_do_write _IO_new_do_write
67: # define _IO_file_close_it _IO_new_file_close_it
68: #else
69: # define _IO_new_do_write _IO_do_write
70: # define _IO_new_file_attach _IO_file_attach
71: # define _IO_new_file_close_it _IO_file_close_it
72: # define _IO_new_file_finish _IO_file_finish
73: # define _IO_new_file_fopen _IO_file_fopen
74: # define _IO_new_file_init _IO_file_init
75: # define _IO_new_file_setbuf _IO_file_setbuf
76: # define _IO_new_file_sync _IO_file_sync
77: # define _IO_new_file_overflow _IO_file_overflow
78: # define _IO_new_file_seekoff _IO_file_seekoff
79: # define _IO_new_file_underflow _IO_file_underflow
80: # define _IO_new_file_write _IO_file_write
81: # define _IO_new_file_xsputn _IO_file_xsputn
82: #endif
83:
84:
85: #ifdef _LIBC
86: extern struct __gconv_trans_data __libio_translit attribute_hidden;
87: #endif
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140: #define CLOSED_FILEBUF_FLAGS \
141: (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
142:
143:
144: void
145: _IO_new_file_init (fp)
146: struct _IO_FILE_plus *fp;
147: {
148:
149:
150:
151: fp->file._offset = _IO_pos_BAD;
152: fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
153:
154: INTUSE(_IO_link_in) (fp);
155: fp->file._fileno = -1;
156: }
157: INTDEF2(_IO_new_file_init, _IO_file_init)
158:
159: int
160: _IO_new_file_close_it (fp)
161: _IO_FILE *fp;
162: {
163: int write_status, close_status;
164: if (!_IO_file_is_open (fp))
165: return EOF;
166:
167: if ((fp->_flags & _IO_NO_WRITES) == 0
168: && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
169: write_status = _IO_do_flush (fp);
170: else
171: write_status = 0;
172:
173: INTUSE(_IO_unsave_markers) (fp);
174:
175: close_status = _IO_SYSCLOSE (fp);
176:
177:
178: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
179: if (fp->_mode > 0)
180: {
181: if (_IO_have_wbackup (fp))
182: INTUSE(_IO_free_wbackup_area) (fp);
183: INTUSE(_IO_wsetb) (fp, NULL, NULL, 0);
184: _IO_wsetg (fp, NULL, NULL, NULL);
185: _IO_wsetp (fp, NULL, NULL);
186: }
187: #endif
188: INTUSE(_IO_setb) (fp, NULL, NULL, 0);
189: _IO_setg (fp, NULL, NULL, NULL);
190: _IO_setp (fp, NULL, NULL);
191:
192: INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
193: fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
194: fp->_fileno = -1;
195: fp->_offset = _IO_pos_BAD;
196:
197: return close_status ? close_status : write_status;
198: }
199: INTDEF2(_IO_new_file_close_it, _IO_file_close_it)
200:
201: void
202: _IO_new_file_finish (fp, dummy)
203: _IO_FILE *fp;
204: int dummy;
205: {
206: if (_IO_file_is_open (fp))
207: {
208: _IO_do_flush (fp);
209: if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
210: _IO_SYSCLOSE (fp);
211: }
212: INTUSE(_IO_default_finish) (fp, 0);
213: }
214: INTDEF2(_IO_new_file_finish, _IO_file_finish)
215:
216: _IO_FILE *
217: _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
218: _IO_FILE *fp;
219: const char *filename;
220: int posix_mode;
221: int prot;
222: int read_write;
223: int is32not64;
224: {
225: int fdesc;
226: #ifdef _LIBC
227: if (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0))
228: fdesc = open_not_cancel (filename,
229: posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
230: else
231: fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
232: #else
233: fdesc = open (filename, posix_mode, prot);
234: #endif
235: if (fdesc < 0)
236: return NULL;
237: fp->_fileno = fdesc;
238: _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
239: if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS))
240: if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
241: == _IO_pos_BAD && errno != ESPIPE)
242: {
243: close_not_cancel (fdesc);
244: return NULL;
245: }
246: INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp);
247: return fp;
248: }
249: libc_hidden_def (_IO_file_open)
250:
251: _IO_FILE *
252: _IO_new_file_fopen (fp, filename, mode, is32not64)
253: _IO_FILE *fp;
254: const char *filename;
255: const char *mode;
256: int is32not64;
257: {
258: int oflags = 0, omode;
259: int read_write;
260: int oprot = 0666;
261: int i;
262: _IO_FILE *result;
263: #ifdef _LIBC
264: const char *cs;
265: const char *last_recognized;
266: #endif
267:
268: if (_IO_file_is_open (fp))
269: return 0;
270: switch (*mode)
271: {
272: case 'r':
273: omode = O_RDONLY;
274: read_write = _IO_NO_WRITES;
275: break;
276: case 'w':
277: omode = O_WRONLY;
278: oflags = O_CREAT|O_TRUNC;
279: read_write = _IO_NO_READS;
280: break;
281: case 'a':
282: omode = O_WRONLY;
283: oflags = O_CREAT|O_APPEND;
284: read_write = _IO_NO_READS|_IO_IS_APPENDING;
285: break;
286: default:
287: __set_errno (EINVAL);
288: return NULL;
289: }
290: #ifdef _LIBC
291: last_recognized = mode;
292: #endif
293: for (i = 1; i < 6; ++i)
294: {
295: switch (*++mode)
296: {
297: case '\0':
298: break;
299: case '+':
300: omode = O_RDWR;
301: read_write &= _IO_IS_APPENDING;
302: #ifdef _LIBC
303: last_recognized = mode;
304: #endif
305: continue;
306: case 'x':
307: oflags |= O_EXCL;
308: #ifdef _LIBC
309: last_recognized = mode;
310: #endif
311: continue;
312: case 'b':
313: #ifdef _LIBC
314: last_recognized = mode;
315: #endif
316: continue;
317: case 'm':
318: fp->_flags2 |= _IO_FLAGS2_MMAP;
319: continue;
320: case 'c':
321: fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
322: break;
323: #ifdef O_CLOEXEC
324: case 'e':
325: oflags |= O_CLOEXEC;
326: break;
327: #endif
328: default:
329:
330: continue;
331: }
332: break;
333: }
334:
335: result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
336: is32not64);
337:
338:
339: #ifdef _LIBC
340: if (result != NULL)
341: {
342:
343: cs = strstr (last_recognized + 1, ",ccs=");
344: if (cs != NULL)
345: {
346:
347:
348: struct gconv_fcts fcts;
349: struct _IO_codecvt *cc;
350: char *endp = __strchrnul (cs + 5, ',');
351: char ccs[endp - (cs + 5) + 3];
352:
353: *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
354: strip (ccs, ccs);
355:
356: if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
357: ? upstr (ccs, cs + 5) : ccs) != 0)
358: {
359:
360:
361:
362: (void) INTUSE(_IO_file_close_it) (fp);
363: __set_errno (EINVAL);
364: return NULL;
365: }
366:
367: assert (fcts.towc_nsteps == 1);
368: assert (fcts.tomb_nsteps == 1);
369:
370: fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
371: fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
372:
373:
374: memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
375: memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
376:
377: cc = fp->_codecvt = &fp->_wide_data->_codecvt;
378:
379:
380: *cc = __libio_codecvt;
381:
382: cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
383: cc->__cd_in.__cd.__steps = fcts.towc;
384:
385: cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
386: cc->__cd_in.__cd.__data[0].__internal_use = 1;
387: cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
388: cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
389:
390:
391: cc->__cd_in.__cd.__data[0].__trans = NULL;
392:
393: cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
394: cc->__cd_out.__cd.__steps = fcts.tomb;
395:
396: cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
397: cc->__cd_out.__cd.__data[0].__internal_use = 1;
398: cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
399: cc->__cd_out.__cd.__data[0].__statep =
400: &result->_wide_data->_IO_state;
401:
402:
403: cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
404:
405:
406: ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
407:
408:
409: result->_mode = 1;
410: }
411: }
412: #endif
413:
414: return result;
415: }
416: INTDEF2(_IO_new_file_fopen, _IO_file_fopen)
417:
418: _IO_FILE *
419: _IO_new_file_attach (fp, fd)
420: _IO_FILE *fp;
421: int fd;
422: {
423: if (_IO_file_is_open (fp))
424: return NULL;
425: fp->_fileno = fd;
426: fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
427: fp->_flags |= _IO_DELETE_DONT_CLOSE;
428:
429:
430: fp->_offset = _IO_pos_BAD;
431: if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
432: == _IO_pos_BAD && errno != ESPIPE)
433: return NULL;
434: return fp;
435: }
436: INTDEF2(_IO_new_file_attach, _IO_file_attach)
437:
438: _IO_FILE *
439: _IO_new_file_setbuf (fp, p, len)
440: _IO_FILE *fp;
441: char *p;
442: _IO_ssize_t len;
443: {
444: if (_IO_default_setbuf (fp, p, len) == NULL)
445: return NULL;
446:
447: fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
448: = fp->_IO_buf_base;
449: _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
450:
451: return fp;
452: }
453: INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf)
454:
455:
456: _IO_FILE *
457: _IO_file_setbuf_mmap (fp, p, len)
458: _IO_FILE *fp;
459: char *p;
460: _IO_ssize_t len;
461: {
462: _IO_FILE *result;
463:
464:
465: _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
466: fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
467:
468:
469: result = _IO_new_file_setbuf (fp, p, len);
470:
471:
472: if (result == NULL)
473: {
474: _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
475: fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
476: }
477:
478: return result;
479: }
480:
481: static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
482:
483:
484:
485:
486: int
487: _IO_new_do_write (fp, data, to_do)
488: _IO_FILE *fp;
489: const char *data;
490: _IO_size_t to_do;
491: {
492: return (to_do == 0
493: || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
494: }
495: INTDEF2(_IO_new_do_write, _IO_do_write)
496:
497: static
498: _IO_size_t
499: new_do_write (fp, data, to_do)
500: _IO_FILE *fp;
501: const char *data;
502: _IO_size_t to_do;
503: {
504: _IO_size_t count;
505: if (fp->_flags & _IO_IS_APPENDING)
506:
507:
508:
509:
510:
511: fp->_offset = _IO_pos_BAD;
512: else if (fp->_IO_read_end != fp->_IO_write_base)
513: {
514: _IO_off64_t new_pos
515: = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
516: if (new_pos == _IO_pos_BAD)
517: return 0;
518: fp->_offset = new_pos;
519: }
520: count = _IO_SYSWRITE (fp, data, to_do);
521: if (fp->_cur_column && count)
522: fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
523: count) + 1;
524: _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
525: fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
526: fp->_IO_write_end = (fp->_mode <= 0
527: && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
528: ? fp->_IO_buf_base : fp->_IO_buf_end);
529: return count;
530: }
531:
532: int
533: _IO_new_file_underflow (fp)
534: _IO_FILE *fp;
535: {
536: _IO_ssize_t count;
537: #if 0
538:
539: if (fp->_flags & _IO_EOF_SEEN)
540: return (EOF);
541: #endif
542:
543: if (fp->_flags & _IO_NO_READS)
544: {
545: fp->_flags |= _IO_ERR_SEEN;
546: __set_errno (EBADF);
547: return EOF;
548: }
549: if (fp->_IO_read_ptr < fp->_IO_read_end)
550: return *(unsigned char *) fp->_IO_read_ptr;
551:
552: if (fp->_IO_buf_base == NULL)
553: {
554:
555: if (fp->_IO_save_base != NULL)
556: {
557: free (fp->_IO_save_base);
558: fp->_flags &= ~_IO_IN_BACKUP;
559: }
560: INTUSE(_IO_doallocbuf) (fp);
561: }
562:
563:
564: