Update.
[glibc.git] / libio / fileops.c
blobf5ec0e2b9ec5531af3e0927887f3b58dec182183
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 static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
292 /* Write TO_DO bytes from DATA to FP.
293 Then mark FP as having empty buffers. */
296 _IO_new_do_write (fp, data, to_do)
297 _IO_FILE *fp;
298 const char *data;
299 _IO_size_t to_do;
301 return (to_do == 0 || new_do_write (fp, data, to_do) == to_do)
302 ? 0 : EOF;
305 static
307 new_do_write (fp, data, to_do)
308 _IO_FILE *fp;
309 const char *data;
310 _IO_size_t to_do;
312 _IO_size_t count;
313 if (fp->_flags & _IO_IS_APPENDING)
314 /* On a system without a proper O_APPEND implementation,
315 you would need to sys_seek(0, SEEK_END) here, but is
316 is not needed nor desirable for Unix- or Posix-like systems.
317 Instead, just indicate that offset (before and after) is
318 unpredictable. */
319 fp->_offset = _IO_pos_BAD;
320 else if (fp->_IO_read_end != fp->_IO_write_base)
322 _IO_fpos64_t new_pos
323 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
324 if (new_pos == _IO_pos_BAD)
325 return 0;
326 fp->_offset = new_pos;
328 count = _IO_SYSWRITE (fp, data, to_do);
329 if (fp->_cur_column && count)
330 fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
331 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
332 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
333 fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
334 ? fp->_IO_buf_base : fp->_IO_buf_end);
335 return count;
339 _IO_new_file_underflow (fp)
340 _IO_FILE *fp;
342 _IO_ssize_t count;
343 #if 0
344 /* SysV does not make this test; take it out for compatibility */
345 if (fp->_flags & _IO_EOF_SEEN)
346 return (EOF);
347 #endif
349 if (fp->_flags & _IO_NO_READS)
351 __set_errno (EBADF);
352 return EOF;
354 if (fp->_IO_read_ptr < fp->_IO_read_end)
355 return *(unsigned char *) fp->_IO_read_ptr;
357 if (fp->_IO_buf_base == NULL)
359 /* Maybe we already have a push back pointer. */
360 if (fp->_IO_save_base != NULL)
362 free (fp->_IO_save_base);
363 fp->_flags &= ~_IO_IN_BACKUP;
365 _IO_doallocbuf (fp);
368 /* Flush all line buffered files before reading. */
369 /* FIXME This can/should be moved to genops ?? */
370 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
371 _IO_flush_all_linebuffered ();
373 _IO_switch_to_get_mode (fp);
375 /* This is very tricky. We have to adjust those
376 pointers before we call _IO_SYSREAD () since
377 we may longjump () out while waiting for
378 input. Those pointers may be screwed up. H.J. */
379 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
380 fp->_IO_read_end = fp->_IO_buf_base;
381 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
382 = fp->_IO_buf_base;
384 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
385 fp->_IO_buf_end - fp->_IO_buf_base);
386 if (count <= 0)
388 if (count == 0)
389 fp->_flags |= _IO_EOF_SEEN;
390 else
391 fp->_flags |= _IO_ERR_SEEN, count = 0;
393 fp->_IO_read_end += count;
394 if (count == 0)
395 return EOF;
396 if (fp->_offset != _IO_pos_BAD)
397 _IO_pos_adjust (fp->_offset, count);
398 return *(unsigned char *) fp->_IO_read_ptr;
402 _IO_new_file_overflow (f, ch)
403 _IO_FILE *f;
404 int ch;
406 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
408 f->_flags |= _IO_ERR_SEEN;
409 __set_errno (EBADF);
410 return EOF;
412 /* If currently reading or no buffer allocated. */
413 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
415 /* Allocate a buffer if needed. */
416 if (f->_IO_write_base == 0)
418 _IO_doallocbuf (f);
419 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
421 /* Otherwise must be currently reading.
422 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
423 logically slide the buffer forwards one block (by setting the
424 read pointers to all point at the beginning of the block). This
425 makes room for subsequent output.
426 Otherwise, set the read pointers to _IO_read_end (leaving that
427 alone, so it can continue to correspond to the external position). */
428 if (f->_IO_read_ptr == f->_IO_buf_end)
429 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
430 f->_IO_write_ptr = f->_IO_read_ptr;
431 f->_IO_write_base = f->_IO_write_ptr;
432 f->_IO_write_end = f->_IO_buf_end;
433 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
435 f->_flags |= _IO_CURRENTLY_PUTTING;
436 if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
437 f->_IO_write_end = f->_IO_write_ptr;
439 if (ch == EOF)
440 return _IO_do_flush (f);
441 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
442 if (_IO_do_flush (f) == EOF)
443 return EOF;
444 *f->_IO_write_ptr++ = ch;
445 if ((f->_flags & _IO_UNBUFFERED)
446 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
447 if (_IO_do_flush (f) == EOF)
448 return EOF;
449 return (unsigned char) ch;
453 _IO_new_file_sync (fp)
454 _IO_FILE *fp;
456 _IO_ssize_t delta;
457 int retval = 0;
459 /* char* ptr = cur_ptr(); */
460 if (fp->_IO_write_ptr > fp->_IO_write_base)
461 if (_IO_do_flush(fp)) return EOF;
462 delta = fp->_IO_read_ptr - fp->_IO_read_end;
463 if (delta != 0)
465 #ifdef TODO
466 if (_IO_in_backup (fp))
467 delta -= eGptr () - Gbase ();
468 #endif
469 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
470 if (new_pos != (_IO_off64_t) EOF)
471 fp->_IO_read_end = fp->_IO_read_ptr;
472 #ifdef ESPIPE
473 else if (errno == ESPIPE)
474 ; /* Ignore error from unseekable devices. */
475 #endif
476 else
477 retval = EOF;
479 if (retval != EOF)
480 fp->_offset = _IO_pos_BAD;
481 /* FIXME: Cleanup - can this be shared? */
482 /* setg(base(), ptr, ptr); */
483 return retval;
486 _IO_fpos64_t
487 _IO_new_file_seekoff (fp, offset, dir, mode)
488 _IO_FILE *fp;
489 _IO_off64_t offset;
490 int dir;
491 int mode;
493 _IO_fpos64_t result;
494 _IO_off64_t delta, new_offset;
495 long count;
496 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
497 offset of the underlying file must be exact. */
498 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
499 && fp->_IO_write_base == fp->_IO_write_ptr);
501 if (mode == 0)
502 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
504 /* Flush unwritten characters.
505 (This may do an unneeded write if we seek within the buffer.
506 But to be able to switch to reading, we would need to set
507 egptr to ptr. That can't be done in the current design,
508 which assumes file_ptr() is eGptr. Anyway, since we probably
509 end up flushing when we close(), it doesn't make much difference.)
510 FIXME: simulate mem-papped files. */
512 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
513 if (_IO_switch_to_get_mode (fp))
514 return EOF;
516 if (fp->_IO_buf_base == NULL)
518 /* It could be that we already have a pushback buffer. */
519 if (fp->_IO_read_base != NULL)
521 free (fp->_IO_read_base);
522 fp->_flags &= ~_IO_IN_BACKUP;
524 _IO_doallocbuf (fp);
525 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
526 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
529 switch (dir)
531 case _IO_seek_cur:
532 /* Adjust for read-ahead (bytes is buffer). */
533 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
534 if (fp->_offset == _IO_pos_BAD)
535 goto dumb;
536 /* Make offset absolute, assuming current pointer is file_ptr(). */
537 offset += _IO_pos_as_off (fp->_offset);
539 dir = _IO_seek_set;
540 break;
541 case _IO_seek_set:
542 break;
543 case _IO_seek_end:
545 struct _G_stat64 st;
546 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
548 offset += st.st_size;
549 dir = _IO_seek_set;
551 else
552 goto dumb;
555 /* At this point, dir==_IO_seek_set. */
557 /* If we are only interested in the current position we've found it now. */
558 if (mode == 0)
559 return offset;
561 /* If destination is within current buffer, optimize: */
562 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
563 && !_IO_in_backup (fp))
565 /* Offset relative to start of main get area. */
566 _IO_fpos64_t rel_offset = (offset - fp->_offset
567 + (fp->_IO_read_end - fp->_IO_read_base));
568 if (rel_offset >= 0)
570 #if 0
571 if (_IO_in_backup (fp))
572 _IO_switch_to_main_get_area (fp);
573 #endif
574 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
576 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
577 fp->_IO_read_end);
578 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
580 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
581 goto resync;
584 #ifdef TODO
585 /* If we have streammarkers, seek forward by reading ahead. */
586 if (_IO_have_markers (fp))
588 int to_skip = rel_offset
589 - (fp->_IO_read_ptr - fp->_IO_read_base);
590 if (ignore (to_skip) != to_skip)
591 goto dumb;
592 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
593 goto resync;
595 #endif
597 #ifdef TODO
598 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
600 if (!_IO_in_backup (fp))
601 _IO_switch_to_backup_area (fp);
602 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
603 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
604 goto resync;
606 #endif
609 #ifdef TODO
610 _IO_unsave_markers (fp);
611 #endif
613 if (fp->_flags & _IO_NO_READS)
614 goto dumb;
616 /* Try to seek to a block boundary, to improve kernel page management. */
617 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
618 delta = offset - new_offset;
619 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
621 new_offset = offset;
622 delta = 0;
624 result = _IO_SYSSEEK (fp, new_offset, 0);
625 if (result < 0)
626 return EOF;
627 if (delta == 0)
628 count = 0;
629 else
631 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
632 (must_be_exact
633 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
634 if (count < delta)
636 /* We weren't allowed to read, but try to seek the remainder. */
637 offset = count == EOF ? delta : delta-count;
638 dir = _IO_seek_cur;
639 goto dumb;
642 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
643 fp->_IO_buf_base + count);
644 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
645 fp->_offset = result + count;
646 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
647 return offset;
648 dumb:
650 _IO_unsave_markers (fp);
651 result = _IO_SYSSEEK (fp, offset, dir);
652 if (result != EOF)
654 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
655 fp->_offset = result;
656 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
657 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
659 return result;
661 resync:
662 /* We need to do it since it is possible that the file offset in
663 the kernel may be changed behind our back. It may happen when
664 we fopen a file and then do a fork. One process may access the
665 the file and the kernel file offset will be changed. */
666 if (fp->_offset >= 0)
667 _IO_SYSSEEK (fp, fp->_offset, 0);
669 return offset;
672 _IO_ssize_t
673 _IO_file_read (fp, buf, size)
674 _IO_FILE *fp;
675 void *buf;
676 _IO_ssize_t size;
678 return read (fp->_fileno, buf, size);
681 _IO_fpos64_t
682 _IO_file_seek (fp, offset, dir)
683 _IO_FILE *fp;
684 _IO_off64_t offset;
685 int dir;
687 #ifdef _G_LSEEK64
688 return _G_LSEEK64 (fp->_fileno, offset, dir);
689 #else
690 return lseek (fp->_fileno, offset, dir);
691 #endif
695 _IO_file_stat (fp, st)
696 _IO_FILE *fp;
697 void *st;
699 #ifdef _G_FSTAT64
700 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
701 #else
702 return fstat (fp->_fileno, (struct _G_stat64 *) st);
703 #endif
707 _IO_file_close (fp)
708 _IO_FILE *fp;
710 return close (fp->_fileno);
713 _IO_ssize_t
714 _IO_new_file_write (f, data, n)
715 _IO_FILE *f;
716 const void *data;
717 _IO_ssize_t n;
719 _IO_ssize_t to_do = n;
720 while (to_do > 0)
722 _IO_ssize_t count = write (f->_fileno, data, to_do);
723 if (count == EOF)
725 f->_flags |= _IO_ERR_SEEN;
726 break;
728 to_do -= count;
729 data = (void *) ((char *) data + count);
731 n -= to_do;
732 if (f->_offset >= 0)
733 f->_offset += n;
734 return n;
737 _IO_size_t
738 _IO_new_file_xsputn (f, data, n)
739 _IO_FILE *f;
740 const void *data;
741 _IO_size_t n;
743 register const char *s = (char *) data;
744 _IO_size_t to_do = n;
745 int must_flush = 0;
746 _IO_size_t count;
748 if (n <= 0)
749 return 0;
750 /* This is an optimized implementation.
751 If the amount to be written straddles a block boundary
752 (or the filebuf is unbuffered), use sys_write directly. */
754 /* First figure out how much space is available in the buffer. */
755 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
756 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
758 count = f->_IO_buf_end - f->_IO_write_ptr;
759 if (count >= n)
761 register const char *p;
762 for (p = s + n; p > s; )
764 if (*--p == '\n')
766 count = p - s + 1;
767 must_flush = 1;
768 break;
773 /* Then fill the buffer. */
774 if (count > 0)
776 if (count > to_do)
777 count = to_do;
778 if (count > 20)
780 #ifdef _LIBC
781 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
782 #else
783 memcpy (f->_IO_write_ptr, s, count);
784 f->_IO_write_ptr += count;
785 #endif
786 s += count;
788 else
790 register char *p = f->_IO_write_ptr;
791 register int i = (int) count;
792 while (--i >= 0)
793 *p++ = *s++;
794 f->_IO_write_ptr = p;
796 to_do -= count;
798 if (to_do + must_flush > 0)
800 _IO_size_t block_size, do_write;
801 /* Next flush the (full) buffer. */
802 if (__overflow (f, EOF) == EOF)
803 return n - to_do;
805 /* Try to maintain alignment: write a whole number of blocks.
806 dont_write is what gets left over. */
807 block_size = f->_IO_buf_end - f->_IO_buf_base;
808 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
810 if (do_write)
812 count = new_do_write (f, s, do_write);
813 to_do -= count;
814 if (count < do_write)
815 return n - to_do;
818 /* Now write out the remainder. Normally, this will fit in the
819 buffer, but it's somewhat messier for line-buffered files,
820 so we let _IO_default_xsputn handle the general case. */
821 if (to_do)
822 to_do -= _IO_default_xsputn (f, s+do_write, to_do);
824 return n - to_do;
827 _IO_size_t
828 _IO_file_xsgetn (fp, data, n)
829 _IO_FILE *fp;
830 void *data;
831 _IO_size_t n;
833 register _IO_size_t want, have;
834 register _IO_ssize_t count;
835 register char *s = data;
837 want = n;
839 while (want > 0)
841 have = fp->_IO_read_end - fp->_IO_read_ptr;
842 if (want <= have)
844 memcpy (s, fp->_IO_read_ptr, want);
845 fp->_IO_read_ptr += want;
846 want = 0;
848 else
850 if (have > 0)
852 #ifdef _LIBC
853 s = __mempcpy (s, fp->_IO_read_ptr, have);
854 #else
855 memcpy (s, fp->_IO_read_ptr, have);
856 s += have;
857 #endif
858 want -= have;
859 fp->_IO_read_ptr += have;
862 /* Check for backup and repeat */
863 if (_IO_in_backup (fp))
865 _IO_switch_to_main_get_area (fp);
866 continue;
869 /* If we now want less than a buffer, underflow and repeat
870 the copy. Otherwise, _IO_SYSREAD directly to
871 the user buffer. */
872 if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
874 if (__underflow (fp) == EOF)
875 break;
877 continue;
880 /* These must be set before the sysread as we might longjmp out
881 waiting for input. */
882 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
883 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
885 /* Try to maintain alignment: read a whole number of blocks. */
886 count = want;
887 if (fp->_IO_buf_base)
889 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
890 if (block_size >= 128)
891 count -= want % block_size;
894 count = _IO_SYSREAD (fp, s, count);
895 if (count <= 0)
897 if (count == 0)
898 fp->_flags |= _IO_EOF_SEEN;
899 else
900 fp->_flags |= _IO_ERR_SEEN;
902 break;
905 s += count;
906 want -= count;
907 if (fp->_offset != _IO_pos_BAD)
908 _IO_pos_adjust (fp->_offset, count);
912 return n - want;
915 struct _IO_jump_t _IO_file_jumps =
917 JUMP_INIT_DUMMY,
918 JUMP_INIT(finish, _IO_new_file_finish),
919 JUMP_INIT(overflow, _IO_new_file_overflow),
920 JUMP_INIT(underflow, _IO_new_file_underflow),
921 JUMP_INIT(uflow, _IO_default_uflow),
922 JUMP_INIT(pbackfail, _IO_default_pbackfail),
923 JUMP_INIT(xsputn, _IO_new_file_xsputn),
924 JUMP_INIT(xsgetn, _IO_file_xsgetn),
925 JUMP_INIT(seekoff, _IO_new_file_seekoff),
926 JUMP_INIT(seekpos, _IO_default_seekpos),
927 JUMP_INIT(setbuf, _IO_new_file_setbuf),
928 JUMP_INIT(sync, _IO_new_file_sync),
929 JUMP_INIT(doallocate, _IO_file_doallocate),
930 JUMP_INIT(read, _IO_file_read),
931 JUMP_INIT(write, _IO_new_file_write),
932 JUMP_INIT(seek, _IO_file_seek),
933 JUMP_INIT(close, _IO_file_close),
934 JUMP_INIT(stat, _IO_file_stat),
935 JUMP_INIT(showmanyc, _IO_default_showmanyc),
936 JUMP_INIT(imbue, _IO_default_imbue)
940 #if defined PIC && DO_VERSIONING
941 default_symbol_version (_IO_new_do_write, _IO_do_write, GLIBC_2.1);
942 default_symbol_version (_IO_new_file_attach, _IO_file_attach, GLIBC_2.1);
943 default_symbol_version (_IO_new_file_close_it, _IO_file_close_it, GLIBC_2.1);
944 default_symbol_version (_IO_new_file_finish, _IO_file_finish, GLIBC_2.1);
945 default_symbol_version (_IO_new_file_fopen, _IO_file_fopen, GLIBC_2.1);
946 default_symbol_version (_IO_new_file_init, _IO_file_init, GLIBC_2.1);
947 default_symbol_version (_IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2.1);
948 default_symbol_version (_IO_new_file_sync, _IO_file_sync, GLIBC_2.1);
949 default_symbol_version (_IO_new_file_overflow, _IO_file_overflow, GLIBC_2.1);
950 default_symbol_version (_IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2.1);
951 default_symbol_version (_IO_new_file_underflow, _IO_file_underflow, GLIBC_2.1);
952 default_symbol_version (_IO_new_file_write, _IO_file_write, GLIBC_2.1);
953 default_symbol_version (_IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2.1);
954 #else
955 # ifdef strong_alias
956 strong_alias (_IO_new_do_write, _IO_do_write);
957 strong_alias (_IO_new_file_attach, _IO_file_attach);
958 strong_alias (_IO_new_file_close_it, _IO_file_close_it);
959 strong_alias (_IO_new_file_finish, _IO_file_finish);
960 strong_alias (_IO_new_file_fopen, _IO_file_fopen);
961 strong_alias (_IO_new_file_init, _IO_file_init);
962 strong_alias (_IO_new_file_setbuf, _IO_file_setbuf);
963 strong_alias (_IO_new_file_sync, _IO_file_sync);
964 strong_alias (_IO_new_file_overflow, _IO_file_overflow);
965 strong_alias (_IO_new_file_seekoff, _IO_file_seekoff);
966 strong_alias (_IO_new_file_underflow, _IO_file_underflow);
967 strong_alias (_IO_new_file_write, _IO_file_write);
968 strong_alias (_IO_new_file_xsputn, _IO_file_xsputn);
969 # endif
970 #endif