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