Hurd: Fix mlock in all cases except non-readable pages.
[glibc.git] / libio / wgenops.c
blob886b25e1abd2be677eec48470496ff0a5723bc81
1 /* Copyright (C) 1993,1995,1997-2002,2004,2006,2012
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Ulrich Drepper <drepper@cygnus.com>.
5 Based on the single byte version by Per Bothner <bothner@cygnus.com>.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <http://www.gnu.org/licenses/>.
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
30 /* Generic or default I/O operations. */
32 #include "libioP.h"
33 #include <stdlib.h>
34 #include <string.h>
35 #include <wchar.h>
38 #ifndef _LIBC
39 # define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
40 #endif
43 static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW
44 #ifdef _LIBC
45 internal_function
46 #endif
49 /* Return minimum _pos markers
50 Assumes the current get area is the main get area. */
51 _IO_ssize_t _IO_least_wmarker (_IO_FILE *fp, wchar_t *end_p) __THROW;
53 _IO_ssize_t
54 _IO_least_wmarker (fp, end_p)
55 _IO_FILE *fp;
56 wchar_t *end_p;
58 _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
59 struct _IO_marker *mark;
60 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
61 if (mark->_pos < least_so_far)
62 least_so_far = mark->_pos;
63 return least_so_far;
65 INTDEF(_IO_least_wmarker)
67 /* Switch current get area from backup buffer to (start of) main get area. */
68 void
69 _IO_switch_to_main_wget_area (fp)
70 _IO_FILE *fp;
72 wchar_t *tmp;
73 fp->_flags &= ~_IO_IN_BACKUP;
74 /* Swap _IO_read_end and _IO_save_end. */
75 tmp = fp->_wide_data->_IO_read_end;
76 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
77 fp->_wide_data->_IO_save_end= tmp;
78 /* Swap _IO_read_base and _IO_save_base. */
79 tmp = fp->_wide_data->_IO_read_base;
80 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
81 fp->_wide_data->_IO_save_base = tmp;
82 /* Set _IO_read_ptr. */
83 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
85 INTDEF(_IO_switch_to_main_wget_area)
88 /* Switch current get area from main get area to (end of) backup area. */
89 void
90 _IO_switch_to_wbackup_area (fp)
91 _IO_FILE *fp;
93 wchar_t *tmp;
94 fp->_flags |= _IO_IN_BACKUP;
95 /* Swap _IO_read_end and _IO_save_end. */
96 tmp = fp->_wide_data->_IO_read_end;
97 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
98 fp->_wide_data->_IO_save_end = tmp;
99 /* Swap _IO_read_base and _IO_save_base. */
100 tmp = fp->_wide_data->_IO_read_base;
101 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
102 fp->_wide_data->_IO_save_base = tmp;
103 /* Set _IO_read_ptr. */
104 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
106 INTDEF(_IO_switch_to_wbackup_area)
109 void
110 _IO_wsetb (f, b, eb, a)
111 _IO_FILE *f;
112 wchar_t *b;
113 wchar_t *eb;
114 int a;
116 if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF))
117 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
118 f->_wide_data->_IO_buf_base = b;
119 f->_wide_data->_IO_buf_end = eb;
120 if (a)
121 f->_flags2 &= ~_IO_FLAGS2_USER_WBUF;
122 else
123 f->_flags2 |= _IO_FLAGS2_USER_WBUF;
125 INTDEF(_IO_wsetb)
128 wint_t
129 _IO_wdefault_pbackfail (fp, c)
130 _IO_FILE *fp;
131 wint_t c;
133 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
134 && !_IO_in_backup (fp)
135 && (wint_t) fp->_IO_read_ptr[-1] == c)
136 --fp->_IO_read_ptr;
137 else
139 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
140 if (!_IO_in_backup (fp))
142 /* We need to keep the invariant that the main get area
143 logically follows the backup area. */
144 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
145 && _IO_have_wbackup (fp))
147 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
148 return WEOF;
150 else if (!_IO_have_wbackup (fp))
152 /* No backup buffer: allocate one. */
153 /* Use nshort buffer, if unused? (probably not) FIXME */
154 int backup_size = 128;
155 wchar_t *bbuf = (wchar_t *) malloc (backup_size
156 * sizeof (wchar_t));
157 if (bbuf == NULL)
158 return WEOF;
159 fp->_wide_data->_IO_save_base = bbuf;
160 fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
161 + backup_size);
162 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
164 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
165 INTUSE(_IO_switch_to_wbackup_area) (fp);
167 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
169 /* Increase size of existing backup buffer. */
170 _IO_size_t new_size;
171 _IO_size_t old_size = (fp->_wide_data->_IO_read_end
172 - fp->_wide_data->_IO_read_base);
173 wchar_t *new_buf;
174 new_size = 2 * old_size;
175 new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
176 if (new_buf == NULL)
177 return WEOF;
178 __wmemcpy (new_buf + (new_size - old_size),
179 fp->_wide_data->_IO_read_base, old_size);
180 free (fp->_wide_data->_IO_read_base);
181 _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
182 new_buf + new_size);
183 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
186 *--fp->_wide_data->_IO_read_ptr = c;
188 return c;
190 INTDEF(_IO_wdefault_pbackfail)
193 void
194 _IO_wdefault_finish (fp, dummy)
195 _IO_FILE *fp;
196 int dummy;
198 struct _IO_marker *mark;
199 if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
201 FREE_BUF (fp->_wide_data->_IO_buf_base,
202 _IO_wblen (fp) * sizeof (wchar_t));
203 fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
206 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
207 mark->_sbuf = NULL;
209 if (fp->_IO_save_base)
211 free (fp->_wide_data->_IO_save_base);
212 fp->_IO_save_base = NULL;
215 #ifdef _IO_MTSAFE_IO
216 if (fp->_lock != NULL)
217 _IO_lock_fini (*fp->_lock);
218 #endif
220 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
222 INTDEF(_IO_wdefault_finish)
225 wint_t
226 _IO_wdefault_uflow (fp)
227 _IO_FILE *fp;
229 wint_t wch;
230 wch = _IO_UNDERFLOW (fp);
231 if (wch == WEOF)
232 return WEOF;
233 return *fp->_wide_data->_IO_read_ptr++;
235 INTDEF(_IO_wdefault_uflow)
238 wint_t
239 __woverflow (f, wch)
240 _IO_FILE *f;
241 wint_t wch;
243 if (f->_mode == 0)
244 _IO_fwide (f, 1);
245 return _IO_OVERFLOW (f, wch);
247 libc_hidden_def (__woverflow)
250 wint_t
251 __wuflow (fp)
252 _IO_FILE *fp;
254 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
255 return WEOF;
257 if (fp->_mode == 0)
258 _IO_fwide (fp, 1);
259 if (_IO_in_put_mode (fp))
260 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
261 return WEOF;
262 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
263 return *fp->_wide_data->_IO_read_ptr++;
264 if (_IO_in_backup (fp))
266 INTUSE(_IO_switch_to_main_wget_area) (fp);
267 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
268 return *fp->_wide_data->_IO_read_ptr++;
270 if (_IO_have_markers (fp))
272 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
273 return WEOF;
275 else if (_IO_have_wbackup (fp))
276 INTUSE(_IO_free_wbackup_area) (fp);
277 return _IO_UFLOW (fp);
279 libc_hidden_def (__wuflow)
281 wint_t
282 __wunderflow (fp)
283 _IO_FILE *fp;
285 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
286 return WEOF;
288 if (fp->_mode == 0)
289 _IO_fwide (fp, 1);
290 if (_IO_in_put_mode (fp))
291 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
292 return WEOF;
293 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
294 return *fp->_wide_data->_IO_read_ptr;
295 if (_IO_in_backup (fp))
297 INTUSE(_IO_switch_to_main_wget_area) (fp);
298 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
299 return *fp->_wide_data->_IO_read_ptr;
301 if (_IO_have_markers (fp))
303 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
304 return WEOF;
306 else if (_IO_have_backup (fp))
307 INTUSE(_IO_free_wbackup_area) (fp);
308 return _IO_UNDERFLOW (fp);
310 libc_hidden_def (__wunderflow)
313 _IO_size_t
314 _IO_wdefault_xsputn (f, data, n)
315 _IO_FILE *f;
316 const void *data;
317 _IO_size_t n;
319 const wchar_t *s = (const wchar_t *) data;
320 _IO_size_t more = n;
321 if (more <= 0)
322 return 0;
323 for (;;)
325 /* Space available. */
326 _IO_ssize_t count = (f->_wide_data->_IO_write_end
327 - f->_wide_data->_IO_write_ptr);
328 if (count > 0)
330 if ((_IO_size_t) count > more)
331 count = more;
332 if (count > 20)
334 #ifdef _LIBC
335 f->_wide_data->_IO_write_ptr =
336 __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
337 #else
338 memcpy (f->_wide_data->_IO_write_ptr, s, count);
339 f->_wide_data->_IO_write_ptr += count;
340 #endif
341 s += count;
343 else if (count <= 0)
344 count = 0;
345 else
347 wchar_t *p = f->_wide_data->_IO_write_ptr;
348 _IO_ssize_t i;
349 for (i = count; --i >= 0; )
350 *p++ = *s++;
351 f->_wide_data->_IO_write_ptr = p;
353 more -= count;
355 if (more == 0 || __woverflow (f, *s++) == WEOF)
356 break;
357 more--;
359 return n - more;
361 INTDEF(_IO_wdefault_xsputn)
364 _IO_size_t
365 _IO_wdefault_xsgetn (fp, data, n)
366 _IO_FILE *fp;
367 void *data;
368 _IO_size_t n;
370 _IO_size_t more = n;
371 wchar_t *s = (wchar_t*) data;
372 for (;;)
374 /* Data available. */
375 _IO_ssize_t count = (fp->_wide_data->_IO_read_end
376 - fp->_wide_data->_IO_read_ptr);
377 if (count > 0)
379 if ((_IO_size_t) count > more)
380 count = more;
381 if (count > 20)
383 #ifdef _LIBC
384 s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
385 #else
386 memcpy (s, fp->_wide_data->_IO_read_ptr, count);
387 s += count;
388 #endif
389 fp->_wide_data->_IO_read_ptr += count;
391 else if (count <= 0)
392 count = 0;
393 else
395 wchar_t *p = fp->_wide_data->_IO_read_ptr;
396 int i = (int) count;
397 while (--i >= 0)
398 *s++ = *p++;
399 fp->_wide_data->_IO_read_ptr = p;
401 more -= count;
403 if (more == 0 || __wunderflow (fp) == WEOF)
404 break;
406 return n - more;
408 INTDEF(_IO_wdefault_xsgetn)
411 void
412 _IO_wdoallocbuf (fp)
413 _IO_FILE *fp;
415 if (fp->_wide_data->_IO_buf_base)
416 return;
417 if (!(fp->_flags & _IO_UNBUFFERED))
418 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
419 return;
420 INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf,
421 fp->_wide_data->_shortbuf + 1, 0);
423 INTDEF(_IO_wdoallocbuf)
427 _IO_wdefault_doallocate (fp)
428 _IO_FILE *fp;
430 wchar_t *buf;
432 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
433 INTUSE(_IO_wsetb) (fp, buf, buf + _IO_BUFSIZ, 1);
434 return 1;
436 INTDEF(_IO_wdefault_doallocate)
440 _IO_switch_to_wget_mode (fp)
441 _IO_FILE *fp;
443 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
444 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
445 return EOF;
446 if (_IO_in_backup (fp))
447 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
448 else
450 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
451 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
452 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
454 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
456 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
457 = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
459 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
460 return 0;
462 INTDEF(_IO_switch_to_wget_mode)
464 void
465 _IO_free_wbackup_area (fp)
466 _IO_FILE *fp;
468 if (_IO_in_backup (fp))
469 INTUSE(_IO_switch_to_main_wget_area) (fp); /* Just in case. */
470 free (fp->_wide_data->_IO_save_base);
471 fp->_wide_data->_IO_save_base = NULL;
472 fp->_wide_data->_IO_save_end = NULL;
473 fp->_wide_data->_IO_backup_base = NULL;
475 INTDEF(_IO_free_wbackup_area)
477 #if 0
479 _IO_switch_to_wput_mode (fp)
480 _IO_FILE *fp;
482 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
483 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
484 /* Following is wrong if line- or un-buffered? */
485 fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
486 ? fp->_wide_data->_IO_read_end
487 : fp->_wide_data->_IO_buf_end);
489 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
490 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
492 fp->_flags |= _IO_CURRENTLY_PUTTING;
493 return 0;
495 #endif
498 static int
499 #ifdef _LIBC
500 internal_function
501 #endif
502 save_for_wbackup (fp, end_p)
503 _IO_FILE *fp;
504 wchar_t *end_p;
506 /* Append [_IO_read_base..end_p] to backup area. */
507 _IO_ssize_t least_mark = INTUSE(_IO_least_wmarker) (fp, end_p);
508 /* needed_size is how much space we need in the backup area. */
509 _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
510 - least_mark);
511 /* FIXME: Dubious arithmetic if pointers are NULL */
512 _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
513 - fp->_wide_data->_IO_save_base);
514 _IO_size_t avail; /* Extra space available for future expansion. */
515 _IO_ssize_t delta;
516 struct _IO_marker *mark;
517 if (needed_size > current_Bsize)
519 wchar_t *new_buffer;
520 avail = 100;
521 new_buffer = (wchar_t *) malloc ((avail + needed_size)
522 * sizeof (wchar_t));
523 if (new_buffer == NULL)
524 return EOF; /* FIXME */
525 if (least_mark < 0)
527 #ifdef _LIBC
528 __wmempcpy (__wmempcpy (new_buffer + avail,
529 fp->_wide_data->_IO_save_end + least_mark,
530 -least_mark),
531 fp->_wide_data->_IO_read_base,
532 end_p - fp->_wide_data->_IO_read_base);
533 #else
534 memcpy (new_buffer + avail,
535 fp->_wide_data->_IO_save_end + least_mark,
536 -least_mark * sizeof (wchar_t));
537 memcpy (new_buffer + avail - least_mark,
538 fp->_wide_data->_IO_read_base,
539 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
540 #endif
542 else
544 #ifdef _LIBC
545 __wmemcpy (new_buffer + avail,
546 fp->_wide_data->_IO_read_base + least_mark,
547 needed_size);
548 #else
549 memcpy (new_buffer + avail,
550 fp->_wide_data->_IO_read_base + least_mark,
551 needed_size * sizeof (wchar_t));
552 #endif
554 free (fp->_wide_data->_IO_save_base);
555 fp->_wide_data->_IO_save_base = new_buffer;
556 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
558 else
560 avail = current_Bsize - needed_size;
561 if (least_mark < 0)
563 #ifdef _LIBC
564 __wmemmove (fp->_wide_data->_IO_save_base + avail,
565 fp->_wide_data->_IO_save_end + least_mark,
566 -least_mark);
567 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
568 fp->_wide_data->_IO_read_base,
569 end_p - fp->_wide_data->_IO_read_base);
570 #else
571 memmove (fp->_wide_data->_IO_save_base + avail,
572 fp->_wide_data->_IO_save_end + least_mark,
573 -least_mark * sizeof (wchar_t));
574 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
575 fp->_wide_data->_IO_read_base,
576 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
577 #endif
579 else if (needed_size > 0)
580 #ifdef _LIBC
581 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
582 fp->_wide_data->_IO_read_base + least_mark,
583 needed_size);
584 #else
585 memcpy (fp->_wide_data->_IO_save_base + avail,
586 fp->_wide_data->_IO_read_base + least_mark,
587 needed_size * sizeof (wchar_t));
588 #endif
590 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
591 /* Adjust all the streammarkers. */
592 delta = end_p - fp->_wide_data->_IO_read_base;
593 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
594 mark->_pos -= delta;
595 return 0;
598 wint_t
599 _IO_sputbackwc (fp, c)
600 _IO_FILE *fp;
601 wint_t c;
603 wint_t result;
605 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
606 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
608 fp->_wide_data->_IO_read_ptr--;
609 result = c;
611 else
612 result = _IO_PBACKFAIL (fp, c);
614 if (result != WEOF)
615 fp->_flags &= ~_IO_EOF_SEEN;
617 return result;
619 INTDEF(_IO_sputbackwc)
621 wint_t
622 _IO_sungetwc (fp)
623 _IO_FILE *fp;
625 wint_t result;
627 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
629 fp->_wide_data->_IO_read_ptr--;
630 result = *fp->_wide_data->_IO_read_ptr;
632 else
633 result = _IO_PBACKFAIL (fp, EOF);
635 if (result != WEOF)
636 fp->_flags &= ~_IO_EOF_SEEN;
638 return result;
642 unsigned
643 _IO_adjust_wcolumn (start, line, count)
644 unsigned start;
645 const wchar_t *line;
646 int count;
648 const wchar_t *ptr = line + count;
649 while (ptr > line)
650 if (*--ptr == L'\n')
651 return line + count - ptr - 1;
652 return start + count;
655 void
656 _IO_init_wmarker (marker, fp)
657 struct _IO_marker *marker;
658 _IO_FILE *fp;
660 marker->_sbuf = fp;
661 if (_IO_in_put_mode (fp))
662 INTUSE(_IO_switch_to_wget_mode) (fp);
663 if (_IO_in_backup (fp))
664 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
665 else
666 marker->_pos = (fp->_wide_data->_IO_read_ptr
667 - fp->_wide_data->_IO_read_base);
669 /* Should perhaps sort the chain? */
670 marker->_next = fp->_markers;
671 fp->_markers = marker;
674 #define BAD_DELTA EOF
676 /* Return difference between MARK and current position of MARK's stream. */
678 _IO_wmarker_delta (mark)
679 struct _IO_marker *mark;
681 int cur_pos;
682 if (mark->_sbuf == NULL)
683 return BAD_DELTA;
684 if (_IO_in_backup (mark->_sbuf))
685 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
686 - mark->_sbuf->_wide_data->_IO_read_end);
687 else
688 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
689 - mark->_sbuf->_wide_data->_IO_read_base);
690 return mark->_pos - cur_pos;
694 _IO_seekwmark (fp, mark, delta)
695 _IO_FILE *fp;
696 struct _IO_marker *mark;
697 int delta;
699 if (mark->_sbuf != fp)
700 return EOF;
701 if (mark->_pos >= 0)
703 if (_IO_in_backup (fp))
704 INTUSE(_IO_switch_to_main_wget_area) (fp);
705 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
706 + mark->_pos);
708 else
710 if (!_IO_in_backup (fp))
711 INTUSE(_IO_switch_to_wbackup_area) (fp);
712 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
714 return 0;
717 void
718 _IO_unsave_wmarkers (fp)
719 _IO_FILE *fp;
721 struct _IO_marker *mark = fp->_markers;
722 if (mark)
724 #ifdef TODO
725 streampos offset = seekoff (0, ios::cur, ios::in);
726 if (offset != EOF)
728 offset += eGptr () - Gbase ();
729 for ( ; mark != NULL; mark = mark->_next)
730 mark->set_streampos (mark->_pos + offset);
732 else
734 for ( ; mark != NULL; mark = mark->_next)
735 mark->set_streampos (EOF);
737 #endif
738 fp->_markers = 0;
741 if (_IO_have_backup (fp))
742 INTUSE(_IO_free_wbackup_area) (fp);