(flushbuf): If !FLUSH_ONLY, don't skip out early if no new data in buffer
[kopensolaris-gnu/glibc.git] / stdio / internals.c
1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995 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       if (fp->__bufp - fp->__buffer <= buffer_offset && flush_only)
269         {
270           /* There is nothing new in the buffer, only data that
271              was read back aligned from the file.  */
272           buffer_written = 0;
273           goto end;
274         }
275     }
276
277   /* If there is read data in the buffer past what was written,
278      write all of that as well.  Otherwise, just write what has been
279      written into the buffer.  */
280   buffer_written = fp->__bufp - fp->__buffer;
281   to_write = (buffer_written == 0 ? 0 :
282               fp->__get_limit > fp->__bufp ?
283               fp->__get_limit - fp->__buffer :
284               buffer_written);
285
286   if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only))
287     {
288       /* There is no writing function or we're coming from an fflush
289          call with nothing in the buffer, so just say the buffer's
290          been flushed, increment the file offset, and return.  */
291       fp->__bufp = fp->__buffer;
292       fp->__offset += to_write;
293       goto end;
294     }
295
296   if (to_write > 0)
297     {
298       int wrote;
299
300       /* Go to the target file position.  Don't bother if appending;
301          the write will just ignore the file position anyway.  */
302       if (!fp->__mode.__append)
303         seek_to_target (fp);
304
305       if (!ferror(fp))
306         {
307           /* Write out the buffered data.  */
308           wrote = (*fp->__io_funcs.__write)(fp->__cookie, fp->__buffer,
309                                             to_write);
310           if (wrote > 0)
311             {
312               if (fp->__mode.__append)
313                 /* The write has written the data to the end of the file
314                    and updated the file position to after the data.  Don't
315                    bother to find the current position; we can get it
316                    later if we need it.  */
317                 fp->__offset = fp->__target = -1;
318               else
319                 /* Record that we've moved forward in the file.  */
320                 fp->__offset += wrote;
321             }
322           if (wrote < (int) to_write)
323             /* The writing function should always write
324                the whole buffer unless there is an error.  */
325             fp->__error = 1;
326         }
327     }
328
329   /* Reset the buffer pointer to the beginning of the buffer.  */
330   fp->__bufp = fp->__buffer;
331
332   /* If we're not just flushing, write the last character, C.  */
333   if (!flush_only && !ferror(fp))
334     {
335       if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n'))
336         {
337           /* Either we're unbuffered, or we're line-buffered and
338              C is a newline, so really write it out immediately.  */
339           char cc = (unsigned char) c;
340           if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1)
341             fp->__error = 1;
342           else
343             {
344               /* Record that we've moved forward in the file.  */
345               ++fp->__offset;
346               ++fp->__target;
347             }
348         }
349       else
350         /* Just put C in the buffer.  */
351         *fp->__bufp++ = (unsigned char) c;
352     }
353
354  end:
355
356   if (!twiddled)
357     {
358       /* The new target position moves up as
359          much as the user wrote into the buffer.  */
360       fp->__target += buffer_written;
361
362       /* Set the reading limit to the beginning of the buffer,
363          so the next `getc' will call __fillbf.  */
364       fp->__get_limit = fp->__buffer;
365     }
366
367   if (feof(fp) || ferror(fp))
368     fp->__bufp = fp->__put_limit;
369 }
370
371
372 /* Fill the buffer for FP and return the first character read (or EOF).
373    This is the default `input_room' function.  */
374 static int
375 DEFUN(fillbuf, (fp), register FILE *fp)
376 {
377   /* How far into the buffer we read we want to start bufp.  */
378   size_t buffer_offset = 0;
379   register char *buffer;
380   register size_t to_read, nread = 0;
381   /* This must be unsigned to avoid sign extension in return.  */
382   unsigned char c;
383
384   if (fp->__io_funcs.__read == NULL)
385     {
386       /* There is no read function, so always return EOF.  */
387       fp->__eof = 1;
388       goto end;
389     }
390
391   if (fp->__buffer == NULL)
392     {
393       /* We're unbuffered, so we want to read only one character.  */
394       buffer = (char *) &c;
395       to_read = 1;
396     }
397   else
398     {
399       /* We're buffered, so try to fill the buffer.  */
400       buffer = fp->__buffer;
401       to_read = fp->__bufsize;
402     }
403
404   /* We're reading, so we're not at the end-of-file.  */
405   fp->__eof = 0;
406
407   /* Go to the target file position.  */
408   {
409     int save = errno;
410     if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset)
411       {
412         /* Move to a block (buffer size) boundary.  */
413         if (fp->__bufsize != 0)
414           {
415             buffer_offset = fp->__target % fp->__bufsize;
416             fp->__target -= buffer_offset;
417           }
418         seek_to_target (fp);
419       }
420     errno = save;
421   }
422
423   while (!ferror(fp) && !feof(fp) && nread <= buffer_offset)
424     {
425       /* Try to fill the buffer.  */
426       int count = (*fp->__io_funcs.__read)(fp->__cookie, buffer, to_read);
427       if (count == 0)
428         fp->__eof = 1;
429       else if (count < 0)
430         fp->__error = 1;
431       else
432         {
433           buffer += count;
434           nread += count;
435           to_read -= count;
436           /* Record that we've moved forward in the file.  */
437           fp->__offset += count;
438         }
439     }
440
441   if (fp->__buffer == NULL)
442     /* There is no buffer, so return the character we read
443        without all the buffer pointer diddling.  */
444     return (feof(fp) || ferror(fp)) ? EOF : c;
445
446   /* Reset the buffer pointer to the beginning of the buffer
447      (plus whatever offset we may have set above).  */
448   fp->__bufp = fp->__buffer + buffer_offset;
449
450  end:;
451
452   if (feof(fp) || ferror(fp))
453     {
454       /* Set both end pointers to the beginning of the buffer so
455          the next i/o call will force a call to __fillbf/__flshfp.  */
456       fp->__put_limit = fp->__get_limit = fp->__buffer;
457       return EOF;
458     }
459
460   /* Set the end pointer to one past the last character we read.  */
461   fp->__get_limit = fp->__buffer + nread;
462
463   /* Make it so the next `putc' will call __flshfp.  */
464   fp->__put_limit = fp->__buffer;
465
466   /* Return the first character in the buffer.  */
467   return *((unsigned char *) (fp->__bufp++));
468 }
469
470
471 /* Default I/O and room functions.  */
472
473 extern __io_read_fn __stdio_read;
474 extern __io_write_fn __stdio_write;
475 extern __io_seek_fn __stdio_seek;
476 extern __io_close_fn __stdio_close;
477 extern __io_fileno_fn __stdio_fileno;
478 CONST __io_functions __default_io_functions =
479   {
480     __stdio_read, __stdio_write, __stdio_seek, __stdio_close, __stdio_fileno
481   };
482
483 CONST __room_functions __default_room_functions =
484   {
485     fillbuf, flushbuf
486   };
487
488
489 /* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero.
490    This is the function used by putc and fflush.  */
491 int
492 DEFUN(__flshfp, (fp, c),
493       register FILE *fp AND int c)
494 {
495   int flush_only = c == EOF;
496
497   if (!__validfp(fp) || !fp->__mode.__write)
498     {
499       errno = EINVAL;
500       return EOF;
501     }
502
503   if (ferror(fp))
504     return EOF;
505
506   if (fp->__pushed_back)
507     {
508       /* Discard the char pushed back by ungetc.  */
509       fp->__bufp = fp->__pushback_bufp;
510       fp->__pushed_back = 0;
511     }
512
513   /* Make sure the stream is initialized (has functions and buffering).  */
514   init_stream(fp);
515
516   /* Do this early, so a `putc' on such a stream will never return success.  */
517   if (fp->__room_funcs.__output == NULL)
518     {
519       /* A NULL `output room' function means
520          to always return an output error.  */
521       fp->__error = 1;
522       return EOF;
523     }
524
525   if (!flush_only &&
526       /* Will C fit into the buffer?
527          See below about linebuf_active.  */
528       fp->__bufp < (fp->__linebuf_active ? fp->__buffer + fp->__bufsize :
529                     fp->__put_limit))
530     {
531       /* The character will fit in the buffer, so put it there.  */
532       *fp->__bufp++ = (unsigned char) c;
533       if (fp->__linebuf && (unsigned char) c == '\n')
534         flush_only = 1;
535       else
536         return (unsigned char) c;
537     }
538
539   if (fp->__linebuf_active)
540     /* This is an active line-buffered stream, so its put-limit is set
541        to the beginning of the buffer in order to force a __flshfp call
542        on each putc (see below).  We undo this hack here (by setting
543        the limit to the end of the buffer) to simplify the interface
544        with the output-room function.  */
545     fp->__put_limit = fp->__buffer + fp->__bufsize;
546
547   /* Make room in the buffer.  */
548   (*fp->__room_funcs.__output) (fp, flush_only ? EOF : (unsigned char) c);
549
550   if (fp->__linebuf)
551     {
552       /* This is a line-buffered stream, and it is now ready to do
553          some output.  We call this an "active line-buffered stream".
554          We set the put_limit to the beginning of the buffer,
555          so the next `putc' call will force a call to this function.
556          Setting the linebuf_active flag tells the code above
557          (on the next call) to undo this hackery.  */
558       fp->__put_limit = fp->__buffer;
559       fp->__linebuf_active = 1;
560     }
561
562   if (ferror (fp))
563     return EOF;
564   if (flush_only)
565     return 0;
566   return (unsigned char) c;
567 }
568
569
570 /* Fill the buffer for FP and return the first character read.
571    This is the function used by getc.  */
572 int
573 DEFUN(__fillbf, (fp), register FILE *fp)
574 {
575   register int c;
576   fpos_t new_target;
577
578   if (!__validfp(fp) || !fp->__mode.__read)
579     {
580       errno = EINVAL;
581       return EOF;
582     }
583
584   if (fp->__pushed_back)
585     {
586       /* Return the char pushed back by ungetc.  */
587       fp->__bufp = fp->__pushback_bufp;
588       fp->__pushed_back = 0;
589       return fp->__pushback;
590     }
591
592   /* Make sure the stream is initialized (has functions and buffering). */
593   init_stream(fp);
594
595   /* If we're trying to read the first character of a new
596      line of input from an unbuffered or line buffered stream,
597      we must flush all line-buffered output streams. */
598   if (fp->__buffer == NULL || fp->__linebuf)
599     {
600       register FILE *f;
601       for (f = __stdio_head; f != NULL; f = f->__next)
602         if (__validfp (f) && f->__linebuf && f->__mode.__write)
603           (void) __flshfp (f, EOF);
604     }
605
606   /* Note we must do this after flushing all line-buffered
607      streams, or else __flshfp would undo it!  */
608   if (fp->__linebuf_active)
609     {
610       /* This is an active line-buffered stream, meaning it is in the midst
611          of writing, but has a bogus put_limit.  Restore it to normality.  */
612       fp->__put_limit = fp->__buffer + fp->__bufsize;
613       fp->__linebuf_active = 0;
614     }
615
616   /* We want the beginning of the buffer to now
617      map to just past the last data we read.  */
618   new_target = fp->__target + (fp->__get_limit - fp->__buffer);
619
620   if (fp->__put_limit > fp->__buffer)
621     {
622       /* There is written data in the buffer.
623          Flush it out.  */
624       if (fp->__room_funcs.__output == NULL)
625         fp->__error = 1;
626       else
627         (*fp->__room_funcs.__output) (fp, EOF);
628     }
629
630   fp->__target = new_target;
631
632   if (ferror(fp))
633     c = EOF;
634   else if (fp->__room_funcs.__input != NULL)
635     {
636       c = (*fp->__room_funcs.__input)(fp);
637       if (fp->__buffer == NULL)
638         /* This is an unbuffered stream, so the target sync above
639            won't do anything the next time around.  Instead, note that
640            we have read one character.  The (nonexistent) buffer now
641            maps to the position just past that character.  */
642         ++fp->__target;
643     }
644   else
645     {
646       /* A NULL `input_room' function means always return EOF.  */
647       fp->__eof = 1;
648       c = EOF;
649     }
650
651   return c;
652 }
653
654
655 /* Nuke a stream, but don't kill its link in the chain.  */
656 void
657 DEFUN(__invalidate, (stream), register FILE *stream)
658 {
659   /* Save its link.  */
660   register FILE *next = stream->__next;
661
662   /* Pulverize the fucker.  */
663   memset((PTR) stream, 0, sizeof(FILE));
664
665   /* Restore the deceased's link.  */
666   stream->__next = next;
667 }