Update.
[glibc.git] / libio / fileops.c
blob8930f6f3cd22b6f4baa4131e628c80b9e3e3e93b
1 /* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
3 Written by Per Bothner <bothner@cygnus.com>.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2, or (at
8 your option) any later version.
10 This library is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to
17 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
18 MA 02111-1307, USA.
20 As a special exception, if you link this library with files
21 compiled with a GNU compiler to produce an executable, this does
22 not cause the resulting executable to be covered by the GNU General
23 Public License. This exception does not however invalidate any
24 other reasons why the executable file might be covered by the GNU
25 General Public License. */
28 #ifndef _POSIX_SOURCE
29 # define _POSIX_SOURCE
30 #endif
31 #include "libioP.h"
32 #include <fcntl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <string.h>
36 #include <errno.h>
37 #ifdef __STDC__
38 #include <stdlib.h>
39 #endif
40 #ifndef errno
41 extern int errno;
42 #endif
43 #ifndef __set_errno
44 # define __set_errno(Val) errno = (Val)
45 #endif
48 #ifdef _LIBC
49 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
50 # define close(FD) __close (FD)
51 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
52 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
53 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
54 #endif
56 /* An fstream can be in at most one of put mode, get mode, or putback mode.
57 Putback mode is a variant of get mode.
59 In a filebuf, there is only one current position, instead of two
60 separate get and put pointers. In get mode, the current position
61 is that of gptr(); in put mode that of pptr().
63 The position in the buffer that corresponds to the position
64 in external file system is normally _IO_read_end, except in putback
65 mode, when it is _IO_save_end.
66 If the field _fb._offset is >= 0, it gives the offset in
67 the file as a whole corresponding to eGptr(). (?)
69 PUT MODE:
70 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
71 and _IO_read_base are equal to each other. These are usually equal
72 to _IO_buf_base, though not necessarily if we have switched from
73 get mode to put mode. (The reason is to maintain the invariant
74 that _IO_read_end corresponds to the external file position.)
75 _IO_write_base is non-NULL and usually equal to _IO_base_base.
76 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
77 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
79 GET MODE:
80 If a filebuf is in get or putback mode, eback() != egptr().
81 In get mode, the unread characters are between gptr() and egptr().
82 The OS file position corresponds to that of egptr().
84 PUTBACK MODE:
85 Putback mode is used to remember "excess" characters that have
86 been sputbackc'd in a separate putback buffer.
87 In putback mode, the get buffer points to the special putback buffer.
88 The unread characters are the characters between gptr() and egptr()
89 in the putback buffer, as well as the area between save_gptr()
90 and save_egptr(), which point into the original reserve buffer.
91 (The pointers save_gptr() and save_egptr() are the values
92 of gptr() and egptr() at the time putback mode was entered.)
93 The OS position corresponds to that of save_egptr().
95 LINE BUFFERED OUTPUT:
96 During line buffered output, _IO_write_base==base() && epptr()==base().
97 However, ptr() may be anywhere between base() and ebuf().
98 This forces a call to filebuf::overflow(int C) on every put.
99 If there is more space in the buffer, and C is not a '\n',
100 then C is inserted, and pptr() incremented.
102 UNBUFFERED STREAMS:
103 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
106 #define CLOSED_FILEBUF_FLAGS \
107 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
110 void
111 _IO_new_file_init (fp)
112 _IO_FILE *fp;
114 /* POSIX.1 allows another file handle to be used to change the position
115 of our file descriptor. Hence we actually don't know the actual
116 position before we do the first fseek (and until a following fflush). */
117 fp->_offset = _IO_pos_BAD;
118 fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
120 _IO_link_in(fp);
121 fp->_fileno = -1;
125 _IO_new_file_close_it (fp)
126 _IO_FILE *fp;
128 int write_status, close_status;
129 if (!_IO_file_is_open (fp))
130 return EOF;
132 write_status = _IO_do_flush (fp);
134 _IO_unsave_markers(fp);
136 close_status = _IO_SYSCLOSE (fp);
138 /* Free buffer. */
139 _IO_setb (fp, NULL, NULL, 0);
140 _IO_setg (fp, NULL, NULL, NULL);
141 _IO_setp (fp, NULL, NULL);
143 _IO_un_link (fp);
144 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
145 fp->_fileno = EOF;
146 fp->_offset = _IO_pos_BAD;
148 return close_status ? close_status : write_status;
151 void
152 _IO_new_file_finish (fp, dummy)
153 _IO_FILE *fp;
154 int dummy;
156 if (_IO_file_is_open (fp))
158 _IO_do_flush (fp);
159 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
160 _IO_SYSCLOSE (fp);
162 _IO_default_finish (fp, 0);
165 #if defined __GNUC__ && __GNUC__ >= 2
166 __inline__
167 #endif
168 _IO_FILE *
169 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
170 _IO_FILE *fp;
171 const char *filename;
172 int posix_mode;
173 int prot;
174 int read_write;
175 int is32not64;
177 int fdesc;
178 #ifdef _G_OPEN64
179 fdesc = (is32not64
180 ? open (filename, posix_mode, prot)
181 : _G_OPEN64 (filename, posix_mode, prot));
182 #else
183 fdesc = open (filename, posix_mode, prot);
184 #endif
185 if (fdesc < 0)
186 return NULL;
187 fp->_fileno = fdesc;
188 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
189 if (read_write & _IO_IS_APPENDING)
190 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
191 == _IO_pos_BAD && errno != ESPIPE)
192 return NULL;
193 _IO_link_in (fp);
194 return fp;
197 _IO_FILE *
198 _IO_new_file_fopen (fp, filename, mode, is32not64)
199 _IO_FILE *fp;
200 const char *filename;
201 const char *mode;
202 int is32not64;
204 int oflags = 0, omode;
205 int read_write;
206 int oprot = 0666;
207 int i;
208 if (_IO_file_is_open (fp))
209 return 0;
210 switch (*mode)
212 case 'r':
213 omode = O_RDONLY;
214 read_write = _IO_NO_WRITES;
215 break;
216 case 'w':
217 omode = O_WRONLY;
218 oflags = O_CREAT|O_TRUNC;
219 read_write = _IO_NO_READS;
220 break;
221 case 'a':
222 omode = O_WRONLY;
223 oflags = O_CREAT|O_APPEND;
224 read_write = _IO_NO_READS|_IO_IS_APPENDING;
225 break;
226 default:
227 __set_errno (EINVAL);
228 return NULL;
230 for (i = 1; i < 4; ++i)
232 switch (*++mode)
234 case '\0':
235 break;
236 case '+':
237 omode = O_RDWR;
238 read_write &= _IO_IS_APPENDING;
239 continue;
240 case 'x':
241 oflags |= O_EXCL;
242 continue;
243 case 'b':
244 default:
245 /* Ignore. */
246 continue;
248 break;
251 return _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
252 is32not64);
255 _IO_FILE *
256 _IO_new_file_attach (fp, fd)
257 _IO_FILE *fp;
258 int fd;
260 if (_IO_file_is_open (fp))
261 return NULL;
262 fp->_fileno = fd;
263 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
264 fp->_flags |= _IO_DELETE_DONT_CLOSE;
265 /* Get the current position of the file. */
266 /* We have to do that since that may be junk. */
267 fp->_offset = _IO_pos_BAD;
268 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
269 == _IO_pos_BAD && errno != ESPIPE)
270 return NULL;
271 return fp;
274 _IO_FILE *
275 _IO_new_file_setbuf (fp, p, len)
276 _IO_FILE *fp;
277 char *p;
278 _IO_ssize_t len;
280 if (_IO_default_setbuf (fp, p, len) == NULL)
281 return NULL;
283 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
284 = fp->_IO_buf_base;
285 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
287 return fp;
290 /* Write TO_DO bytes from DATA to FP.
291 Then mark FP as having empty buffers. */
294 _IO_new_do_write (fp, data, to_do)
295 _IO_FILE *fp;
296 const char *data;
297 _IO_size_t to_do;
299 _IO_size_t count;
300 if (to_do == 0)
301 return 0;
302 if (fp->_flags & _IO_IS_APPENDING)
303 /* On a system without a proper O_APPEND implementation,
304 you would need to sys_seek(0, SEEK_END) here, but is
305 is not needed nor desirable for Unix- or Posix-like systems.
306 Instead, just indicate that offset (before and after) is
307 unpredictable. */
308 fp->_offset = _IO_pos_BAD;
309 else if (fp->_IO_read_end != fp->_IO_write_base)
311 _IO_fpos64_t new_pos
312 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
313 if (new_pos == _IO_pos_BAD)
314 return EOF;
315 fp->_offset = new_pos;
317 count = _IO_SYSWRITE (fp, data, to_do);
318 if (fp->_cur_column)
319 fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, to_do) + 1;
320 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
321 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
322 fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
323 ? fp->_IO_buf_base : fp->_IO_buf_end);
324 return count != to_do ? EOF : 0;
328 _IO_new_file_underflow (fp)
329 _IO_FILE *fp;
331 _IO_ssize_t count;
332 #if 0
333 /* SysV does not make this test; take it out for compatibility */
334 if (fp->_flags & _IO_EOF_SEEN)
335 return (EOF);
336 #endif
338 if (fp->_flags & _IO_NO_READS)
340 __set_errno (EBADF);
341 return EOF;
343 if (fp->_IO_read_ptr < fp->_IO_read_end)
344 return *(unsigned char *) fp->_IO_read_ptr;
346 if (fp->_IO_buf_base == NULL)
348 /* Maybe we already have a push back pointer. */
349 if (fp->_IO_save_base != NULL)
351 free (fp->_IO_save_base);
352 fp->_flags &= ~_IO_IN_BACKUP;
354 _IO_doallocbuf (fp);
357 /* Flush all line buffered files before reading. */
358 /* FIXME This can/should be moved to genops ?? */
359 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
360 _IO_flush_all_linebuffered ();
362 _IO_switch_to_get_mode (fp);
364 /* This is very tricky. We have to adjust those
365 pointers before we call _IO_SYSREAD () since
366 we may longjump () out while waiting for
367 input. Those pointers may be screwed up. H.J. */
368 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
369 fp->_IO_read_end = fp->_IO_buf_base;
370 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
371 = fp->_IO_buf_base;
373 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
374 fp->_IO_buf_end - fp->_IO_buf_base);
375 if (count <= 0)
377 if (count == 0)
378 fp->_flags |= _IO_EOF_SEEN;
379 else
380 fp->_flags |= _IO_ERR_SEEN, count = 0;
382 fp->_IO_read_end += count;
383 if (count == 0)
384 return EOF;
385 if (fp->_offset != _IO_pos_BAD)
386 _IO_pos_adjust (fp->_offset, count);
387 return *(unsigned char *) fp->_IO_read_ptr;
391 _IO_new_file_overflow (f, ch)
392 _IO_FILE *f;
393 int ch;
395 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
397 f->_flags |= _IO_ERR_SEEN;
398 __set_errno (EBADF);
399 return EOF;
401 /* If currently reading or no buffer allocated. */
402 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
404 /* Allocate a buffer if needed. */
405 if (f->_IO_write_base == 0)
407 _IO_doallocbuf (f);
408 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
410 /* Otherwise must be currently reading.
411 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
412 logically slide the buffer forwards one block (by setting the
413 read pointers to all point at the beginning of the block). This
414 makes room for subsequent output.
415 Otherwise, set the read pointers to _IO_read_end (leaving that
416 alone, so it can continue to correspond to the external position). */
417 if (f->_IO_read_ptr == f->_IO_buf_end)
418 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
419 f->_IO_write_ptr = f->_IO_read_ptr;
420 f->_IO_write_base = f->_IO_write_ptr;
421 f->_IO_write_end = f->_IO_buf_end;
422 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
424 f->_flags |= _IO_CURRENTLY_PUTTING;
425 if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
426 f->_IO_write_end = f->_IO_write_ptr;
428 if (ch == EOF)
429 return _IO_do_flush (f);
430 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
431 if (_IO_do_flush (f) == EOF)
432 return EOF;
433 *f->_IO_write_ptr++ = ch;
434 if ((f->_flags & _IO_UNBUFFERED)
435 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
436 if (_IO_do_flush (f) == EOF)
437 return EOF;
438 return (unsigned char) ch;
442 _IO_new_file_sync (fp)
443 _IO_FILE *fp;
445 _IO_ssize_t delta;
446 int retval = 0;
448 /* char* ptr = cur_ptr(); */
449 if (fp->_IO_write_ptr > fp->_IO_write_base)
450 if (_IO_do_flush(fp)) return EOF;
451 delta = fp->_IO_read_ptr - fp->_IO_read_end;
452 if (delta != 0)
454 #ifdef TODO
455 if (_IO_in_backup (fp))
456 delta -= eGptr () - Gbase ();
457 #endif
458 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
459 if (new_pos != (_IO_off64_t) EOF)
460 fp->_IO_read_end = fp->_IO_read_ptr;
461 #ifdef ESPIPE
462 else if (errno == ESPIPE)
463 ; /* Ignore error from unseekable devices. */
464 #endif
465 else
466 retval = EOF;
468 if (retval != EOF)
469 fp->_offset = _IO_pos_BAD;
470 /* FIXME: Cleanup - can this be shared? */
471 /* setg(base(), ptr, ptr); */
472 return retval;
475 _IO_fpos64_t
476 _IO_new_file_seekoff (fp, offset, dir, mode)
477 _IO_FILE *fp;
478 _IO_off64_t offset;
479 int dir;
480 int mode;
482 _IO_fpos64_t result;
483 _IO_off64_t delta, new_offset;
484 long count;
485 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
486 offset of the underlying file must be exact. */
487 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
488 && fp->_IO_write_base == fp->_IO_write_ptr);
490 if (mode == 0)
491 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
493 /* Flush unwritten characters.
494 (This may do an unneeded write if we seek within the buffer.
495 But to be able to switch to reading, we would need to set
496 egptr to ptr. That can't be done in the current design,
497 which assumes file_ptr() is eGptr. Anyway, since we probably
498 end up flushing when we close(), it doesn't make much difference.)
499 FIXME: simulate mem-papped files. */
501 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
502 if (_IO_switch_to_get_mode (fp))
503 return EOF;
505 if (fp->_IO_buf_base == NULL)
507 /* It could be that we already have a pushback buffer. */
508 if (fp->_IO_read_base != NULL)
510 free (fp->_IO_read_base);
511 fp->_flags &= ~_IO_IN_BACKUP;
513 _IO_doallocbuf (fp);
514 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
515 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
518 switch (dir)
520 case _IO_seek_cur:
521 /* Adjust for read-ahead (bytes is buffer). */
522 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
523 if (fp->_offset == _IO_pos_BAD)
524 goto dumb;
525 /* Make offset absolute, assuming current pointer is file_ptr(). */
526 offset += _IO_pos_as_off (fp->_offset);
528 dir = _IO_seek_set;
529 break;
530 case _IO_seek_set:
531 break;
532 case _IO_seek_end:
534 struct _G_stat64 st;
535 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
537 offset += st.st_size;
538 dir = _IO_seek_set;
540 else
541 goto dumb;
544 /* At this point, dir==_IO_seek_set. */
546 /* If we are only interested in the current position we've found it now. */
547 if (mode == 0)
548 return offset;
550 /* If destination is within current buffer, optimize: */
551 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
552 && !_IO_in_backup (fp))
554 /* Offset relative to start of main get area. */
555 _IO_fpos64_t rel_offset = (offset - fp->_offset
556 + (fp->_IO_read_end - fp->_IO_read_base));
557 if (rel_offset >= 0)
559 #if 0
560 if (_IO_in_backup (fp))
561 _IO_switch_to_main_get_area (fp);
562 #endif
563 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
565 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
566 fp->_IO_read_end);
567 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
569 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
570 goto resync;
573 #ifdef TODO
574 /* If we have streammarkers, seek forward by reading ahead. */
575 if (_IO_have_markers (fp))
577 int to_skip = rel_offset
578 - (fp->_IO_read_ptr - fp->_IO_read_base);
579 if (ignore (to_skip) != to_skip)
580 goto dumb;
581 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
582 goto resync;
584 #endif
586 #ifdef TODO
587 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
589 if (!_IO_in_backup (fp))
590 _IO_switch_to_backup_area (fp);
591 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
592 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
593 goto resync;
595 #endif
598 #ifdef TODO
599 _IO_unsave_markers (fp);
600 #endif
602 if (fp->_flags & _IO_NO_READS)
603 goto dumb;
605 /* Try to seek to a block boundary, to improve kernel page management. */
606 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
607 delta = offset - new_offset;
608 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
610 new_offset = offset;
611 delta = 0;
613 result = _IO_SYSSEEK (fp, new_offset, 0);
614 if (result < 0)
615 return EOF;
616 if (delta == 0)
617 count = 0;
618 else
620 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
621 (must_be_exact
622 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
623 if (count < delta)
625 /* We weren't allowed to read, but try to seek the remainder. */
626 offset = count == EOF ? delta : delta-count;
627 dir = _IO_seek_cur;
628 goto dumb;
631 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
632 fp->_IO_buf_base + count);
633 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
634 fp->_offset = result + count;
635 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
636 return offset;
637 dumb:
639 _IO_unsave_markers (fp);
640 result = _IO_SYSSEEK (fp, offset, dir);
641 if (result != EOF)
643 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
644 fp->_offset = result;
645 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
646 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
648 return result;
650 resync:
651 /* We need to do it since it is possible that the file offset in
652 the kernel may be changed behind our back. It may happen when
653 we fopen a file and then do a fork. One process may access the
654 the file and the kernel file offset will be changed. */
655 if (fp->_offset >= 0)
656 _IO_SYSSEEK (fp, fp->_offset, 0);
658 return offset;
661 _IO_ssize_t
662 _IO_file_read (fp, buf, size)
663 _IO_FILE *fp;
664 void *buf;
665 _IO_ssize_t size;
667 return read (fp->_fileno, buf, size);
670 _IO_fpos64_t
671 _IO_file_seek (fp, offset, dir)
672 _IO_FILE *fp;
673 _IO_off64_t offset;
674 int dir;
676 #ifdef _G_LSEEK64
677 return _G_LSEEK64 (fp->_fileno, offset, dir);
678 #else
679 return lseek (fp->_fileno, offset, dir);
680 #endif
684 _IO_file_stat (fp, st)
685 _IO_FILE *fp;
686 void *st;
688 #ifdef _G_FSTAT64
689 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
690 #else
691 return fstat (fp->_fileno, (struct _G_stat64 *) st);
692 #endif
696 _IO_file_close (fp)
697 _IO_FILE *fp;
699 return close (fp->_fileno);
702 _IO_ssize_t
703 _IO_new_file_write (f, data, n)
704 _IO_FILE *f;
705 const void *data;
706 _IO_ssize_t n;
708 _IO_ssize_t to_do = n;
709 while (to_do > 0)
711 _IO_ssize_t count = write (f->_fileno, data, to_do);
712 if (count == EOF)
714 f->_flags |= _IO_ERR_SEEN;
715 break;
717 to_do -= count;
718 data = (void *) ((char *) data + count);
720 n -= to_do;
721 if (f->_offset >= 0)
722 f->_offset += n;
723 return n;
726 _IO_size_t
727 _IO_new_file_xsputn (f, data, n)
728 _IO_FILE *f;
729 const void *data;
730 _IO_size_t n;
732 register const char *s = (char *) data;
733 _IO_size_t to_do = n;
734 int must_flush = 0;
735 _IO_size_t count;
737 if (n <= 0)
738 return 0;
739 /* This is an optimized implementation.
740 If the amount to be written straddles a block boundary
741 (or the filebuf is unbuffered), use sys_write directly. */
743 /* First figure out how much space is available in the buffer. */
744 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
745 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
747 count = f->_IO_buf_end - f->_IO_write_ptr;
748 if (count >= n)
750 register const char *p;
751 for (p = s + n; p > s; )
753 if (*--p == '\n')
755 count = p - s + 1;
756 must_flush = 1;
757 break;
762 /* Then fill the buffer. */
763 if (count > 0)
765 if (count > to_do)
766 count = to_do;
767 if (count > 20)
769 #ifdef _LIBC
770 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
771 #else
772 memcpy (f->_IO_write_ptr, s, count);
773 f->_IO_write_ptr += count;
774 #endif
775 s += count;
777 else
779 register char *p = f->_IO_write_ptr;
780 register int i = (int) count;
781 while (--i >= 0)
782 *p++ = *s++;
783 f->_IO_write_ptr = p;
785 to_do -= count;
787 if (to_do + must_flush > 0)
789 _IO_size_t block_size, dont_write;
790 /* Next flush the (full) buffer. */
791 if (__overflow (f, EOF) == EOF)
792 return n - to_do;
794 /* Try to maintain alignment: write a whole number of blocks.
795 dont_write is what gets left over. */
796 block_size = f->_IO_buf_end - f->_IO_buf_base;
797 dont_write = block_size >= 128 ? to_do % block_size : 0;
799 count = to_do - dont_write;
800 if (_IO_new_do_write (f, s, count) == EOF)
801 return n - to_do;
802 to_do = dont_write;
804 /* Now write out the remainder. Normally, this will fit in the
805 buffer, but it's somewhat messier for line-buffered files,
806 so we let _IO_default_xsputn handle the general case. */
807 if (dont_write)
808 to_do -= _IO_default_xsputn (f, s+count, dont_write);
810 return n - to_do;
813 _IO_size_t
814 _IO_file_xsgetn (fp, data, n)
815 _IO_FILE *fp;
816 void *data;
817 _IO_size_t n;
819 register _IO_size_t want, have;
820 register _IO_ssize_t count;
821 register char *s = data;
823 want = n;
825 while (want > 0)
827 have = fp->_IO_read_end - fp->_IO_read_ptr;
828 if (want <= have)
830 memcpy (s, fp->_IO_read_ptr, want);
831 fp->_IO_read_ptr += want;
832 want = 0;
834 else
836 if (have > 0)
838 #ifdef _LIBC
839 s = __mempcpy (s, fp->_IO_read_ptr, have);
840 #else
841 memcpy (s, fp->_IO_read_ptr, have);
842 s += have;
843 #endif
844 want -= have;
845 fp->_IO_read_ptr += have;
848 /* Check for backup and repeat */
849 if (_IO_in_backup (fp))
851 _IO_switch_to_main_get_area (fp);
852 continue;
855 /* If we now want less than a buffer, underflow and repeat
856 the copy. Otherwise, _IO_SYSREAD directly to
857 the user buffer. */
858 if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
860 if (__underflow (fp) == EOF)
861 break;
863 continue;
866 /* These must be set before the sysread as we might longjmp out
867 waiting for input. */
868 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
869 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
871 /* Try to maintain alignment: read a whole number of blocks. */
872 count = want;
873 if (fp->_IO_buf_base)
875 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
876 if (block_size >= 128)
877 count -= want % block_size;
880 count = _IO_SYSREAD (fp, s, count);
881 if (count <= 0)
883 if (count == 0)
884 fp->_flags |= _IO_EOF_SEEN;
885 else
886 fp->_flags |= _IO_ERR_SEEN;
888 break;
891 s += count;
892 want -= count;
893 if (fp->_offset != _IO_pos_BAD)
894 _IO_pos_adjust (fp->_offset, count);
898 return n - want;
901 struct _IO_jump_t _IO_file_jumps =
903 JUMP_INIT_DUMMY,
904 JUMP_INIT(finish, _IO_new_file_finish),
905 JUMP_INIT(overflow, _IO_new_file_overflow),
906 JUMP_INIT(underflow, _IO_new_file_underflow),
907 JUMP_INIT(uflow, _IO_default_uflow),
908 JUMP_INIT(pbackfail, _IO_default_pbackfail),
909 JUMP_INIT(xsputn, _IO_new_file_xsputn),
910 JUMP_INIT(xsgetn, _IO_file_xsgetn),
911 JUMP_INIT(seekoff, _IO_new_file_seekoff),
912 JUMP_INIT(seekpos, _IO_default_seekpos),
913 JUMP_INIT(setbuf, _IO_new_file_setbuf),
914 JUMP_INIT(sync, _IO_new_file_sync),
915 JUMP_INIT(doallocate, _IO_file_doallocate),
916 JUMP_INIT(read, _IO_file_read),
917 JUMP_INIT(write, _IO_new_file_write),
918 JUMP_INIT(seek, _IO_file_seek),
919 JUMP_INIT(close, _IO_file_close),
920 JUMP_INIT(stat, _IO_file_stat),
921 JUMP_INIT(showmanyc, _IO_default_showmanyc),
922 JUMP_INIT(imbue, _IO_default_imbue)
926 #if defined PIC && DO_VERSIONING
927 default_symbol_version (_IO_new_do_write, _IO_do_write, GLIBC_2.1);
928 default_symbol_version (_IO_new_file_attach, _IO_file_attach, GLIBC_2.1);
929 default_symbol_version (_IO_new_file_close_it, _IO_file_close_it, GLIBC_2.1);
930 default_symbol_version (_IO_new_file_finish, _IO_file_finish, GLIBC_2.1);
931 default_symbol_version (_IO_new_file_fopen, _IO_file_fopen, GLIBC_2.1);
932 default_symbol_version (_IO_new_file_init, _IO_file_init, GLIBC_2.1);
933 default_symbol_version (_IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2.1);
934 default_symbol_version (_IO_new_file_sync, _IO_file_sync, GLIBC_2.1);
935 default_symbol_version (_IO_new_file_overflow, _IO_file_overflow, GLIBC_2.1);
936 default_symbol_version (_IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2.1);
937 default_symbol_version (_IO_new_file_underflow, _IO_file_underflow, GLIBC_2.1);
938 default_symbol_version (_IO_new_file_write, _IO_file_write, GLIBC_2.1);
939 default_symbol_version (_IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2.1);
940 #else
941 # ifdef strong_alias
942 strong_alias (_IO_new_do_write, _IO_do_write);
943 strong_alias (_IO_new_file_attach, _IO_file_attach);
944 strong_alias (_IO_new_file_close_it, _IO_file_close_it);
945 strong_alias (_IO_new_file_finish, _IO_file_finish);
946 strong_alias (_IO_new_file_fopen, _IO_file_fopen);
947 strong_alias (_IO_new_file_init, _IO_file_init);
948 strong_alias (_IO_new_file_setbuf, _IO_file_setbuf);
949 strong_alias (_IO_new_file_sync, _IO_file_sync);
950 strong_alias (_IO_new_file_overflow, _IO_file_overflow);
951 strong_alias (_IO_new_file_seekoff, _IO_file_seekoff);
952 strong_alias (_IO_new_file_underflow, _IO_file_underflow);
953 strong_alias (_IO_new_file_write, _IO_file_write);
954 strong_alias (_IO_new_file_xsputn, _IO_file_xsputn);
955 # endif
956 #endif