/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Make sure that FP has its functions set. */
void
__stdio_check_funcs (register FILE *fp)
{
if (!fp->__seen)
{
/* Initialize the stream's info, including buffering info.
This may give a buffer, change I/O functions, etc.
If no buffer is set (and the stream is not made explicitly
unbuffered), we allocate a buffer below, using the bufsize
set by this function. */
extern void __stdio_init_stream __P ((FILE *));
fp->__room_funcs = __default_room_functions;
fp->__io_funcs = __default_io_functions;
__stdio_init_stream (fp);
fp->__seen = 1;
}
}
/* Minimum size of a buffer we will allocate by default.
If this much memory is not available,
the stream in question will be made unbuffered instead. */
#define MIN_BUFSIZE 128
/* Figure out what kind of buffering (none, line, or full)
and what buffer size to give FP. */
static void
init_stream (register FILE *fp)
{
__stdio_check_funcs (fp);
if (fp->__buffer == NULL && !fp->__userbuf)
{
int save;
if (fp->__bufsize == 0)
fp->__bufsize = BUFSIZ;
/* Try to get however many bytes of buffering __stdio_pickbuf
specified, but if that much memory isn't available,
try half as much each time until it succeeds or the buffer
size becomes too small to be useful. */
save = errno;
while (fp->__bufsize >= MIN_BUFSIZE)
{
fp->__buffer = (char *) malloc (fp->__bufsize);
if (fp->__buffer == NULL)
fp->__bufsize /= 2;
else
break;
}
__set_errno (save);
if (fp->__buffer == NULL)
{
/* We can't get space for the buffer, so make it unbuffered. */
fp->__userbuf = 1;
fp->__bufsize = 0;
}
}
if (fp->__bufp == NULL)
{
/* Set the buffer pointer to the beginning of the buffer. */
fp->__bufp = fp->__buffer;
fp->__put_limit = fp->__get_limit = fp->__buffer;
}
}
/* Determine the current file position of STREAM if it is unknown. */
int
__stdio_check_offset (stream)
FILE *stream;
{
init_stream (stream);
if (stream->__offset == (fpos_t) -1)
{
/* This stream's offset is unknown or unknowable. */
if (stream->__io_funcs.__seek == NULL)
{
/* Unknowable. */
__set_errno (ESPIPE);
return EOF;
}
else
{
/* Unknown. Find it out. */
fpos_t pos = (fpos_t) 0;
if ((*stream->__io_funcs.__seek) (stream->__cookie,
&