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
35 #include <sys/types.h>
44 # include "../wcsmbs/wcsmbsload.h"
45 # include <shlib-compat.h>
51 # define __set_errno(Val) errno = (Val)
56 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
57 # define close(FD) __close (FD)
58 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
59 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
60 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
62 # define _IO_new_do_write _IO_do_write
63 # define _IO_new_file_attach _IO_file_attach
64 # define _IO_new_file_close_it _IO_file_close_it
65 # define _IO_new_file_finish _IO_file_finish
66 # define _IO_new_file_fopen _IO_file_fopen
67 # define _IO_new_file_init _IO_file_init
68 # define _IO_new_file_setbuf _IO_file_setbuf
69 # define _IO_new_file_sync _IO_file_sync
70 # define _IO_new_file_overflow _IO_file_overflow
71 # define _IO_new_file_seekoff _IO_file_seekoff
72 # define _IO_new_file_underflow _IO_file_underflow
73 # define _IO_new_file_write _IO_file_write
74 # define _IO_new_file_xsputn _IO_file_xsputn
77 /* An fstream can be in at most one of put mode, get mode, or putback mode.
78 Putback mode is a variant of get mode.
80 In a filebuf, there is only one current position, instead of two
81 separate get and put pointers. In get mode, the current position
82 is that of gptr(); in put mode that of pptr().
84 The position in the buffer that corresponds to the position
85 in external file system is normally _IO_read_end, except in putback
86 mode, when it is _IO_save_end.
87 If the field _fb._offset is >= 0, it gives the offset in
88 the file as a whole corresponding to eGptr(). (?)
91 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
92 and _IO_read_base are equal to each other. These are usually equal
93 to _IO_buf_base, though not necessarily if we have switched from
94 get mode to put mode. (The reason is to maintain the invariant
95 that _IO_read_end corresponds to the external file position.)
96 _IO_write_base is non-NULL and usually equal to _IO_base_base.
97 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
98 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
101 If a filebuf is in get or putback mode, eback() != egptr().
102 In get mode, the unread characters are between gptr() and egptr().
103 The OS file position corresponds to that of egptr().
106 Putback mode is used to remember "excess" characters that have
107 been sputbackc'd in a separate putback buffer.
108 In putback mode, the get buffer points to the special putback buffer.
109 The unread characters are the characters between gptr() and egptr()
110 in the putback buffer, as well as the area between save_gptr()
111 and save_egptr(), which point into the original reserve buffer.
112 (The pointers save_gptr() and save_egptr() are the values
113 of gptr() and egptr() at the time putback mode was entered.)
114 The OS position corresponds to that of save_egptr().
116 LINE BUFFERED OUTPUT:
117 During line buffered output, _IO_write_base==base() && epptr()==base().
118 However, ptr() may be anywhere between base() and ebuf().
119 This forces a call to filebuf::overflow(int C) on every put.
120 If there is more space in the buffer, and C is not a '\n',
121 then C is inserted, and pptr() incremented.
124 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
127 #define CLOSED_FILEBUF_FLAGS \
128 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
132 _IO_new_file_init (fp
)
133 struct _IO_FILE_plus
*fp
;
135 /* POSIX.1 allows another file handle to be used to change the position
136 of our file descriptor. Hence we actually don't know the actual
137 position before we do the first fseek (and until a following fflush). */
138 fp
->file
._offset
= _IO_pos_BAD
;
139 fp
->file
._IO_file_flags
|= CLOSED_FILEBUF_FLAGS
;
142 fp
->file
._fileno
= -1;
146 _IO_new_file_close_it (fp
)
149 int write_status
, close_status
;
150 if (!_IO_file_is_open (fp
))
153 write_status
= _IO_do_flush (fp
);
155 _IO_unsave_markers(fp
);
157 close_status
= _IO_SYSCLOSE (fp
);
162 _IO_setb (fp
, NULL
, NULL
, 0);
163 _IO_setg (fp
, NULL
, NULL
, NULL
);
164 _IO_setp (fp
, NULL
, NULL
);
166 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
169 _IO_wsetb (fp
, NULL
, NULL
, 0);
170 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
171 _IO_wsetp (fp
, NULL
, NULL
);
175 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
176 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
178 fp
->_offset
= _IO_pos_BAD
;
180 return close_status
? close_status
: write_status
;
184 _IO_new_file_finish (fp
, dummy
)
188 if (_IO_file_is_open (fp
))
191 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
194 _IO_default_finish (fp
, 0);
197 #if defined __GNUC__ && __GNUC__ >= 2
201 _IO_file_open (fp
, filename
, posix_mode
, prot
, read_write
, is32not64
)
203 const char *filename
;
212 ? open (filename
, posix_mode
, prot
)
213 : _G_OPEN64 (filename
, posix_mode
, prot
));
215 fdesc
= open (filename
, posix_mode
, prot
);
220 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
221 if (read_write
& _IO_IS_APPENDING
)
222 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_end
, _IOS_INPUT
|_IOS_OUTPUT
)
223 == _IO_pos_BAD
&& errno
!= ESPIPE
)
225 _IO_link_in ((struct _IO_FILE_plus
*) fp
);
230 _IO_new_file_fopen (fp
, filename
, mode
, is32not64
)
232 const char *filename
;
236 int oflags
= 0, omode
;
245 if (_IO_file_is_open (fp
))
251 read_write
= _IO_NO_WRITES
;
255 oflags
= O_CREAT
|O_TRUNC
;
256 read_write
= _IO_NO_READS
;
260 oflags
= O_CREAT
|O_APPEND
;
261 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
264 __set_errno (EINVAL
);
267 for (i
= 1; i
< 4; ++i
)
275 read_write
&= _IO_IS_APPENDING
;
288 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
293 /* Test whether the mode string specifies the conversion. */
294 cs
= strstr (mode
, ",ccs=");
297 /* Yep. Load the appropriate conversions and set the orientation
299 struct gconv_fcts fcts
;
300 struct _IO_codecvt
*cc
;
302 if (! _IO_CHECK_WIDE (fp
) || __wcsmbs_named_conv (&fcts
, cs
+ 5) != 0)
304 /* Something went wrong, we cannot load the conversion modules.
305 This means we cannot proceed since the user explicitly asked
307 _IO_new_fclose (result
);
311 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
313 /* The functions are always the same. */
314 *cc
= __libio_codecvt
;
316 cc
->__cd_in
.__cd
.__nsteps
= 1; /* Only one step allowed. */
317 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
319 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
320 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
321 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
322 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
324 cc
->__cd_out
.__cd
.__nsteps
= 1; /* Only one step allowed. */
325 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
327 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
328 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
329 cc
->__cd_out
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
330 cc
->__cd_out
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
332 /* Set the mode now. */
335 #endif /* GNU libc */
341 _IO_new_file_attach (fp
, fd
)
345 if (_IO_file_is_open (fp
))
348 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
349 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
350 /* Get the current position of the file. */
351 /* We have to do that since that may be junk. */
352 fp
->_offset
= _IO_pos_BAD
;
353 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
354 == _IO_pos_BAD
&& errno
!= ESPIPE
)
360 _IO_new_file_setbuf (fp
, p
, len
)
365 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
368 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
370 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
375 static int new_do_write
__P ((_IO_FILE
*, const char *, _IO_size_t
));
377 /* Write TO_DO bytes from DATA to FP.
378 Then mark FP as having empty buffers. */
381 _IO_new_do_write (fp
, data
, to_do
)
386 return (to_do
== 0 || new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
391 new_do_write (fp
, data
, to_do
)
397 if (fp
->_flags
& _IO_IS_APPENDING
)
398 /* On a system without a proper O_APPEND implementation,
399 you would need to sys_seek(0, SEEK_END) here, but is
400 is not needed nor desirable for Unix- or Posix-like systems.
401 Instead, just indicate that offset (before and after) is
403 fp
->_offset
= _IO_pos_BAD
;
404 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
407 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
408 if (new_pos
== _IO_pos_BAD
)
410 fp
->_offset
= new_pos
;
412 count
= _IO_SYSWRITE (fp
, data
, to_do
);
413 if (fp
->_cur_column
&& count
)
414 fp
->_cur_column
= _IO_adjust_column (fp
->_cur_column
- 1, data
, count
) + 1;
415 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
416 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
417 fp
->_IO_write_end
= (fp
->_mode
<= 0
418 && (fp
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
419 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
424 _IO_new_file_underflow (fp
)
429 /* SysV does not make this test; take it out for compatibility */
430 if (fp
->_flags
& _IO_EOF_SEEN
)
434 if (fp
->_flags
& _IO_NO_READS
)
436 fp
->_flags
|= _IO_ERR_SEEN
;
440 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
441 return *(unsigned char *) fp
->_IO_read_ptr
;
443 if (fp
->_IO_buf_base
== NULL
)
445 /* Maybe we already have a push back pointer. */
446 if (fp
->_IO_save_base
!= NULL
)
448 free (fp
->_IO_save_base
);
449 fp
->_flags
&= ~_IO_IN_BACKUP
;
454 /* Flush all line buffered files before reading. */
455 /* FIXME This can/should be moved to genops ?? */
456 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
457 _IO_flush_all_linebuffered ();
459 _IO_switch_to_get_mode (fp
);
461 /* This is very tricky. We have to adjust those
462 pointers before we call _IO_SYSREAD () since
463 we may longjump () out while waiting for
464 input. Those pointers may be screwed up. H.J. */
465 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
466 fp
->_IO_read_end
= fp
->_IO_buf_base
;
467 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
470 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
471 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
475 fp
->_flags
|= _IO_EOF_SEEN
;
477 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
479 fp
->_IO_read_end
+= count
;
482 if (fp
->_offset
!= _IO_pos_BAD
)
483 _IO_pos_adjust (fp
->_offset
, count
);
484 return *(unsigned char *) fp
->_IO_read_ptr
;
488 _IO_new_file_overflow (f
, ch
)
492 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
494 f
->_flags
|= _IO_ERR_SEEN
;
498 /* If currently reading or no buffer allocated. */
499 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== 0)
501 /* Allocate a buffer if needed. */
502 if (f
->_IO_write_base
== 0)
505 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
507 /* Otherwise must be currently reading.
508 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
509 logically slide the buffer forwards one block (by setting the
510 read pointers to all point at the beginning of the block). This
511 makes room for subsequent output.
512 Otherwise, set the read pointers to _IO_read_end (leaving that
513 alone, so it can continue to correspond to the external position). */
514 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
515 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
516 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
517 f
->_IO_write_base
= f
->_IO_write_ptr
;
518 f
->_IO_write_end
= f
->_IO_buf_end
;
519 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
521 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
522 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
523 f
->_IO_write_end
= f
->_IO_write_ptr
;
526 return _IO_new_do_write(f
, f
->_IO_write_base
,
527 f
->_IO_write_ptr
- f
->_IO_write_base
);
528 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
529 if (_IO_do_flush (f
) == EOF
)
531 *f
->_IO_write_ptr
++ = ch
;
532 if ((f
->_flags
& _IO_UNBUFFERED
)
533 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
534 if (_IO_new_do_write(f
, f
->_IO_write_base
,
535 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
537 return (unsigned char) ch
;
541 _IO_new_file_sync (fp
)
547 /* char* ptr = cur_ptr(); */
548 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
549 if (_IO_do_flush(fp
)) return EOF
;
550 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
554 if (_IO_in_backup (fp
))
555 delta
-= eGptr () - Gbase ();
557 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
558 if (new_pos
!= (_IO_off64_t
) EOF
)
559 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
561 else if (errno
== ESPIPE
)
562 ; /* Ignore error from unseekable devices. */
568 fp
->_offset
= _IO_pos_BAD
;
569 /* FIXME: Cleanup - can this be shared? */
570 /* setg(base(), ptr, ptr); */
575 _IO_new_file_seekoff (fp
, offset
, dir
, mode
)
582 _IO_off64_t delta
, new_offset
;
584 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
585 offset of the underlying file must be exact. */
586 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
587 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
590 dir
= _IO_seek_cur
, offset
= 0; /* Don't move any pointers. */
592 /* Flush unwritten characters.
593 (This may do an unneeded write if we seek within the buffer.
594 But to be able to switch to reading, we would need to set
595 egptr to ptr. That can't be done in the current design,
596 which assumes file_ptr() is eGptr. Anyway, since we probably
597 end up flushing when we close(), it doesn't make much difference.)
598 FIXME: simulate mem-papped files. */
600 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
|| _IO_in_put_mode (fp
))
601 if (_IO_switch_to_get_mode (fp
))
604 if (fp
->_IO_buf_base
== NULL
)
606 /* It could be that we already have a pushback buffer. */
607 if (fp
->_IO_read_base
!= NULL
)
609 free (fp
->_IO_read_base
);
610 fp
->_flags
&= ~_IO_IN_BACKUP
;
613 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
614 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
620 /* Adjust for read-ahead (bytes is buffer). */
621 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
622 if (fp
->_offset
== _IO_pos_BAD
)
624 /* Make offset absolute, assuming current pointer is file_ptr(). */
625 offset
+= fp
->_offset
;
634 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
636 offset
+= st
.st_size
;
643 /* At this point, dir==_IO_seek_set. */
645 /* If we are only interested in the current position we've found it now. */
649 /* If destination is within current buffer, optimize: */
650 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
651 && !_IO_in_backup (fp
))
653 /* Offset relative to start of main get area. */
654 _IO_off64_t rel_offset
= (offset
- fp
->_offset
655 + (fp
->_IO_read_end
- fp
->_IO_read_base
));
659 if (_IO_in_backup (fp
))
660 _IO_switch_to_main_get_area (fp
);
662 if (rel_offset
<= fp
->_IO_read_end
- fp
->_IO_read_base
)
664 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ rel_offset
,
666 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
668 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
673 /* If we have streammarkers, seek forward by reading ahead. */
674 if (_IO_have_markers (fp
))
676 int to_skip
= rel_offset
677 - (fp
->_IO_read_ptr
- fp
->_IO_read_base
);
678 if (ignore (to_skip
) != to_skip
)
680 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
686 if (rel_offset
< 0 && rel_offset
>= Bbase () - Bptr ())
688 if (!_IO_in_backup (fp
))
689 _IO_switch_to_backup_area (fp
);
690 gbump (fp
->_IO_read_end
+ rel_offset
- fp
->_IO_read_ptr
);
691 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
698 _IO_unsave_markers (fp
);
701 if (fp
->_flags
& _IO_NO_READS
)
704 /* Try to seek to a block boundary, to improve kernel page management. */
705 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
706 delta
= offset
- new_offset
;
707 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
712 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
719 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
721 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
724 /* We weren't allowed to read, but try to seek the remainder. */
725 offset
= count
== EOF
? delta
: delta
-count
;
730 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
731 fp
->_IO_buf_base
+ count
);
732 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
733 fp
->_offset
= result
+ count
;
734 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
738 _IO_unsave_markers (fp
);
739 result
= _IO_SYSSEEK (fp
, offset
, dir
);
742 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
743 fp
->_offset
= result
;
744 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
745 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
750 /* We need to do it since it is possible that the file offset in
751 the kernel may be changed behind our back. It may happen when
752 we fopen a file and then do a fork. One process may access the
753 the file and the kernel file offset will be changed. */
754 if (fp
->_offset
>= 0)
755 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
761 _IO_file_read (fp
, buf
, size
)
766 return read (fp
->_fileno
, buf
, size
);
770 _IO_file_seek (fp
, offset
, dir
)
776 return _G_LSEEK64 (fp
->_fileno
, offset
, dir
);
778 return lseek (fp
->_fileno
, offset
, dir
);
783 _IO_file_stat (fp
, st
)
788 return _G_FSTAT64 (fp
->_fileno
, (struct _G_stat64
*) st
);
790 return fstat (fp
->_fileno
, (struct stat
*) st
);
798 return close (fp
->_fileno
);
802 _IO_new_file_write (f
, data
, n
)
807 _IO_ssize_t to_do
= n
;
810 _IO_ssize_t count
= write (f
->_fileno
, data
, to_do
);
813 f
->_flags
|= _IO_ERR_SEEN
;
817 data
= (void *) ((char *) data
+ count
);
826 _IO_new_file_xsputn (f
, data
, n
)
831 register const char *s
= (const char *) data
;
832 _IO_size_t to_do
= n
;
838 /* This is an optimized implementation.
839 If the amount to be written straddles a block boundary
840 (or the filebuf is unbuffered), use sys_write directly. */
842 /* First figure out how much space is available in the buffer. */
843 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
844 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
846 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
849 register const char *p
;
850 for (p
= s
+ n
; p
> s
; )
861 /* Then fill the buffer. */
869 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
871 memcpy (f
->_IO_write_ptr
, s
, count
);
872 f
->_IO_write_ptr
+= count
;
878 register char *p
= f
->_IO_write_ptr
;
879 register int i
= (int) count
;
882 f
->_IO_write_ptr
= p
;
886 if (to_do
+ must_flush
> 0)
888 _IO_size_t block_size
, do_write
;
889 /* Next flush the (full) buffer. */
890 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
893 /* Try to maintain alignment: write a whole number of blocks.
894 dont_write is what gets left over. */
895 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
896 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
900 count
= new_do_write (f
, s
, do_write
);
902 if (count
< do_write
)
906 /* Now write out the remainder. Normally, this will fit in the
907 buffer, but it's somewhat messier for line-buffered files,
908 so we let _IO_default_xsputn handle the general case. */
910 to_do
-= _IO_default_xsputn (f
, s
+do_write
, to_do
);
916 _IO_file_xsgetn (fp
, data
, n
)
921 register _IO_size_t want
, have
;
922 register _IO_ssize_t count
;
923 register char *s
= data
;
927 if (fp
->_IO_buf_base
== NULL
)
929 /* Maybe we already have a push back pointer. */
930 if (fp
->_IO_save_base
!= NULL
)
932 free (fp
->_IO_save_base
);
933 fp
->_flags
&= ~_IO_IN_BACKUP
;
940 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
943 memcpy (s
, fp
->_IO_read_ptr
, want
);
944 fp
->_IO_read_ptr
+= want
;
952 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
954 memcpy (s
, fp
->_IO_read_ptr
, have
);
958 fp
->_IO_read_ptr
+= have
;
961 /* Check for backup and repeat */
962 if (_IO_in_backup (fp
))
964 _IO_switch_to_main_get_area (fp
);
968 /* If we now want less than a buffer, underflow and repeat
969 the copy. Otherwise, _IO_SYSREAD directly to
971 if (fp
->_IO_buf_base
&& want
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
973 if (__underflow (fp
) == EOF
)
979 /* These must be set before the sysread as we might longjmp out
980 waiting for input. */
981 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
982 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
984 /* Try to maintain alignment: read a whole number of blocks. */
986 if (fp
->_IO_buf_base
)
988 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
989 if (block_size
>= 128)
990 count
-= want
% block_size
;
993 count
= _IO_SYSREAD (fp
, s
, count
);
997 fp
->_flags
|= _IO_EOF_SEEN
;
999 fp
->_flags
|= _IO_ERR_SEEN
;
1006 if (fp
->_offset
!= _IO_pos_BAD
)
1007 _IO_pos_adjust (fp
->_offset
, count
);
1014 struct _IO_jump_t _IO_file_jumps
=
1017 JUMP_INIT(finish
, _IO_new_file_finish
),
1018 JUMP_INIT(overflow
, _IO_new_file_overflow
),
1019 JUMP_INIT(underflow
, _IO_new_file_underflow
),
1020 JUMP_INIT(uflow
, _IO_default_uflow
),
1021 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1022 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1023 JUMP_INIT(xsgetn
, _IO_file_xsgetn
),
1024 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1025 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1026 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1027 JUMP_INIT(sync
, _IO_new_file_sync
),
1028 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1029 JUMP_INIT(read
, _IO_file_read
),
1030 JUMP_INIT(write
, _IO_new_file_write
),
1031 JUMP_INIT(seek
, _IO_file_seek
),
1032 JUMP_INIT(close
, _IO_file_close
),
1033 JUMP_INIT(stat
, _IO_file_stat
),
1034 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1035 JUMP_INIT(imbue
, _IO_default_imbue
)
1039 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1040 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1041 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1042 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1043 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1044 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1045 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1046 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1047 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1048 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1049 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1050 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1051 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);