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