Formerly ../stdio/internals.c.~41~
[kopensolaris-gnu/glibc.git] / stdio / internals.c
1 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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.  */
18
19 #include <ansidecl.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25
26 /* Minimum size of a buffer we will allocate by default.
27    If this much memory is not available,
28    the stream in question will be made unbuffered instead.  */
29 #define MIN_BUFSIZE     128
30
31 /* Figure out what kind of buffering (none, line, or full)
32    and what buffer size to give FP.  */
33 static void
34 DEFUN(init_stream, (fp), register FILE *fp)
35 {
36   if (!fp->__seen)
37     {
38       /* Initialize the stream's info, including buffering info.
39          This may give a buffer, change I/O functions, etc.
40          If no buffer is set (and the stream is not made explicitly
41          unbuffered), we allocate a buffer below, using the bufsize
42          set by this function.  */
43       extern void EXFUN(__stdio_init_stream, (FILE *));
44       fp->__room_funcs = __default_room_functions;
45       fp->__io_funcs = __default_io_functions;
46       __stdio_init_stream(fp);
47       fp->__seen = 1;
48     }
49
50   if (fp->__buffer == NULL && !fp->__userbuf)
51     {
52       int save;
53
54       if (fp->__bufsize == 0)
55         fp->__bufsize = BUFSIZ;
56
57       /* Try to get however many bytes of buffering __stdio_pickbuf
58          specified, but if that much memory isn't available,
59          try half as much each time until it succeeds or the buffer
60          size becomes too small to be useful.  */
61       save = errno;
62       while (fp->__bufsize >= MIN_BUFSIZE)
63         {
64           fp->__buffer = (char *) malloc(fp->__bufsize);
65           if (fp->__buffer == NULL)
66             fp->__bufsize /= 2;
67           else
68             break;
69         }
70       errno = save;
71
72       if (fp->__buffer == NULL)
73         {
74           /* We can't get space for the buffer, so make it unbuffered.  */
75           fp->__userbuf = 1;
76           fp->__bufsize = 0;
77         }
78     }
79
80   if (fp->__bufp == NULL)
81     {
82       /* Set the buffer pointer to the beginning of the buffer.  */
83       fp->__bufp = fp->__buffer;
84       fp->__put_limit = fp->__get_limit = fp->__buffer;
85     }
86 }
87
88
89 /* Determine the current file position of STREAM if it is unknown.  */
90 int
91 DEFUN(__stdio_check_offset, (stream), FILE *stream)
92 {
93   init_stream (stream);
94
95   if (stream->__offset == (fpos_t) -1)
96     {
97       /* This stream's offset is unknown or unknowable.  */
98       if (stream->__io_funcs.__seek == NULL)
99         {
100           /* Unknowable.  */
101           errno = ESPIPE;
102           return EOF;
103         }
104       else
105         {
106           /* Unknown.  Find it out.  */
107           fpos_t pos = (fpos_t) 0;
108           if ((*stream->__io_funcs.__seek)(stream->__cookie,
109                                            &pos, SEEK_CUR) < 0)
110             {
111               if (errno == ESPIPE)
112                 /* Object is incapable of seeking.  */
113                 stream->__io_funcs.__seek = NULL;
114               return EOF;
115             }
116           stream->__offset = pos;
117         }
118     }
119
120   if (stream->__target == (fpos_t) -1)
121     /* This stream was opened on an existing object with
122        an unknown file position.  The position is now known.
123        Make this the target position.  */
124     stream->__target = stream->__offset;
125
126   return 0;
127 }
128
129
130 /* Move FP's file position to its target file position,
131    seeking as necessary and updating its `offset' field.
132    Sets ferror(FP) (and possibly errno) for errors.  */
133 static void
134 DEFUN(seek_to_target, (fp), FILE *fp)
135 {
136   if (__stdio_check_offset (fp) == EOF)
137     fp->__error = 1;
138   else if (fp->__target != fp->__offset)
139     {
140       /* We are not at the target file position.
141          Seek to that position.  */
142       if (fp->__io_funcs.__seek == NULL)
143         {
144           /* We can't seek!  */
145           errno = ESPIPE;
146           fp->__error = 1;
147         }
148       else
149         {
150           fpos_t pos = fp->__target;
151           if ((*fp->__io_funcs.__seek)(fp->__cookie, &pos, SEEK_SET) < 0)
152             /* Seek failed!  */
153             fp->__error = 1;
154           else
155             {
156               fp->__offset = pos;
157               if (pos != fp->__target)
158                 /* Seek didn't go to the right place!  */
159                 fp->__error = 1;
160             }
161         }
162     }
163 }
164
165 /* Flush the buffer for FP.
166    If C is not EOF, it is also to be written.
167    If the stream is line buffered and C is a newline, it is written
168    to the output, otherwise it is put in the buffer after it has been
169    flushed to avoid a system call for a single character.
170    This is the default `output room' function.  */
171 static void
172 DEFUN(flushbuf, (fp, c),
173       register FILE *fp AND int c)
174 {
175   int flush_only = c == EOF;
176   size_t buffer_written;
177   size_t to_write;
178
179   /* Set if target and get_limit have already been twiddled appropriately.  */
180   int twiddled = 0;
181
182   if (fp->__put_limit == fp->__buffer)
183     {
184       /* The stream needs to be primed for writing.  */
185
186       size_t buffer_offset = 0;
187
188       /* If the user has read some of the buffer, the target position
189          is incremented for each character he has read.  */
190       fp->__target += fp->__bufp - fp->__buffer;
191
192       if (fp->__mode.__read && fp->__room_funcs.__input != NULL &&
193           !fp->__mode.__append)
194         {
195           int save = errno;
196           CONST int aligned = (__stdio_check_offset(fp) == EOF ||
197                                fp->__target % fp->__bufsize == 0);
198           errno = save;
199
200           if (!aligned)
201             {
202               /* Move to a block (buffer size) boundary and read in a block.
203                  Then the output will be written as a whole block, too.  */
204               CONST size_t o = fp->__target % fp->__bufsize;
205               fp->__target -= o;
206               if ((*fp->__room_funcs.__input)(fp) == EOF && ferror(fp))
207                 return;
208               else
209                 __clearerr(fp);
210
211               if (fp->__get_limit - fp->__buffer < o)
212                 /* Oops.  We didn't read enough (probably because we got EOF).
213                    Forget we even mentioned it.  */
214                 fp->__target += o;
215               else
216                 /* Start bufp as far into the buffer as we were into
217                    this block before we read it.  */
218                 buffer_offset = o;
219             }
220
221           /* The target position is now set to where the beginning of the
222              buffer maps to; and the get_limit was set by the input-room
223              function.  */
224           twiddled = 1;
225         }
226
227       if (fp->__buffer != NULL)
228         {
229           /* Set up to write output into the buffer.  */
230           fp->__put_limit = fp->__buffer + fp->__bufsize;
231           fp->__bufp = fp->__buffer + buffer_offset;
232
233           if (!flush_only)
234             {
235               /* Put C in the buffer to be written out.
236                  We only need to actually write it out now if
237                  it is a newline on a line-buffered stream.  */
238               *fp->__bufp++ = (unsigned char) c;
239               if (!fp->__linebuf || (unsigned char) c != '\n')
240                 {
241                   /* There is no need to flush C from the buffer right now.
242                      Record that nothing was written from the buffer,
243                      and go do clean-up at end.  */
244                   buffer_written = 0;
245                   goto end;
246                 }
247               else
248                 /* We put C in the buffer, so don't write it again later.  */
249                 flush_only = 1;
250             }
251         }
252     }
253
254   /* If there is read data in the buffer past what was written,
255      write all of that as well.  Otherwise, just write what has been
256      written into the buffer.  */
257   buffer_written = fp->__bufp - fp->__buffer;
258   to_write = (buffer_written == 0 ? 0 :
259               fp->__get_limit > fp->__bufp ?
260               fp->__get_limit - fp->__buffer :
261               buffer_written);
262
263   if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only))
264     {
265       /* There is no writing function or we're coming from an fflush
266          call with nothing in the buffer, so just say the buffer's
267          been flushed, increment the file offset, and return.  */
268       fp->__bufp = fp->__buffer;
269       fp->__offset += to_write;
270       goto end;
271     }
272
273   if (to_write > 0)
274     {
275       int wrote;
276
277       /* Go to the target file position.  Don't bother if appending;
278          the write will just ignore the file position anyway.  */
279       if (!fp->__mode.__append)
280         seek_to_target (fp);
281
282       if (!ferror(fp))
283         {
284           /* Write out the buffered data.  */
285           wrote = (*fp->__io_funcs.__write)(fp->__cookie, fp->__buffer,
286                                             to_write);
287           if (wrote > 0)
288             {
289               if (fp->__mode.__append)
290                 /* The write has written the data to the end of the file
291                    and updated the file position to after the data.  Don't
292                    bother to find the current position; we can get it
293                    later if we need it.  */
294                 fp->__offset = fp->__target = -1;
295               else
296                 /* Record that we've moved forward in the file.  */
297                 fp->__offset += wrote;
298             }
299           if (wrote < (int) to_write)
300             /* The writing function should always write
301                the whole buffer unless there is an error.  */
302             fp->__error = 1;
303         }
304     }
305
306   /* Reset the buffer pointer to the beginning of the buffer.  */
307   fp->__bufp = fp->__buffer;
308
309   /* If we're not just flushing, write the last character, C.  */
310   if (!flush_only && !ferror(fp))
311     {
312       if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n'))
313         {
314           /* Either we're unbuffered, or we're line-buffered and
315              C is a newline, so really write it out immediately.  */
316           char cc = (unsigned char) c;
317           if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1)
318             fp->__error = 1;
319           else
320             {
321               /* Record that we've moved forward in the file.  */
322               ++fp->__offset;
323               ++fp->__target;
324             }
325         }
326       else
327         /* Just put C in the buffer.  */
328         *fp->__bufp++ = (unsigned char) c;
329     }
330
331  end:
332
333   if (!twiddled)
334     {
335       /* The new target position moves up as
336          much as the user wrote into the buffer.  */
337       fp->__target += buffer_written;
338
339       /* Set the reading limit to the beginning of the buffer,
340          so the next `getc' will call __fillbf.  */
341       fp->__get_limit = fp->__buffer;
342     }
343
344   if (feof(fp) || ferror(fp))
345     fp->__bufp = fp->__put_limit;
346 }
347
348
349 /* Fill the buffer for FP and return the first character read (or EOF).
350    This is the default `input_room' function.  */
351 static int
352 DEFUN(fillbuf, (fp), register FILE *fp)
353 {
354   /* How far into the buffer we read we want to start bufp.  */
355   size_t buffer_offset = 0;
356   register char *buffer;
357   register size_t to_read, nread = 0;
358   char c;
359
360   if (fp->__io_funcs.__read == NULL)
361     {
362       /* There is no read function, so always return EOF.  */
363       fp->__eof = 1;
364       goto end;
365     }
366
367   if (fp->__buffer == NULL)
368     {
369       /* We're unbuffered, so we want to read only one character.  */
370       buffer = &c;
371       to_read = 1;
372     }
373   else
374     {
375       /* We're buffered, so try to fill the buffer.  */
376       buffer = fp->__buffer;
377       to_read = fp->__bufsize;
378     }
379
380   /* We're reading, so we're not at the end-of-file.  */
381   fp->__eof = 0;
382
383   /* Go to the target file position.  */
384   {
385     int save = errno;
386     if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset)
387       {
388         /* Move to a block (buffer size) boundary.  */
389         if (fp->__bufsize != 0)
390           {
391             buffer_offset = fp->__target % fp->__bufsize;
392             fp->__target -= buffer_offset;
393           }
394         seek_to_target (fp);
395       }
396     errno = save;
397   }
398
399   while (!ferror(fp) && !feof(fp) && nread <= buffer_offset)
400     {
401       /* Try to fill the buffer.  */
402       int count = (*fp->__io_funcs.__read)(fp->__cookie, buffer, to_read);
403       if (count == 0)
404         fp->__eof = 1;
405       else if (count < 0)
406         fp->__error = 1;
407       else
408         {
409           buffer += count;
410           nread += count;
411           to_read -= count;
412           /* Record that we've moved forward in the file.  */
413           fp->__offset += count;
414         }
415     }
416
417   if (fp->__buffer == NULL)
418     /* There is no buffer, so return the character we read
419        without all the buffer pointer diddling.  */
420     return (feof(fp) || ferror(fp)) ? EOF : c;
421
422   /* Reset the buffer pointer to the beginning of the buffer
423      (plus whatever offset we may have set above).  */
424   fp->__bufp = fp->__buffer + buffer_offset;
425
426  end:;
427
428   if (feof(fp) || ferror(fp))
429     {
430       /* Set both end pointers to the beginning of the buffer so
431          the next i/o call will force a call to __fillbf/__flshfp.  */
432       fp->__put_limit = fp->__get_limit = fp->__buffer;
433       return EOF;
434     }
435
436   /* Set the end pointer to one past the last character we read.  */
437   fp->__get_limit = fp->__buffer + nread;
438
439   /* Make it so the next `putc' will call __flshfp.  */
440   fp->__put_limit = fp->__buffer;
441
442   /* Return the first character in the buffer.  */
443   return (unsigned char) *fp->__bufp++;
444 }
445
446
447 /* Default I/O and room functions.  */
448
449 extern __io_read __stdio_read;
450 extern __io_write __stdio_write;
451 extern __io_seek __stdio_seek;
452 extern __io_close __stdio_close;
453 CONST __io_functions __default_io_functions =
454   {
455     __stdio_read, __stdio_write, __stdio_seek, __stdio_close
456   };
457
458 CONST __room_functions __default_room_functions =
459   {
460     fillbuf, flushbuf
461   };
462
463
464 /* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero.
465    This is the function used by putc and fflush.  */
466 int
467 DEFUN(__flshfp, (fp, c),
468       register FILE *fp AND int c)
469 {
470   int flush_only = c == EOF;
471
472   if (!__validfp(fp) || !fp->__mode.__write)
473     {
474       errno = EINVAL;
475       return EOF;
476     }
477
478   if (ferror(fp))
479     return EOF;
480
481   if (fp->__pushed_back)
482     {
483       /* Discard the char pushed back by ungetc.  */
484       fp->__bufp = fp->__pushback_bufp;
485       fp->__pushed_back = 0;
486     }
487
488   /* Make sure the stream is initialized (has functions and buffering).  */
489   init_stream(fp);
490
491   /* Do this early, so a `putc' on such a stream will never return success.  */
492   if (fp->__room_funcs.__output == NULL)
493     {
494       /* A NULL `output room' function means
495          to always return an output error.  */
496       fp->__error = 1;
497       return EOF;
498     }
499
500   if (!flush_only &&
501       /* Will C fit into the buffer?
502          See below about linebuf_active.  */
503       fp->__bufp < (fp->__linebuf_active ? fp->__buffer + fp->__bufsize :
504                     fp->__put_limit))
505     {
506       /* The character will fit in the buffer, so put it there.  */
507       *fp->__bufp++ = (unsigned char) c;
508       if (fp->__linebuf && (unsigned char) c == '\n')
509         flush_only = 1;
510       else
511         return (unsigned char) c;
512     }
513
514   if (fp->__linebuf_active)
515     /* This is an active line-buffered stream, so its put-limit is set
516        to the beginning of the buffer in order to force a __flshfp call
517        on each putc (see below).  We undo this hack here (by setting
518        the limit to the end of the buffer) to simplify the interface
519        with the output-room function.  */
520     fp->__put_limit = fp->__buffer + fp->__bufsize;
521
522   /* Make room in the buffer.  */
523   (*fp->__room_funcs.__output) (fp, flush_only ? EOF : (unsigned char) c);
524
525   if (fp->__linebuf)
526     {
527       /* This is a line-buffered stream, and it is now ready to do
528          some output.  We call this an "active line-buffered stream".
529          We set the put_limit to the beginning of the buffer,
530          so the next `putc' call will force a call to this function.
531          Setting the linebuf_active flag tells the code above
532          (on the next call) to undo this hackery.  */
533       fp->__put_limit = fp->__buffer;
534       fp->__linebuf_active = 1;
535     }
536
537   if (ferror (fp))
538     return EOF;
539   if (flush_only)
540     return 0;
541   return (unsigned char) c;
542 }
543
544
545 /* Fill the buffer for FP and return the first character read.
546    This is the function used by getc.  */
547 int
548 DEFUN(__fillbf, (fp), register FILE *fp)
549 {
550   register int c;
551   fpos_t new_target;
552
553   if (!__validfp(fp) || !fp->__mode.__read)
554     {
555       errno = EINVAL;
556       return EOF;
557     }
558
559   if (fp->__pushed_back)
560     {
561       /* Return the char pushed back by ungetc.  */
562       fp->__bufp = fp->__pushback_bufp;
563       fp->__pushed_back = 0;
564       return fp->__pushback;
565     }
566
567   /* Make sure the stream is initialized (has functions and buffering). */
568   init_stream(fp);
569
570   /* If we're trying to read the first character of a new
571      line of input from an unbuffered or line buffered stream,
572      we must flush all line-buffered output streams. */
573   if (fp->__buffer == NULL || fp->__linebuf)
574     {
575       register FILE *f;
576       for (f = __stdio_head; f != NULL; f = f->__next)
577         if (__validfp (f) && f->__linebuf && f->__mode.__write)
578           (void) __flshfp (f, EOF);
579     }
580
581   /* Note we must do this after flushing all line-buffered
582      streams, or else __flshfp would undo it!  */
583   if (fp->__linebuf_active)
584     {
585       /* This is an active line-buffered stream, meaning it is in the midst
586          of writing, but has a bogus put_limit.  Restore it to normality.  */
587       fp->__put_limit = fp->__buffer + fp->__bufsize;
588       fp->__linebuf_active = 0;
589     }
590
591   /* We want the beginning of the buffer to now
592      map to just past the last data we read.  */
593   new_target = fp->__target + (fp->__get_limit - fp->__buffer);
594
595   if (fp->__put_limit > fp->__buffer)
596     {
597       /* There is written data in the buffer.
598          Flush it out.  */
599       if (fp->__room_funcs.__output == NULL)
600         fp->__error = 1;
601       else
602         (*fp->__room_funcs.__output) (fp, EOF);
603     }
604
605   fp->__target = new_target;
606
607   if (ferror(fp))
608     c = EOF;
609   else if (fp->__room_funcs.__input != NULL)
610     {
611       c = (*fp->__room_funcs.__input)(fp);
612       if (fp->__buffer == NULL)
613         /* This is an unbuffered stream, so the target sync above
614            won't do anything the next time around.  Instead, note that
615            we have read one character.  The (nonexistent) buffer now
616            maps to the position just past that character.  */
617         ++fp->__target;
618     }
619   else
620     {
621       /* A NULL `input_room' function means always return EOF.  */
622       fp->__eof = 1;
623       c = EOF;
624     }
625
626   return c;
627 }
628
629
630 /* Nuke a stream, but don't kill its link in the chain.  */
631 void
632 DEFUN(__invalidate, (stream), register FILE *stream)
633 {
634   /* Save its link.  */
635   register FILE *next = stream->__next;
636
637   /* Pulverize the fucker.  */
638   memset((PTR) stream, 0, sizeof(FILE));
639
640   /* Restore the deceased's link.  */
641   stream->__next = next;
642 }