1 /* Copyright (C) 1993, 1995, 1997-2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 As a special exception, if you link the code in this file with
21 files compiled with a GNU compiler to produce an executable,
22 that does not cause the resulting executable to be covered by
23 the GNU Lesser General Public License. This exception does not
24 however invalidate any other reasons why the executable file
25 might be covered by the GNU Lesser General Public License.
26 This exception applies to code released by its copyright holders
27 in files containing the exception. */
31 # define _POSIX_SOURCE
36 #include <sys/types.h>
45 # include "../wcsmbs/wcsmbsload.h"
46 # include "../iconv/gconv_charset.h"
47 # include "../iconv/gconv_int.h"
48 # include <shlib-compat.h>
54 # define __set_errno(Val) errno = (Val)
59 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
60 # define close(FD) __close (FD)
61 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
62 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
63 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
65 # define _IO_new_do_write _IO_do_write
66 # define _IO_new_file_attach _IO_file_attach
67 # define _IO_new_file_close_it _IO_file_close_it
68 # define _IO_new_file_finish _IO_file_finish
69 # define _IO_new_file_fopen _IO_file_fopen
70 # define _IO_new_file_init _IO_file_init
71 # define _IO_new_file_setbuf _IO_file_setbuf
72 # define _IO_new_file_sync _IO_file_sync
73 # define _IO_new_file_overflow _IO_file_overflow
74 # define _IO_new_file_seekoff _IO_file_seekoff
75 # define _IO_new_file_underflow _IO_file_underflow
76 # define _IO_new_file_write _IO_file_write
77 # define _IO_new_file_xsputn _IO_file_xsputn
82 extern struct __gconv_trans_data __libio_translit
;
86 /* An fstream can be in at most one of put mode, get mode, or putback mode.
87 Putback mode is a variant of get mode.
89 In a filebuf, there is only one current position, instead of two
90 separate get and put pointers. In get mode, the current position
91 is that of gptr(); in put mode that of pptr().
93 The position in the buffer that corresponds to the position
94 in external file system is normally _IO_read_end, except in putback
95 mode, when it is _IO_save_end.
96 If the field _fb._offset is >= 0, it gives the offset in
97 the file as a whole corresponding to eGptr(). (?)
100 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
101 and _IO_read_base are equal to each other. These are usually equal
102 to _IO_buf_base, though not necessarily if we have switched from
103 get mode to put mode. (The reason is to maintain the invariant
104 that _IO_read_end corresponds to the external file position.)
105 _IO_write_base is non-NULL and usually equal to _IO_base_base.
106 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
107 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
110 If a filebuf is in get or putback mode, eback() != egptr().
111 In get mode, the unread characters are between gptr() and egptr().
112 The OS file position corresponds to that of egptr().
115 Putback mode is used to remember "excess" characters that have
116 been sputbackc'd in a separate putback buffer.
117 In putback mode, the get buffer points to the special putback buffer.
118 The unread characters are the characters between gptr() and egptr()
119 in the putback buffer, as well as the area between save_gptr()
120 and save_egptr(), which point into the original reserve buffer.
121 (The pointers save_gptr() and save_egptr() are the values
122 of gptr() and egptr() at the time putback mode was entered.)
123 The OS position corresponds to that of save_egptr().
125 LINE BUFFERED OUTPUT:
126 During line buffered output, _IO_write_base==base() && epptr()==base().
127 However, ptr() may be anywhere between base() and ebuf().
128 This forces a call to filebuf::overflow(int C) on every put.
129 If there is more space in the buffer, and C is not a '\n',
130 then C is inserted, and pptr() incremented.
133 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
136 #define CLOSED_FILEBUF_FLAGS \
137 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
141 _IO_new_file_init (fp
)
142 struct _IO_FILE_plus
*fp
;
144 /* POSIX.1 allows another file handle to be used to change the position
145 of our file descriptor. Hence we actually don't know the actual
146 position before we do the first fseek (and until a following fflush). */
147 fp
->file
._offset
= _IO_pos_BAD
;
148 fp
->file
._IO_file_flags
|= CLOSED_FILEBUF_FLAGS
;
151 fp
->file
._fileno
= -1;
155 _IO_new_file_close_it (fp
)
158 int write_status
, close_status
;
159 if (!_IO_file_is_open (fp
))
162 write_status
= _IO_do_flush (fp
);
164 _IO_unsave_markers(fp
);
166 close_status
= _IO_SYSCLOSE (fp
);
171 _IO_setb (fp
, NULL
, NULL
, 0);
172 _IO_setg (fp
, NULL
, NULL
, NULL
);
173 _IO_setp (fp
, NULL
, NULL
);
175 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
178 _IO_wsetb (fp
, NULL
, NULL
, 0);
179 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
180 _IO_wsetp (fp
, NULL
, NULL
);
184 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
185 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
187 fp
->_offset
= _IO_pos_BAD
;
189 return close_status
? close_status
: write_status
;
193 _IO_new_file_finish (fp
, dummy
)
197 if (_IO_file_is_open (fp
))
200 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
203 _IO_default_finish (fp
, 0);
206 #if defined __GNUC__ && __GNUC__ >= 2
210 _IO_file_open (fp
, filename
, posix_mode
, prot
, read_write
, is32not64
)
212 const char *filename
;
221 ? open (filename
, posix_mode
, prot
)
222 : _G_OPEN64 (filename
, posix_mode
, prot
));
224 fdesc
= open (filename
, posix_mode
, prot
);
229 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
230 if (read_write
& _IO_IS_APPENDING
)
231 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_end
, _IOS_INPUT
|_IOS_OUTPUT
)
232 == _IO_pos_BAD
&& errno
!= ESPIPE
)
234 _IO_link_in ((struct _IO_FILE_plus
*) fp
);
239 _IO_new_file_fopen (fp
, filename
, mode
, is32not64
)
241 const char *filename
;
245 int oflags
= 0, omode
;
252 const char *last_recognized
;
255 if (_IO_file_is_open (fp
))
261 read_write
= _IO_NO_WRITES
;
265 oflags
= O_CREAT
|O_TRUNC
;
266 read_write
= _IO_NO_READS
;
270 oflags
= O_CREAT
|O_APPEND
;
271 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
274 __set_errno (EINVAL
);
278 last_recognized
= mode
;
280 for (i
= 1; i
< 4; ++i
)
288 read_write
&= _IO_IS_APPENDING
;
290 last_recognized
= mode
;
296 last_recognized
= mode
;
301 last_recognized
= mode
;
310 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
317 /* Test whether the mode string specifies the conversion. */
318 cs
= strstr (last_recognized
+ 1, ",ccs=");
321 /* Yep. Load the appropriate conversions and set the orientation
323 struct gconv_fcts fcts
;
324 struct _IO_codecvt
*cc
;
325 char *endp
= __strchrnul (cs
+ 5, ',');
326 char ccs
[endp
- (cs
+ 5) + 3];
328 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
331 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
332 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
334 /* Something went wrong, we cannot load the conversion modules.
335 This means we cannot proceed since the user explicitly asked
337 __set_errno (EINVAL
);
341 assert (fcts
.towc_nsteps
== 1);
342 assert (fcts
.tomb_nsteps
== 1);
344 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
345 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
347 /* Clear the state. We start all over again. */
348 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
349 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
351 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
353 /* The functions are always the same. */
354 *cc
= __libio_codecvt
;
356 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
357 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
359 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
360 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
361 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
362 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
364 /* XXX For now no transliteration. */
365 cc
->__cd_in
.__cd
.__data
[0].__trans
= NULL
;
367 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
368 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
370 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
371 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
372 cc
->__cd_out
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
373 cc
->__cd_out
.__cd
.__data
[0].__statep
=
374 &result
->_wide_data
->_IO_state
;
376 /* And now the transliteration. */
377 cc
->__cd_out
.__cd
.__data
[0].__trans
= &__libio_translit
;
379 /* Set the mode now. */
382 /* We don't need the step data structure anymore. */
383 __gconv_release_cache (fcts
.towc
, fcts
.towc_nsteps
);
384 __gconv_release_cache (fcts
.tomb
, fcts
.tomb_nsteps
);
387 #endif /* GNU libc */
393 _IO_new_file_attach (fp
, fd
)
397 if (_IO_file_is_open (fp
))
400 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
401 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
402 /* Get the current position of the file. */
403 /* We have to do that since that may be junk. */
404 fp
->_offset
= _IO_pos_BAD
;
405 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
406 == _IO_pos_BAD
&& errno
!= ESPIPE
)
412 _IO_new_file_setbuf (fp
, p
, len
)
417 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
420 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
422 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
427 static int new_do_write
__P ((_IO_FILE
*, const char *, _IO_size_t
));
429 /* Write TO_DO bytes from DATA to FP.
430 Then mark FP as having empty buffers. */
433 _IO_new_do_write (fp
, data
, to_do
)
438 return (to_do
== 0 || new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
443 new_do_write (fp
, data
, to_do
)
449 if (fp
->_flags
& _IO_IS_APPENDING
)
450 /* On a system without a proper O_APPEND implementation,
451 you would need to sys_seek(0, SEEK_END) here, but is
452 is not needed nor desirable for Unix- or Posix-like systems.
453 Instead, just indicate that offset (before and after) is
455 fp
->_offset
= _IO_pos_BAD
;
456 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
459 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
460 if (new_pos
== _IO_pos_BAD
)
462 fp
->_offset
= new_pos
;
464 count
= _IO_SYSWRITE (fp
, data
, to_do
);
465 if (fp
->_cur_column
&& count
)
466 fp
->_cur_column
= _IO_adjust_column (fp
->_cur_column
- 1, data
, count
) + 1;
467 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
468 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
469 fp
->_IO_write_end
= (fp
->_mode
<= 0
470 && (fp
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
471 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
476 _IO_new_file_underflow (fp
)
481 /* SysV does not make this test; take it out for compatibility */
482 if (fp
->_flags
& _IO_EOF_SEEN
)
486 if (fp
->_flags
& _IO_NO_READS
)
488 fp
->_flags
|= _IO_ERR_SEEN
;
492 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
493 return *(unsigned char *) fp
->_IO_read_ptr
;
495 if (fp
->_IO_buf_base
== NULL
)
497 /* Maybe we already have a push back pointer. */
498 if (fp
->_IO_save_base
!= NULL
)
500 free (fp
->_IO_save_base
);
501 fp
->_flags
&= ~_IO_IN_BACKUP
;
506 /* Flush all line buffered files before reading. */
507 /* FIXME This can/should be moved to genops ?? */
508 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
511 _IO_flush_all_linebuffered ();
513 /* We used to flush all line-buffered stream. This really isn't
514 required by any standard. My recollection is that
515 traditional Unix systems did this for stdout. stderr better
516 not be line buffered. So we do just that here
517 explicitly. --drepper */
518 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile
,
520 _IO_flockfile (_IO_stdout
);
522 if ((_IO_stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
523 == (_IO_LINKED
| _IO_LINE_BUF
))
524 _IO_OVERFLOW (_IO_stdout
, EOF
);
526 _IO_funlockfile (_IO_stdout
);
527 _IO_cleanup_region_end (0);
531 _IO_switch_to_get_mode (fp
);
533 /* This is very tricky. We have to adjust those
534 pointers before we call _IO_SYSREAD () since
535 we may longjump () out while waiting for
536 input. Those pointers may be screwed up. H.J. */
537 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
538 fp
->_IO_read_end
= fp
->_IO_buf_base
;
539 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
542 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
543 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
547 fp
->_flags
|= _IO_EOF_SEEN
;
549 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
551 fp
->_IO_read_end
+= count
;
554 if (fp
->_offset
!= _IO_pos_BAD
)
555 _IO_pos_adjust (fp
->_offset
, count
);
556 return *(unsigned char *) fp
->_IO_read_ptr
;
560 _IO_new_file_overflow (f
, ch
)
564 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
566 f
->_flags
|= _IO_ERR_SEEN
;
570 /* If currently reading or no buffer allocated. */
571 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== 0)
573 /* Allocate a buffer if needed. */
574 if (f
->_IO_write_base
== 0)
577 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
579 /* Otherwise must be currently reading.
580 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
581 logically slide the buffer forwards one block (by setting the
582 read pointers to all point at the beginning of the block). This
583 makes room for subsequent output.
584 Otherwise, set the read pointers to _IO_read_end (leaving that
585 alone, so it can continue to correspond to the external position). */
586 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
587 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
588 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
589 f
->_IO_write_base
= f
->_IO_write_ptr
;
590 f
->_IO_write_end
= f
->_IO_buf_end
;
591 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
593 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
594 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
595 f
->_IO_write_end
= f
->_IO_write_ptr
;
598 return _IO_new_do_write(f
, f
->_IO_write_base
,
599 f
->_IO_write_ptr
- f
->_IO_write_base
);
600 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
601 if (_IO_do_flush (f
) == EOF
)
603 *f
->_IO_write_ptr
++ = ch
;
604 if ((f
->_flags
& _IO_UNBUFFERED
)
605 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
606 if (_IO_new_do_write(f
, f
->_IO_write_base
,
607 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
609 return (unsigned char) ch
;
613 _IO_new_file_sync (fp
)
619 /* char* ptr = cur_ptr(); */
620 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
621 if (_IO_do_flush(fp
)) return EOF
;
622 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
626 if (_IO_in_backup (fp
))
627 delta
-= eGptr () - Gbase ();
629 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
630 if (new_pos
!= (_IO_off64_t
) EOF
)
631 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
633 else if (errno
== ESPIPE
)
634 ; /* Ignore error from unseekable devices. */
640 fp
->_offset
= _IO_pos_BAD
;
641 /* FIXME: Cleanup - can this be shared? */
642 /* setg(base(), ptr, ptr); */
647 _IO_new_file_seekoff (fp
, offset
, dir
, mode
)
654 _IO_off64_t delta
, new_offset
;
656 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
657 offset of the underlying file must be exact. */
658 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
659 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
662 dir
= _IO_seek_cur
, offset
= 0; /* Don't move any pointers. */
664 /* Flush unwritten characters.
665 (This may do an unneeded write if we seek within the buffer.
666 But to be able to switch to reading, we would need to set
667 egptr to ptr. That can't be done in the current design,
668 which assumes file_ptr() is eGptr. Anyway, since we probably
669 end up flushing when we close(), it doesn't make much difference.)
670 FIXME: simulate mem-papped files. */
672 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
|| _IO_in_put_mode (fp
))
673 if (_IO_switch_to_get_mode (fp
))
676 if (fp
->_IO_buf_base
== NULL
)
678 /* It could be that we already have a pushback buffer. */
679 if (fp
->_IO_read_base
!= NULL
)
681 free (fp
->_IO_read_base
);
682 fp
->_flags
&= ~_IO_IN_BACKUP
;
685 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
686 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
692 /* Adjust for read-ahead (bytes is buffer). */
693 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
694 if (fp
->_offset
== _IO_pos_BAD
)
696 /* Make offset absolute, assuming current pointer is file_ptr(). */
697 offset
+= fp
->_offset
;
706 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
708 offset
+= st
.st_size
;
715 /* At this point, dir==_IO_seek_set. */
717 /* If we are only interested in the current position we've found it now. */
721 /* If destination is within current buffer, optimize: */
722 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
723 && !_IO_in_backup (fp
))
725 /* Offset relative to start of main get area. */
726 _IO_off64_t rel_offset
= (offset
- fp
->_offset
727 + (fp
->_IO_read_end
- fp
->_IO_read_base
));
731 if (_IO_in_backup (fp
))
732 _IO_switch_to_main_get_area (fp
);
734 if (rel_offset
<= fp
->_IO_read_end
- fp
->_IO_read_base
)
736 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ rel_offset
,
738 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
740 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
745 /* If we have streammarkers, seek forward by reading ahead. */
746 if (_IO_have_markers (fp
))
748 int to_skip
= rel_offset
749 - (fp
->_IO_read_ptr
- fp
->_IO_read_base
);
750 if (ignore (to_skip
) != to_skip
)
752 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
758 if (rel_offset
< 0 && rel_offset
>= Bbase () - Bptr ())
760 if (!_IO_in_backup (fp
))
761 _IO_switch_to_backup_area (fp
);
762 gbump (fp
->_IO_read_end
+ rel_offset
- fp
->_IO_read_ptr
);
763 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
770 _IO_unsave_markers (fp
);
773 if (fp
->_flags
& _IO_NO_READS
)
776 /* Try to seek to a block boundary, to improve kernel page management. */
777 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
778 delta
= offset
- new_offset
;
779 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
784 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
791 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
793 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
796 /* We weren't allowed to read, but try to seek the remainder. */
797 offset
= count
== EOF
? delta
: delta
-count
;
802 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
803 fp
->_IO_buf_base
+ count
);
804 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
805 fp
->_offset
= result
+ count
;
806 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
810 _IO_unsave_markers (fp
);
811 result
= _IO_SYSSEEK (fp
, offset
, dir
);
814 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
815 fp
->_offset
= result
;
816 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
817 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
822 /* We need to do it since it is possible that the file offset in
823 the kernel may be changed behind our back. It may happen when
824 we fopen a file and then do a fork. One process may access the
825 the file and the kernel file offset will be changed. */
826 if (fp
->_offset
>= 0)
827 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
833 _IO_file_read (fp
, buf
, size
)
838 return read (fp
->_fileno
, buf
, size
);
842 _IO_file_seek (fp
, offset
, dir
)
848 return _G_LSEEK64 (fp
->_fileno
, offset
, dir
);
850 return lseek (fp
->_fileno
, offset
, dir
);
855 _IO_file_stat (fp
, st
)
860 return _G_FSTAT64 (fp
->_fileno
, (struct _G_stat64
*) st
);
862 return fstat (fp
->_fileno
, (struct stat
*) st
);
870 return close (fp
->_fileno
);
874 _IO_new_file_write (f
, data
, n
)
879 _IO_ssize_t to_do
= n
;
882 _IO_ssize_t count
= write (f
->_fileno
, data
, to_do
);
885 f
->_flags
|= _IO_ERR_SEEN
;
889 data
= (void *) ((char *) data
+ count
);
898 _IO_new_file_xsputn (f
, data
, n
)
903 register const char *s
= (const char *) data
;
904 _IO_size_t to_do
= n
;
910 /* This is an optimized implementation.
911 If the amount to be written straddles a block boundary
912 (or the filebuf is unbuffered), use sys_write directly. */
914 /* First figure out how much space is available in the buffer. */
915 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
916 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
918 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
921 register const char *p
;
922 for (p
= s
+ n
; p
> s
; )
933 /* Then fill the buffer. */
941 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
943 memcpy (f
->_IO_write_ptr
, s
, count
);
944 f
->_IO_write_ptr
+= count
;
950 register char *p
= f
->_IO_write_ptr
;
951 register int i
= (int) count
;
954 f
->_IO_write_ptr
= p
;
958 if (to_do
+ must_flush
> 0)
960 _IO_size_t block_size
, do_write
;
961 /* Next flush the (full) buffer. */
962 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
965 /* Try to maintain alignment: write a whole number of blocks.
966 dont_write is what gets left over. */
967 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
968 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
972 count
= new_do_write (f
, s
, do_write
);
974 if (count
< do_write
)
978 /* Now write out the remainder. Normally, this will fit in the
979 buffer, but it's somewhat messier for line-buffered files,
980 so we let _IO_default_xsputn handle the general case. */
982 to_do
-= _IO_default_xsputn (f
, s
+do_write
, to_do
);
988 _IO_file_xsgetn (fp
, data
, n
)
993 register _IO_size_t want
, have
;
994 register _IO_ssize_t count
;
995 register char *s
= data
;
999 if (fp
->_IO_buf_base
== NULL
)
1001 /* Maybe we already have a push back pointer. */
1002 if (fp
->_IO_save_base
!= NULL
)
1004 free (fp
->_IO_save_base
);
1005 fp
->_flags
&= ~_IO_IN_BACKUP
;
1007 _IO_doallocbuf (fp
);
1012 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1015 memcpy (s
, fp
->_IO_read_ptr
, want
);
1016 fp
->_IO_read_ptr
+= want
;
1024 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1026 memcpy (s
, fp
->_IO_read_ptr
, have
);
1030 fp
->_IO_read_ptr
+= have
;
1033 /* Check for backup and repeat */
1034 if (_IO_in_backup (fp
))
1036 _IO_switch_to_main_get_area (fp
);
1040 /* If we now want less than a buffer, underflow and repeat
1041 the copy. Otherwise, _IO_SYSREAD directly to
1043 if (fp
->_IO_buf_base
&& want
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1045 if (__underflow (fp
) == EOF
)
1051 /* These must be set before the sysread as we might longjmp out
1052 waiting for input. */
1053 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1054 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1056 /* Try to maintain alignment: read a whole number of blocks. */
1058 if (fp
->_IO_buf_base
)
1060 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1061 if (block_size
>= 128)
1062 count
-= want
% block_size
;
1065 count
= _IO_SYSREAD (fp
, s
, count
);
1069 fp
->_flags
|= _IO_EOF_SEEN
;
1071 fp
->_flags
|= _IO_ERR_SEEN
;
1078 if (fp
->_offset
!= _IO_pos_BAD
)
1079 _IO_pos_adjust (fp
->_offset
, count
);
1086 struct _IO_jump_t _IO_file_jumps
=
1089 JUMP_INIT(finish
, _IO_new_file_finish
),
1090 JUMP_INIT(overflow
, _IO_new_file_overflow
),
1091 JUMP_INIT(underflow
, _IO_new_file_underflow
),
1092 JUMP_INIT(uflow
, _IO_default_uflow
),
1093 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1094 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1095 JUMP_INIT(xsgetn
, _IO_file_xsgetn
),
1096 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1097 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1098 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1099 JUMP_INIT(sync
, _IO_new_file_sync
),
1100 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1101 JUMP_INIT(read
, _IO_file_read
),
1102 JUMP_INIT(write
, _IO_new_file_write
),
1103 JUMP_INIT(seek
, _IO_file_seek
),
1104 JUMP_INIT(close
, _IO_file_close
),
1105 JUMP_INIT(stat
, _IO_file_stat
),
1106 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1107 JUMP_INIT(imbue
, _IO_default_imbue
)
1111 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1112 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1113 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1114 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1115 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1116 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1117 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1118 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1119 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1120 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1121 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1122 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1123 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);