patches from bug-gnu-utils to support more architectures
[glibc.git] / stdio / internals.c
blob8c2acc4026b2de5448d351a5eb3ee27bb462c093
1 /* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
25 /* Make sure that FP has its functions set. */
26 void
27 __stdio_check_funcs (fp)
28 register FILE *fp;
30 if (!fp->__seen)
32 /* Initialize the stream's info, including buffering info.
33 This may give a buffer, change I/O functions, etc.
34 If no buffer is set (and the stream is not made explicitly
35 unbuffered), we allocate a buffer below, using the bufsize
36 set by this function. */
37 extern void __stdio_init_stream __P ((FILE *));
38 fp->__room_funcs = __default_room_functions;
39 fp->__io_funcs = __default_io_functions;
40 __stdio_init_stream (fp);
41 fp->__seen = 1;
46 /* Minimum size of a buffer we will allocate by default.
47 If this much memory is not available,
48 the stream in question will be made unbuffered instead. */
49 #define MIN_BUFSIZE 128
51 /* Figure out what kind of buffering (none, line, or full)
52 and what buffer size to give FP. */
53 static void
54 init_stream (fp)
55 register FILE *fp;
57 __stdio_check_funcs (fp);
59 if (fp->__buffer == NULL && !fp->__userbuf)
61 int save;
63 if (fp->__bufsize == 0)
64 fp->__bufsize = BUFSIZ;
66 /* Try to get however many bytes of buffering __stdio_pickbuf
67 specified, but if that much memory isn't available,
68 try half as much each time until it succeeds or the buffer
69 size becomes too small to be useful. */
70 save = errno;
71 while (fp->__bufsize >= MIN_BUFSIZE)
73 fp->__buffer = (char *) malloc (fp->__bufsize);
74 if (fp->__buffer == NULL)
75 fp->__bufsize /= 2;
76 else
77 break;
79 __set_errno (save);
81 if (fp->__buffer == NULL)
83 /* We can't get space for the buffer, so make it unbuffered. */
84 fp->__userbuf = 1;
85 fp->__bufsize = 0;
89 if (fp->__bufp == NULL)
91 /* Set the buffer pointer to the beginning of the buffer. */
92 fp->__bufp = fp->__buffer;
93 fp->__put_limit = fp->__get_limit = fp->__buffer;
98 /* Determine the current file position of STREAM if it is unknown. */
99 int
100 __stdio_check_offset (stream)
101 FILE *stream;
103 init_stream (stream);
105 if (stream->__offset == (fpos_t) -1)
107 /* This stream's offset is unknown or unknowable. */
108 if (stream->__io_funcs.__seek == NULL)
110 /* Unknowable. */
111 __set_errno (ESPIPE);
112 return EOF;
114 else
116 /* Unknown. Find it out. */
117 fpos_t pos = (fpos_t) 0;
118 if ((*stream->__io_funcs.__seek) (stream->__cookie,
119 &pos, SEEK_CUR) < 0)
121 if (errno == ESPIPE)
122 /* Object is incapable of seeking. */
123 stream->__io_funcs.__seek = NULL;
124 return EOF;
126 stream->__offset = pos;
130 if (stream->__target == (fpos_t) -1)
131 /* This stream was opened on an existing object with
132 an unknown file position. The position is now known.
133 Make this the target position. */
134 stream->__target = stream->__offset;
136 return 0;
140 /* Move FP's file position to its target file position,
141 seeking as necessary and updating its `offset' field.
142 Sets ferror(FP) (and possibly errno) for errors. */
143 static void
144 seek_to_target (fp)
145 FILE *fp;
147 int save = errno;
148 if (__stdio_check_offset (fp) == EOF)
150 if (errno == ESPIPE)
151 __set_errno (save);
152 else
153 fp->__error = 1;
155 else if (fp->__target != fp->__offset)
157 /* We are not at the target file position.
158 Seek to that position. */
159 if (fp->__io_funcs.__seek == NULL)
161 /* We can't seek! */
162 __set_errno (ESPIPE);
163 fp->__error = 1;
165 else
167 fpos_t pos = fp->__target;
168 if ((*fp->__io_funcs.__seek) (fp->__cookie, &pos, SEEK_SET) < 0)
169 /* Seek failed! */
170 fp->__error = 1;
171 else
173 fp->__offset = pos;
174 if (pos != fp->__target)
176 /* Seek didn't go to the right place!
177 This should never happen. */
178 #ifdef EGRATUITOUS
179 /* It happens in the Hurd when the io server doesn't
180 obey the protocol for io_seek. */
181 __set_errno (EGRATUITOUS);
182 #else
183 /* I don't think this can happen in Unix. */
184 __set_errno (ESPIPE); /* ??? */
185 #endif
186 fp->__error = 1;
193 /* Flush the buffer for FP.
194 If C is not EOF, it is also to be written.
195 If the stream is line buffered and C is a newline, it is written
196 to the output, otherwise it is put in the buffer after it has been
197 flushed to avoid a system call for a single character.
198 This is the default `output room' function. */
199 static void
200 flushbuf (fp, c)
201 register FILE *fp;
202 int c;
204 int flush_only = c == EOF;
205 size_t buffer_written;
206 size_t to_write;
208 /* Set if target and get_limit have already been twiddled appropriately. */
209 int twiddled = 0;
211 if (fp->__put_limit == fp->__buffer)
213 /* The stream needs to be primed for writing. */
215 size_t buffer_offset = 0;
217 if (fp->__target == -1)
218 /* For an unseekable object, data recently read bears no relation
219 to data we will write later. Discard the buffer. */
220 fp->__get_limit = fp->__buffer;
221 else
222 /* If the user has read some of the buffer, the target position
223 is incremented for each character he has read. */
224 fp->__target += fp->__bufp - fp->__buffer;
226 if (fp->__mode.__read && fp->__room_funcs.__input != NULL &&
227 !fp->__mode.__append)
229 int save = errno;
230 const int aligned = (fp->__buffer == NULL ||
231 __stdio_check_offset (fp) == EOF ||
232 fp->__target % fp->__bufsize == 0);
233 __set_errno (save);
235 if (!aligned)
237 /* Move to a block (buffer size) boundary and read in a block.
238 Then the output will be written as a whole block, too. */
239 const size_t o = fp->__target % fp->__bufsize;
240 fp->__target -= o;
241 if ((*fp->__room_funcs.__input) (fp) == EOF && ferror (fp))
242 return;
243 else
244 __clearerr (fp);
246 if (fp->__get_limit - fp->__buffer < o)
247 /* Oops. We didn't read enough (probably because we got EOF).
248 Forget we even mentioned it. */
249 fp->__target += o;
250 else
251 /* Start bufp as far into the buffer as we were into
252 this block before we read it. */
253 buffer_offset = o;
255 /* The target position is now set to where the beginning of the
256 buffer maps to; and the get_limit was set by the input-room
257 function. */
258 twiddled = 1;
262 if (fp->__buffer != NULL)
264 /* Set up to write output into the buffer. */
265 fp->__put_limit = fp->__buffer + fp->__bufsize;
266 fp->__bufp = fp->__buffer + buffer_offset;
268 if (!flush_only)
270 /* Put C in the buffer to be written out.
271 We only need to actually write it out now if
272 it is a newline on a line-buffered stream. */
273 *fp->__bufp++ = (unsigned char) c;
274 if (!fp->__linebuf || (unsigned char) c != '\n')
276 /* There is no need to flush C from the buffer right now.
277 Record that nothing was written from the buffer,
278 and go do clean-up at end. */
279 buffer_written = 0;
280 goto end;
282 else
283 /* We put C in the buffer, so don't write it again later. */
284 flush_only = 1;
288 if (fp->__bufp - fp->__buffer <= buffer_offset && flush_only)
290 /* There is nothing new in the buffer, only data that
291 was read back aligned from the file. */
292 buffer_written = 0;
293 goto end;
297 /* If there is read data in the buffer past what was written,
298 write all of that as well. Otherwise, just write what has been
299 written into the buffer. */
300 buffer_written = fp->__bufp - fp->__buffer;
301 to_write = (buffer_written == 0 ? 0 :
302 fp->__get_limit > fp->__bufp ?
303 fp->__get_limit - fp->__buffer :
304 buffer_written);
306 if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only))
308 /* There is no writing function or we're coming from an fflush
309 call with nothing in the buffer, so just say the buffer's
310 been flushed, increment the file offset, and return. */
311 fp->__bufp = fp->__buffer;
312 if (fp->__offset != -1)
313 fp->__offset += to_write;
314 goto end;
317 if (to_write > 0)
319 int wrote;
321 /* Go to the target file position. Don't bother if appending;
322 the write will just ignore the file position anyway. */
323 if (!fp->__mode.__append)
324 seek_to_target (fp);
326 if (!ferror(fp))
328 /* Write out the buffered data. */
329 wrote = (*fp->__io_funcs.__write) (fp->__cookie, fp->__buffer,
330 to_write);
331 if (wrote > 0)
333 if (fp->__mode.__append)
334 /* The write has written the data to the end of the file
335 and updated the file position to after the data. Don't
336 bother to find the current position; we can get it
337 later if we need it. */
338 fp->__offset = fp->__target = -1;
339 else if (fp->__offset != -1)
340 /* Record that we've moved forward in the file. */
341 fp->__offset += wrote;
343 if (wrote < (int) to_write)
344 /* The writing function should always write
345 the whole buffer unless there is an error. */
346 fp->__error = 1;
350 /* Reset the buffer pointer to the beginning of the buffer. */
351 fp->__bufp = fp->__buffer;
353 /* If we're not just flushing, write the last character, C. */
354 if (!flush_only && !ferror (fp))
356 if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n'))
358 /* Either we're unbuffered, or we're line-buffered and
359 C is a newline, so really write it out immediately. */
360 char cc = (unsigned char) c;
361 if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1)
362 fp->__error = 1;
363 else if (fp->__offset != -1)
365 /* Record that we've moved forward in the file. */
366 ++fp->__offset;
367 ++fp->__target;
370 else
371 /* Just put C in the buffer. */
372 *fp->__bufp++ = (unsigned char) c;
375 end:
377 if (!twiddled)
379 if (fp->__target != -1)
380 /* The new target position moves up as
381 much as the user wrote into the buffer. */
382 fp->__target += buffer_written;
384 /* Set the reading limit to the beginning of the buffer,
385 so the next `getc' will call __fillbf. */
386 fp->__get_limit = fp->__buffer;
389 if (feof (fp) || ferror (fp))
390 fp->__bufp = fp->__put_limit;
394 /* Fill the buffer for FP and return the first character read (or EOF).
395 This is the default `input_room' function. */
396 static int
397 fillbuf (fp)
398 register FILE *fp;
400 /* How far into the buffer we read we want to start bufp. */
401 size_t buffer_offset = 0;
402 register char *buffer;
403 register size_t to_read, nread = 0;
404 /* This must be unsigned to avoid sign extension in return. */
405 unsigned char c;
407 if (fp->__io_funcs.__read == NULL)
409 /* There is no read function, so always return EOF. */
410 fp->__eof = 1;
411 goto end;
414 if (fp->__buffer == NULL)
416 /* We're unbuffered, so we want to read only one character. */
417 buffer = (char *) &c;
418 to_read = 1;
420 else
422 /* We're buffered, so try to fill the buffer. */
423 buffer = fp->__buffer;
424 to_read = fp->__bufsize;
427 /* We're reading, so we're not at the end-of-file. */
428 fp->__eof = 0;
430 /* Go to the target file position. */
432 int save = errno;
433 if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset)
435 /* Move to a block (buffer size) boundary. */
436 if (fp->__bufsize != 0)
438 buffer_offset = fp->__target % fp->__bufsize;
439 fp->__target -= buffer_offset;
441 seek_to_target (fp);
443 __set_errno (save);
446 while (!ferror (fp) && !feof (fp) && nread <= buffer_offset)
448 /* Try to fill the buffer. */
449 int count = (*fp->__io_funcs.__read) (fp->__cookie, buffer, to_read);
450 if (count == 0)
451 fp->__eof = 1;
452 else if (count < 0)
453 fp->__error = 1;
454 else
456 buffer += count;
457 nread += count;
458 to_read -= count;
459 if (fp->__offset != -1)
460 /* Record that we've moved forward in the file. */
461 fp->__offset += count;
465 if (fp->__buffer == NULL)
466 /* There is no buffer, so return the character we read
467 without all the buffer pointer diddling. */
468 return (feof (fp) || ferror (fp)) ? EOF : c;
470 /* Reset the buffer pointer to the beginning of the buffer
471 (plus whatever offset we may have set above). */
472 fp->__bufp = fp->__buffer + buffer_offset;
474 end:;
476 if (feof (fp) || ferror (fp))
478 /* Set both end pointers to the beginning of the buffer so
479 the next i/o call will force a call to __fillbf/__flshfp. */
480 fp->__put_limit = fp->__get_limit = fp->__buffer;
481 return EOF;
484 /* Set the end pointer to one past the last character we read. */
485 fp->__get_limit = fp->__buffer + nread;
487 /* Make it so the next `putc' will call __flshfp. */
488 fp->__put_limit = fp->__buffer;
490 /* Return the first character in the buffer. */
491 return *((unsigned char *) (fp->__bufp++));
495 /* Default I/O and room functions. */
497 extern __io_read_fn __stdio_read;
498 extern __io_write_fn __stdio_write;
499 extern __io_seek_fn __stdio_seek;
500 extern __io_close_fn __stdio_close;
501 extern __io_fileno_fn __stdio_fileno;
502 const __io_functions __default_io_functions =
504 __stdio_read, __stdio_write, __stdio_seek, __stdio_close, __stdio_fileno
507 const __room_functions __default_room_functions =
509 fillbuf, flushbuf
513 /* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero.
514 This is the function used by putc and fflush. */
516 __flshfp (fp, c)
517 register FILE *fp;
518 int c;
520 int flush_only = c == EOF;
522 if (!__validfp (fp) || !fp->__mode.__write)
524 __set_errno (EINVAL);
525 return EOF;
528 if (ferror (fp))
529 return EOF;
531 if (fp->__pushed_back)
533 /* Discard the char pushed back by ungetc. */
534 fp->__bufp = fp->__pushback_bufp;
535 fp->__pushed_back = 0;
538 /* Make sure the stream is initialized (has functions and buffering). */
539 init_stream (fp);
541 /* Do this early, so a `putc' on such a stream will never return success. */
542 if (fp->__room_funcs.__output == NULL)
544 /* A NULL `output room' function means
545 to always return an output error. */
546 fp->__error = 1;
547 return EOF;
550 if (!flush_only &&
551 /* Will C fit into the buffer?
552 See below about linebuf_active. */
553 fp->__bufp < (fp->__linebuf_active ? fp->__buffer + fp->__bufsize :
554 fp->__put_limit))
556 /* The character will fit in the buffer, so put it there. */
557 *fp->__bufp++ = (unsigned char) c;
558 if (fp->__linebuf && (unsigned char) c == '\n')
559 flush_only = 1;
560 else
561 return (unsigned char) c;
564 if (fp->__linebuf_active)
565 /* This is an active line-buffered stream, so its put-limit is set
566 to the beginning of the buffer in order to force a __flshfp call
567 on each putc (see below). We undo this hack here (by setting
568 the limit to the end of the buffer) to simplify the interface
569 with the output-room function. */
570 fp->__put_limit = fp->__buffer + fp->__bufsize;
572 /* Make room in the buffer. */
573 (*fp->__room_funcs.__output) (fp, flush_only ? EOF : (unsigned char) c);
575 if (fp->__linebuf)
577 /* This is a line-buffered stream, and it is now ready to do
578 some output. We call this an "active line-buffered stream".
579 We set the put_limit to the beginning of the buffer,
580 so the next `putc' call will force a call to this function.
581 Setting the linebuf_active flag tells the code above
582 (on the next call) to undo this hackery. */
583 fp->__put_limit = fp->__buffer;
584 fp->__linebuf_active = 1;
587 if (ferror (fp))
588 return EOF;
589 if (flush_only)
590 return 0;
591 return (unsigned char) c;
595 /* Fill the buffer for FP and return the first character read.
596 This is the function used by getc. */
598 __fillbf (fp)
599 register FILE *fp;
601 register int c;
602 fpos_t new_target;
604 if (!__validfp (fp) || !fp->__mode.__read)
606 __set_errno (EINVAL);
607 return EOF;
610 if (fp->__pushed_back)
612 /* Return the char pushed back by ungetc. */
613 fp->__bufp = fp->__pushback_bufp;
614 fp->__pushed_back = 0;
615 return fp->__pushback;
618 /* Make sure the stream is initialized (has functions and buffering). */
619 init_stream (fp);
621 /* If we're trying to read the first character of a new
622 line of input from an unbuffered or line buffered stream,
623 we must flush all line-buffered output streams. */
624 if (fp->__buffer == NULL || fp->__linebuf)
626 register FILE *f;
627 for (f = __stdio_head; f != NULL; f = f->__next)
628 if (__validfp (f) && f->__linebuf && f->__mode.__write)
629 (void) __flshfp (f, EOF);
632 /* Note we must do this after flushing all line-buffered
633 streams, or else __flshfp would undo it! */
634 if (fp->__linebuf_active)
636 /* This is an active line-buffered stream, meaning it is in the midst
637 of writing, but has a bogus put_limit. Restore it to normality. */
638 fp->__put_limit = fp->__buffer + fp->__bufsize;
639 fp->__linebuf_active = 0;
642 /* We want the beginning of the buffer to now
643 map to just past the last data we read. */
644 new_target = fp->__target + (fp->__get_limit - fp->__buffer);
646 if (fp->__put_limit > fp->__buffer)
648 /* There is written data in the buffer.
649 Flush it out. */
650 if (fp->__room_funcs.__output == NULL)
651 fp->__error = 1;
652 else
653 (*fp->__room_funcs.__output) (fp, EOF);
656 fp->__target = new_target;
658 if (ferror (fp))
659 c = EOF;
660 else if (fp->__room_funcs.__input != NULL)
662 c = (*fp->__room_funcs.__input) (fp);
663 if (fp->__buffer == NULL)
664 /* This is an unbuffered stream, so the target sync above
665 won't do anything the next time around. Instead, note that
666 we have read one character. The (nonexistent) buffer now
667 maps to the position just past that character. */
668 ++fp->__target;
670 else
672 /* A NULL `input_room' function means always return EOF. */
673 fp->__eof = 1;
674 c = EOF;
677 return c;
681 /* Nuke a stream, but don't kill its link in the chain. */
682 void
683 __invalidate (stream)
684 register FILE *stream;
686 /* Save its link. */
687 register FILE *next = stream->__next;
689 /* Pulverize the fucker. */
690 memset((void *) stream, 0, sizeof(FILE));
692 /* Restore the deceased's link. */
693 stream->__next = next;