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: #include "libioP.h"
32: #ifdef __STDC__
33: #include <stdlib.h>
34: #endif
35: #include <string.h>
36: #include <stdbool.h>
37: #ifdef _LIBC
38: #include <sched.h>
39: #endif
40:
41: #ifdef _IO_MTSAFE_IO
42: static _IO_lock_t list_all_lock = _IO_lock_initializer;
43: #endif
44:
45:
46: static int _IO_list_all_stamp;
47:
48:
49: static _IO_FILE *run_fp;
50:
51: static void
52: flush_cleanup (void *not_used)
53: {
54: if (run_fp != NULL)
55: _IO_funlockfile (run_fp);
56: #ifdef _IO_MTSAFE_IO
57: _IO_lock_unlock (list_all_lock);
58: #endif
59: }
60:
61: void
62: _IO_un_link (fp)
63: struct _IO_FILE_plus *fp;
64: {
65: if (fp->file._flags & _IO_LINKED)
66: {
67: struct _IO_FILE **f;
68: #ifdef _IO_MTSAFE_IO
69: _IO_cleanup_region_start_noarg (flush_cleanup);
70: _IO_lock_lock (list_all_lock);
71: run_fp = (_IO_FILE *) fp;
72: _IO_flockfile ((_IO_FILE *) fp);
73: #endif
74: if (INTUSE(_IO_list_all) == NULL)
75: ;
76: else if (fp == INTUSE(_IO_list_all))
77: {
78: INTUSE(_IO_list_all)
79: = (struct _IO_FILE_plus *) INTUSE(_IO_list_all)->file._chain;
80: ++_IO_list_all_stamp;
81: }
82: else
83: for (f = &INTUSE(_IO_list_all)->file._chain; *f; f = &(*f)->_chain)
84: if (*f == (_IO_FILE *) fp)
85: {
86: *f = fp->file._chain;
87: ++_IO_list_all_stamp;
88: break;
89: }
90: fp->file._flags &= ~_IO_LINKED;
91: #ifdef _IO_MTSAFE_IO
92: _IO_funlockfile ((_IO_FILE *) fp);
93: run_fp = NULL;
94: _IO_lock_unlock (list_all_lock);
95: _IO_cleanup_region_end (0);
96: #endif
97: }
98: }
99: INTDEF(_IO_un_link)
100:
101: void
102: _IO_link_in (fp)
103: struct _IO_FILE_plus *fp;
104: {
105: if ((fp->file._flags & _IO_LINKED) == 0)
106: {
107: fp->file._flags |= _IO_LINKED;
108: #ifdef _IO_MTSAFE_IO
109: _IO_cleanup_region_start_noarg (flush_cleanup);
110: _IO_lock_lock (list_all_lock);
111: run_fp = (_IO_FILE *) fp;
112: _IO_flockfile ((_IO_FILE *) fp);
113: #endif
114: fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
115: INTUSE(_IO_list_all) = fp;
116: ++_IO_list_all_stamp;
117: #ifdef _IO_MTSAFE_IO
118: _IO_funlockfile ((_IO_FILE *) fp);
119: run_fp = NULL;
120: _IO_lock_unlock (list_all_lock);
121: _IO_cleanup_region_end (0);
122: #endif
123: }
124: }
125: INTDEF(_IO_link_in)
126:
127:
128:
129: _IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
130:
131: _IO_ssize_t
132: _IO_least_marker (fp, end_p)
133: _IO_FILE *fp;
134: char *end_p;
135: {
136: _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
137: struct _IO_marker *mark;
138: for (mark = fp->_markers; mark != NULL; mark = mark->_next)
139: if (mark->_pos < least_so_far)
140: least_so_far = mark->_pos;
141: return least_so_far;
142: }
143:
144:
145:
146: void
147: _IO_switch_to_main_get_area (fp)
148: _IO_FILE *fp;
149: {
150: char *tmp;
151: fp->_flags &= ~_IO_IN_BACKUP;
152:
153: tmp = fp->_IO_read_end;
154: fp->_IO_read_end = fp->_IO_save_end;
155: fp->_IO_save_end= tmp;
156:
157: tmp = fp->_IO_read_base;
158: fp->_IO_read_base = fp->_IO_save_base;
159: fp->_IO_save_base = tmp;
160:
161: fp->_IO_read_ptr = fp->_IO_read_base;
162: }
163:
164:
165:
166: void
167: _IO_switch_to_backup_area (fp)
168: _IO_FILE *fp;
169: {
170: char *tmp;
171: fp->_flags |= _IO_IN_BACKUP;
172:
173: tmp = fp->_IO_read_end;
174: fp->_IO_read_end = fp->_IO_save_end;
175: fp->_IO_save_end = tmp;
176:
177: tmp = fp->_IO_read_base;
178: fp->_IO_read_base = fp->_IO_save_base;
179: fp->_IO_save_base = tmp;
180:
181: fp->_IO_read_ptr = fp->_IO_read_end;
182: }
183:
184: int
185: _IO_switch_to_get_mode (fp)
186: _IO_FILE *fp;
187: {
188: if (fp->_IO_write_ptr > fp->_IO_write_base)
189: if (_IO_OVERFLOW (fp, EOF) == EOF)
190: return EOF;
191: if (_IO_in_backup (fp))
192: fp->_IO_read_base = fp->_IO_backup_base;
193: else
194: {
195: fp->_IO_read_base = fp->_IO_buf_base;
196: if (fp->_IO_write_ptr > fp->_IO_read_end)
197: fp->_IO_read_end = fp->_IO_write_ptr;
198: }
199: fp->_IO_read_ptr = fp->_IO_write_ptr;
200:
201: fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
202:
203: fp->_flags &= ~_IO_CURRENTLY_PUTTING;
204: return 0;
205: }
206: INTDEF(_IO_switch_to_get_mode)
207:
208: void
209: _IO_free_backup_area (fp)
210: _IO_FILE *fp;
211: {
212: if (_IO_in_backup (fp))
213: _IO_switch_to_main_get_area (fp);
214: free (fp->_IO_save_base);
215: fp->_IO_save_base = NULL;
216: fp->_IO_save_end = NULL;
217: fp->_IO_backup_base = NULL;
218: }
219: INTDEF(_IO_free_backup_area)
220:
221: #if 0
222: int
223: _IO_switch_to_put_mode (fp)
224: _IO_FILE *fp;
225: {
226: fp->_IO_write_base = fp->_IO_read_ptr;
227: fp->_IO_write_ptr = fp->_IO_read_ptr;
228:
229: fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
230: ? fp->_IO_read_end : fp->_IO_buf_end);
231:
232: fp->_IO_read_ptr = fp->_IO_read_end;
233: fp->_IO_read_base = fp->_IO_read_end;
234:
235: fp->_flags |= _IO_CURRENTLY_PUTTING;
236: return 0;
237: }
238: #endif
239:
240: int
241: __overflow (f, ch)
242: _IO_FILE *f;
243: int ch;
244: {
245:
246: if (f->_mode == 0)
247: _IO_fwide (f, -1);
248: return _IO_OVERFLOW (f, ch);
249: }
250: libc_hidden_def (__overflow)
251:
252: static int save_for_backup (_IO_FILE *fp, char *end_p)
253: #ifdef _LIBC
254: internal_function
255: #endif
256: ;
257:
258: static int
259: #ifdef _LIBC
260: internal_function
261: #endif
262: save_for_backup (fp, end_p)
263: _IO_FILE *fp;
264: char *end_p;
265: {
266:
267: _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
268:
269: _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
270:
271: _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
272: _IO_size_t avail;
273: _IO_ssize_t delta;
274: struct _IO_marker *mark;
275: if (needed_size > current_Bsize)
276: {
277: char *new_buffer;
278: avail = 100;
279: new_buffer = (char *) malloc (avail + needed_size);
280: if (new_buffer == NULL)
281: return EOF;
282: if (least_mark < 0)
283: {
284: #ifdef _LIBC
285: __mempcpy (__mempcpy (new_buffer + avail,
286: fp->_IO_save_end + least_mark,
287: -least_mark),
288: fp->_IO_read_base,
289: end_p - fp->_IO_read_base);
290: #else
291: memcpy (new_buffer + avail,
292: fp->_IO_save_end + least_mark,
293: -least_mark);
294: memcpy (new_buffer + avail - least_mark,
295: fp->_IO_read_base,
296: end_p - fp->_IO_read_base);
297: #endif
298: }
299: else
300: memcpy (new_buffer + avail,
301: fp->_IO_read_base + least_mark,
302: needed_size);
303: if (fp->_IO_save_base)
304: free (fp->_IO_save_base);
305: fp->_IO_save_base = new_buffer;
306: fp->_IO_save_end = new_buffer + avail + needed_size;
307: }
308: else
309: {
310: avail = current_Bsize - needed_size;
311: if (least_mark < 0)
312: {
313: memmove (fp->_IO_save_base + avail,
314: fp->_IO_save_end + least_mark,
315: -least_mark);
316: memcpy (fp->_IO_save_base + avail - least_mark,
317: fp->_IO_read_base,
318: end_p - fp->_IO_read_base);
319: }
320: else if (needed_size > 0)
321: memcpy (fp->_IO_save_base + avail,
322: fp->_IO_read_base + least_mark,
323: needed_size);
324: }
325: fp->_IO_backup_base = fp->_IO_save_base + avail;
326:
327: delta = end_p - fp->_IO_read_base;
328: for (mark = fp->_markers; mark != NULL; mark = mark->_next)
329: mark->_pos -= delta;
330: return 0;
331: }
332:
333: int
334: __underflow (fp)
335: _IO_FILE *fp;
336: {
337: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
338: if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
339: return EOF;
340: #endif
341:
342: if (fp->_mode == 0)
343: _IO_fwide (fp, -1);
344: if (_IO_in_put_mode (fp))
345: if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
346: return EOF;
347: if (fp->_IO_read_ptr < fp->_IO_read_end)
348: return *(unsigned char *) fp->_IO_read_ptr;
349: if (_IO_in_backup (fp))
350: {
351: _IO_switch_to_main_get_area (fp);
352: if (fp->_IO_read_ptr < fp->_IO_read_end)
353: return *(unsigned char *) fp->_IO_read_ptr;
354: }
355: if (_IO_have_markers (fp))
356: {
357: if (save_for_backup (fp, fp->_IO_read_end))
358: return EOF;
359: }
360: else if (_IO_have_backup (fp))
361: INTUSE(_IO_free_backup_area) (fp);
362: return _IO_UNDERFLOW (fp);
363: }
364: libc_hidden_def (__underflow)
365:
366: int
367: __uflow (fp)
368: _IO_FILE *fp;
369: {
370: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
371: if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
372: return EOF;
373: #endif
374:
375: if (fp->_mode == 0)
376: _IO_fwide (fp, -1);
377: if (_IO_in_put_mode (fp))
378: if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
379: return EOF;
380: if (fp->_IO_read_ptr < fp->_IO_read_end)
381: return *(unsigned char *) fp->_IO_read_ptr++;
382: if (_IO_in_backup (fp))
383: {
384: _IO_switch_to_main_get_area (fp);
385: if (fp->_IO_read_ptr < fp->_IO_read_end)
386: return *(unsigned char *) fp->_IO_read_ptr++;
387: }
388: if (_IO_have_markers (fp))
389: {
390: if (save_for_backup (fp, fp->_IO_read_end))
391: return EOF;
392: }
393: else if (_IO_have_backup (fp))
394: INTUSE(_IO_free_backup_area) (fp);
395: return _IO_UFLOW (fp);
396: }
397: libc_hidden_def (__uflow)
398:
399: void
400: _IO_setb (f, b, eb, a)
401: _IO_FILE *f;
402: char *b;
403: char *eb;
404: int a;
405: {
406: if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
407: FREE_BUF (f->_IO_buf_base, _IO_blen (f));
408: f->_IO_buf_base = b;
409: f->_IO_buf_end = eb;
410: if (a)
411: f->_flags &= ~_IO_USER_BUF;
412: else
413: f->_flags |= _IO_USER_BUF;
414: }
415: INTDEF(_IO_setb)
416:
417: void
418: _IO_doallocbuf (fp)
419: _IO_FILE *fp;
420: {
421: if (fp->_IO_buf_base)
422: return;
423: if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
424: if (_IO_DOALLOCATE (fp) != EOF)
425: return;
426: INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
427: }
428: INTDEF(_IO_doallocbuf)
429:
430: int
431: _IO_default_underflow (fp)
432: _IO_FILE *fp;
433: {
434: return EOF;
435: }
436:
437: int
438: _IO_default_uflow (fp)
439: _IO_FILE *fp;
440: {
441: int ch = _IO_UNDERFLOW (fp);
442: if (ch == EOF)
443: return EOF;
444: return *(unsigned char *) fp->_IO_read_ptr++;
445: }
446: INTDEF(_IO_default_uflow)
447:
448: _IO_size_t
449: _IO_default_xsputn (f, data, n)
450: _IO_FILE *f;
451: const void *data;
452: _IO_size_t n;
453: {
454: const char *s = (char *) data;
455: _IO_size_t more = n;
456: if (more <= 0)
457: return 0;
458: for (;;)
459: {
460:
461: if (f->_IO_write_ptr < f->_IO_write_end)
462: {
463: _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
464: if (count > more)
465: count = more;
466: if (count > 20)
467: {
468: #ifdef _LIBC
469: f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
470: #else
471: memcpy (f->_IO_write_ptr, s, count);
472: f->_IO_write_ptr += count;
473: #endif
474: s += count;
475: }
476: else if (count)
477: {
478: char *p = f->_IO_write_ptr;
479: _IO_ssize_t i;
480: for (i = count; --i >= 0; )
481: *p++ = *s++;
482: f->_IO_write_ptr = p;
483: }
484: more -= count;
485: }
486: if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
487: break;
488: more--;
489: }
490: return n - more;
491: }
492: INTDEF(_IO_default_xsputn)
493:
494: _IO_size_t
495: _IO_sgetn (fp, data, n)
496: _IO_FILE *fp;
497: void *data;
498: _IO_size_t n;
499: {
500:
501: return _IO_XSGETN (fp, data, n);
502: }
503: INTDEF(_IO_sgetn)
504:
505: _IO_size_t
506: _IO_default_xsgetn (fp, data, n)
507: _IO_FILE *fp;
508: void *data;
509: _IO_size_t n;
510: {
511: _IO_size_t more = n;
512: char *s = (char*) data;
513: for (;;)
514: {
515:
516: if (fp->_IO_read_ptr < fp->_IO_read_end)
517: {
518: _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
519: if (count > more)
520: count = more;
521: if (count > 20)
522: {
523: #ifdef _LIBC
524: s = __mempcpy (s, fp->_IO_read_ptr, count);
525: #else
526: memcpy (s, fp->_IO_read_ptr, count);
527: s += count;
528: #endif
529: fp->_IO_read_ptr += count;
530: }
531: else if (count)
532: {
533: char *p = fp->_IO_read_ptr;
534: int i = (int) count;
535: while (--i >= 0)
536: *s++ = *p++;
537: fp->_IO_read_ptr = p;
538: }
539: more -= count;
540: }
541: if (more == 0 || __underflow (fp) == EOF)
542: break;
543: }
544: return n - more;
545: }
546: INTDEF(_IO_default_xsgetn)
547:
548: #if 0
549:
550: int
551: _IO_sync (fp)
552: _IO_FILE *fp;
553: {
554: return 0;
555: }
556: #endif
557:
558: _IO_FILE *
559: _IO_default_setbuf (fp, p, len)
560: _IO_FILE *fp;
561: char *p;
562: _IO_ssize_t len;
563: {
564: if (_IO_SYNC (fp) == EOF)
565: return NULL;
566: if (p == NULL || len == 0)
567: {
568: fp->_flags |= _IO_UNBUFFERED;
569: INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
570: }
571: else
572: {
573: fp->_flags &= ~_IO_UNBUFFERED;
574: INTUSE(_IO_setb) (fp, p, p+len, 0);
575: }
576: fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
577: fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
578: return fp;
579: }
580:
581: _IO_off64_t
582: _IO_default_seekpos (fp, pos, mode)
583: _IO_FILE *fp;
584: _IO_off64_t pos;
585: int mode;
586: {
587: return _IO_SEEKOFF (fp, pos, 0, mode);
588: }
589:
590: int
591: _IO_default_doallocate (fp)
592: _IO_FILE *fp;
593: {
594: char *buf;
595: