Initial revision
[kopensolaris-gnu/glibc.git] / stdio / internals.c
1 /* Copyright (C) 1991 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   if (stream->__offset == (fpos_t) -1)
94     {
95       /* This stream's offset is unknown or unknowable.  */
96       if (stream->__io_funcs.__seek == NULL)
97         {
98           /* Unknowable.  */
99           errno = ESPIPE;
100           return EOF;
101         }
102       else
103         {
104           /* Unknown.  Find it out. */
105           fpos_t pos = (fpos_t) 0;
106           if ((*stream->__io_funcs.__seek)(stream->__cookie,
107                                            &pos, SEEK_CUR) < 0)
108             {
109               if (errno == ESPIPE)
110                 /* Object is incapable of seeking.  */
111                 stream->__io_funcs.__seek = NULL;
112               return EOF;
113             }
114           stream->__offset = pos;
115         }
116     }
117
118   if (stream->__target == (fpos_t) -1)
119     /* This stream was opened on an existing object with
120        an unknown file position.  The position is now known.
121        Make this the target position.  */
122     stream->__target = stream->__offset;
123
124   return 0;
125 }
126
127
128 /* Move FP's file position to its target file position,
129    seeking as necessary and updating its `offset' field.
130    Sets ferror(FP) (and possibly errno) for errors.  */
131 static void
132 DEFUN(seek_to_target, (fp), FILE *fp)
133 {
134   if (fp->__target != fp->__offset)
135     {
136       /* We are not at the target file position.
137          Seek to that position.  */
138       if (fp->__io_funcs.__seek == NULL)
139         {
140           /* We can't seek!  */
141           errno = ESPIPE;
142           fp->__error = 1;
143         }
144       else
145         {
146           fpos_t pos = fp->__target;
147           if ((*fp->__io_funcs.__seek)(fp->__cookie, &pos, SEEK_SET) < 0)
148             /* Seek failed!  */
149             fp->__error = 1;
150           else
151             {
152               fp->__offset = pos;
153               if (pos != fp->__target)
154                 /* Seek didn't go to the right place!  */
155                 fp->__error = 1;
156             }
157         }
158     }
159 }
160
161 /* Flush the buffer for FP.
162    If C is not EOF, it is also to be written.
163    If the stream is line buffered and C is a newline, it is written
164    to the output, otherwise it is put in the buffer after it has been
165    flushed to avoid a system call for a single character.
166    This is the default `output room' function.  */
167 static void
168 DEFUN(flushbuf, (fp, c),
169       register FILE *fp AND int c)
170 {
171   int flush_only = c == EOF;
172   size_t to_write;
173   int target_set = 0;
174
175   if (fp->__put_limit == fp->__buffer)
176     {
177       /* The stream needs to be primed for writing.  */
178
179       size_t buffer_offset = 0;
180
181       if (fp->__mode.__read && fp->__room_funcs.__input != NULL)
182         {
183           int save = errno;
184           CONST int aligned = (__stdio_check_offset(fp) == EOF ||
185                                fp->__target % fp->__bufsize == 0);
186           errno = save;
187
188           if (!aligned)
189             {
190               /* Move to a block (buffer size) boundary and read in a block.
191                  Then the output will be written as a whole block, too.  */
192               CONST size_t o = fp->__target % fp->__bufsize;
193               fp->__target -= o;
194               if ((*fp->__room_funcs.__input)(fp) == EOF && ferror(fp))
195                 return;
196               else
197                 __clearerr(fp);
198
199               if (fp->__get_limit - fp->__buffer < o)
200                 /* Oops.  We didn't read enough (probably because we got EOF).
201                    Forget we even mentioned it.  */
202                 fp->__target += o;
203               else
204                 /* Start bufp as far into the buffer as we were into
205                    this block before we read it.  */
206                 buffer_offset = o;
207             }
208
209           /* The target position is now set to where
210              the beginning of the buffer maps to.  */
211           target_set = 1;
212         }
213
214       if (fp->__buffer != NULL)
215         {
216           /* Set up to write output into the buffer.  */
217           fp->__put_limit = fp->__buffer + fp->__bufsize;
218           fp->__bufp = fp->__buffer + buffer_offset;
219           if (!flush_only)
220             {
221               *fp->__bufp++ = (unsigned char) c;
222               if (!fp->__linebuf || (unsigned char) c != '\n')
223                 return;
224               flush_only = 1;
225             }
226         }
227     }
228
229   /* If there is read data in the buffer past what was written,
230      write all of that as well.  Otherwise, just write what has been
231      written into the buffer.  */
232   to_write = (fp->__get_limit > fp->__bufp ?
233               fp->__get_limit - fp->__buffer :
234               fp->__bufp - fp->__buffer);
235
236   if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only))
237     {
238       /* There is no writing function or we're coming from an fflush
239          call with nothing in the buffer, so just say the buffer's
240          been flushed, increment the file offset, and return.  */
241       fp->__bufp = fp->__buffer;
242       fp->__offset += to_write;
243       goto end;
244     }
245
246   if (to_write > 0)
247     {
248       int wrote;
249
250       /* Go to the target file position.  */
251       seek_to_target(fp);
252
253       if (!ferror(fp))
254         {
255           /* Write out the buffered data.  */
256           wrote = (*fp->__io_funcs.__write)(fp->__cookie, fp->__buffer,
257                                             to_write);
258           if (wrote > 0)
259             /* Record that we've moved forward in the file.  */
260             fp->__offset += wrote;
261           if (wrote < (int) to_write)
262             /* The writing function should always write
263                the whole buffer unless there is an error.  */
264             fp->__error = 1;
265         }
266     }
267
268   /* Reset the buffer pointer to the beginning of the buffer.  */
269   fp->__bufp = fp->__buffer;
270
271   /* If we're not just flushing, write the last character, C.  */
272   if (!flush_only && !ferror(fp))
273     {
274       if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n'))
275         {
276           /* Either we're unbuffered, or we're line-buffered and
277              C is a newline, so really write it out immediately.  */
278           char cc = (unsigned char) c;
279           if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1)
280             fp->__error = 1;
281           else
282             /* Record that we've moved forward in the file.  */
283             ++fp->__offset;
284         }
285       else
286         /* Just put C in the buffer.  */
287         *fp->__bufp++ = (unsigned char) c;
288     }
289
290  end:;
291
292   if (!target_set)
293     /* The beginning of the buffer now maps to
294        just past the data we have just written.  */
295     fp->__target = fp->__offset;
296
297   if (!fp->__mode.__write)
298     /* Set the reading limit to the beginning of the buffer,
299        so the next `getc' will call __fillbf.  */
300     fp->__get_limit = fp->__buffer;
301
302   if (feof(fp) || ferror(fp))
303     fp->__bufp = fp->__put_limit;
304 }
305
306
307 /* Fill the buffer for FP and return the first character read (or EOF).
308    This is the default `input_room' function.  */
309 static int
310 DEFUN(fillbuf, (fp), register FILE *fp)
311 {
312   /* How far into the buffer we read we want to start bufp.  */
313   size_t buffer_offset = 0;
314   register char *buffer;
315   register size_t to_read, nread = 0;
316   char c;
317
318   if (fp->__io_funcs.__read == NULL)
319     {
320       /* There is no read function, so always return EOF.  */
321       fp->__eof = 1;
322       goto end;
323     }
324
325   if (fp->__buffer == NULL)
326     {
327       /* We're unbuffered, so we want to read only one character.  */
328       buffer = &c;
329       to_read = 1;
330     }
331   else
332     {
333       /* We're buffered, so try to fill the buffer.  */
334       buffer = fp->__buffer;
335       to_read = fp->__bufsize;
336     }
337
338   /* We're reading, so we're not at the end-of-file.  */
339   fp->__eof = 0;
340
341   /* Go to the target file position.  */
342   {
343     int save = errno;
344     if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset)
345       {
346         /* Move to a block (buffer size) boundary.  */
347         if (fp->__bufsize != 0)
348           {
349             buffer_offset = fp->__target % fp->__bufsize;
350             fp->__target -= buffer_offset;
351           }
352         seek_to_target (fp);
353       }
354     errno = save;
355   }
356
357   while (!ferror(fp) && !feof(fp) && nread <= buffer_offset)
358     {
359       /* Try to fill the buffer.  */
360       int count = (*fp->__io_funcs.__read)(fp->__cookie, buffer, to_read);
361       if (count == 0)
362         fp->__eof = 1;
363       else if (count < 0)
364         fp->__error = 1;
365       else
366         {
367           buffer += count;
368           nread += count;
369           to_read -= count;
370           /* Record that we've moved forward in the file.  */
371           fp->__offset += count;
372         }
373     }
374
375   if (fp->__buffer == NULL)
376     /* There is no buffer, so return the character we read
377        without all the buffer pointer diddling.  */
378     return (feof(fp) || ferror(fp)) ? EOF : c;
379
380   /* Reset the buffer pointer to the beginning of the buffer
381      (plus whatever offset we may have set above).  */
382   fp->__bufp = fp->__buffer + buffer_offset;
383
384  end:;
385
386   if (feof(fp) || ferror(fp))
387     {
388       /* Set both end pointers to the beginning of the buffer so
389          the next i/o call will force a call to __fillbf/__flshfp.  */
390       fp->__put_limit = fp->__get_limit = fp->__buffer;
391       return EOF;
392     }
393
394   /* Set the end pointer to one past the last character we read.  */
395   fp->__get_limit = fp->__buffer + nread;
396
397   if (fp->__mode.__write)
398     /* Allow writing into the buffer.  */
399     fp->__put_limit = fp->__buffer + fp->__bufsize;
400   else
401     /* Make it so the next `putc' will call __flshfp.  */
402     fp->__put_limit = fp->__buffer;
403
404   /* Return the first character in the buffer.  */
405   return (unsigned char) *fp->__bufp++;
406 }
407
408
409 /* Default I/O and room functions.  */
410
411 extern __io_read __stdio_read;
412 extern __io_write __stdio_write;
413 extern __io_seek __stdio_seek;
414 extern __io_close __stdio_close;
415 CONST __io_functions __default_io_functions =
416   {
417     __stdio_read, __stdio_write, __stdio_seek, __stdio_close
418   };
419
420 CONST __room_functions __default_room_functions =
421   {
422     fillbuf, flushbuf
423   };
424
425
426 /* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero.
427    This is the function used by putc and fflush.  */
428 int
429 DEFUN(__flshfp, (fp, c),
430       register FILE *fp AND int c)
431 {
432   int flush_only = c == EOF;
433
434   if (!__validfp(fp) || !fp->__mode.__write)
435     {
436       errno = EINVAL;
437       return EOF;
438     }
439
440   if (ferror(fp))
441     return EOF;
442
443   /* Make sure the stream is initialized (has functions and buffering).  */
444   init_stream(fp);
445
446   if (!flush_only && fp->__get_limit == fp->__buffer &&
447       fp->__bufp > fp->__buffer && fp->__bufp < fp->__buffer + fp->__bufsize)
448     {
449       /* The character will fit in the buffer, so put it there.  */
450       *fp->__bufp++ = (unsigned char) c;
451       if (fp->__linebuf && (unsigned char) c == '\n')
452         flush_only = 1;
453       else
454         return (unsigned char) c;
455     }
456
457   if (fp->__room_funcs.__output == NULL)
458     {
459       /* A NULL `output room' function means
460          to always return an output error.  */
461       fp->__error = 1;
462       return EOF;
463     }
464
465   if (!flush_only || fp->__bufp > fp->__buffer)
466     {
467       if (fp->__linebuf && fp->__bufp > fp->__buffer)
468         /* This is a line-buffered stream, so its put-limit is
469            set to the beginning of the buffer in order to force
470            a __flshfp call on each putc.  We undo this hack here
471            (by setting the limit to the end of the buffer) to simplify
472            the interface with the output-room function.
473            However, we must make sure we don't do this if there isn't
474            actually anything in the buffer, because in that case we
475            want to give the output-room function a chance to prime
476            the stream for writing in whatever fashion turns it on.  */
477         fp->__put_limit = fp->__buffer + fp->__bufsize;
478
479       /* Make room in the buffer.  */
480       (*fp->__room_funcs.__output)(fp, flush_only ? EOF : (unsigned char) c);
481
482       if (fp->__linebuf)
483         /* Set the end pointer to the beginning of the buffer,
484            so the next `putc' call will force a call to this function
485            (see comment above about line-buffered streams).  */
486         fp->__put_limit = fp->__buffer;
487     }
488
489   if (ferror (fp))
490     return EOF;
491   if (flush_only)
492     return 0;
493   return (unsigned char) c;
494 }
495
496
497 /* Fill the buffer for FP and return the first character read.
498    This is the function used by getc.  */
499 int
500 DEFUN(__fillbf, (fp), register FILE *fp)
501 {
502   register int c;
503
504   if (!__validfp(fp) || !fp->__mode.__read)
505     {
506       errno = EINVAL;
507       return EOF;
508     }
509
510   if (fp->__pushed_back)
511     {
512       /* Return the char pushed back by ungetc.  */
513       fp->__bufp = fp->__pushback_bufp;
514       fp->__pushed_back = 0;
515       return fp->__pushback;
516     }
517
518   /* Make sure the stream is initialized (has functions and buffering). */
519   init_stream(fp);
520
521   /* If we're trying to read the first character of a new
522      line of input from an unbuffered or line buffered stream,
523      we must flush all line-buffered output streams. */
524   if (fp->__buffer == NULL || fp->__linebuf)
525     {
526       register FILE *f;
527       for (f = __stdio_head; f != NULL; f = f->__next)
528         if (__validfp(f) && f->__linebuf && f->__mode.__write &&
529             f->__put_limit > f->__buffer)
530           (void) __flshfp(f, EOF);
531     }
532
533   if (fp->__put_limit > fp->__buffer)
534     {
535       /* There is written data in the buffer.
536          Flush it out.  */
537       if (fp->__room_funcs.__output == NULL)
538         fp->__error = 1;
539       else
540         {
541           fpos_t target = fp->__target;
542           (*fp->__room_funcs.__output)(fp, EOF);
543           fp->__target = target;
544         }
545     }
546
547   /* We want the beginning of the buffer to now
548      map to just past the last data we read.  */
549   fp->__target += fp->__get_limit - fp->__buffer;
550
551   if (ferror(fp))
552     c = EOF;
553   else if (fp->__room_funcs.__input != NULL)
554     {
555       c = (*fp->__room_funcs.__input)(fp);
556       if (fp->__buffer == NULL)
557         /* This is an unbuffered stream, so the target sync above
558            won't do anything the next time around.  Instead, note that
559            we have read one character.  The (nonexistent) buffer now
560            maps to the position just past that character.  */
561         ++fp->__target;
562     }
563   else
564     {
565       /* A NULL `input_room' function means always return EOF.  */
566       fp->__eof = 1;
567       c = EOF;
568     }
569
570   return c;
571 }
572
573
574 /* Nuke a stream, but don't kill its link in the chain.  */
575 void
576 DEFUN(__invalidate, (stream), register FILE *stream)
577 {
578   /* Save its link.  */
579   register FILE *next = stream->__next;
580
581   /* Pulverize the fucker.  */
582   memset((PTR) stream, 0, sizeof(FILE));
583
584   /* Restore the deceased's link.  */
585   stream->__next = next;
586 }
587
588
589 /* Abort with an error message.  */
590 __NORETURN
591 void
592 DEFUN(__libc_fatal, (message), CONST char *message)
593 {
594   __stdio_errmsg(message, strlen(message));
595   abort();
596 }