mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	* locale/locale.c: Include errno.h. * locale/localedef.c: Likewise. Tue Sep 19 00:02:06 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * Makefile (distclean-1): Remove config.cache, config.log, config.h. (parent-mostlyclean): Remove all flavors of the parent library. * misc/mntent.c (getmntent): Skip multiple whitespace chars between fields. * hurd/hurdstartup.c (_hurd_startup): If RPC returns EXEC_STACK_ARGS flag, get args from stack. If args on stack but have info from RPC, relocate args on stack to make space for struct hurd_startup_data. * elf/dl-object.c: Include errno.h. * posix/execvp.c: Likewise. * dirent/scandir.c: Likewise. * sysdeps/posix/system.c: Likewise. * sysdeps/generic/setenv.c: Likewise. * stdlib/msort.c: Likewise. * stdio/memstream.c: Likewise. * stdio/fclose.c: Likewise. * stdio/getdelim.c: Likewise. * stdio/setvbuf.c: Likewise. * sysdeps/ieee754/ldexp.c: Likewise. * locale/locfile-parse.c: Likewise. * stdlib/lcong48_r.c: Don't check for null argument; let it fault. * stdlib/seed48_r.c: Likewise. * stdlib/srand48_r.c: Likewise. * stdlib/jrand48_r.c: Likewise. * stdlib/nrand48_r.c: Likewise. * misc/search.h: Many decls for hsearch functions.
		
			
				
	
	
		
			179 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 1991, 1992, 1994, 1995 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., 675 Mass Ave,
 | 
						||
Cambridge, MA 02139, USA.  */
 | 
						||
 | 
						||
#include <ansidecl.h>
 | 
						||
#include <stdio.h>
 | 
						||
#include <stdlib.h>
 | 
						||
#include <string.h>
 | 
						||
#include <errno.h>
 | 
						||
 | 
						||
struct memstream_info
 | 
						||
  {
 | 
						||
    char **buffer;
 | 
						||
    size_t *bufsize;
 | 
						||
  };
 | 
						||
 | 
						||
/* Enlarge STREAM's buffer.  */
 | 
						||
static void
 | 
						||
DEFUN(enlarge_buffer, (stream, c),
 | 
						||
      register FILE *stream AND int c)
 | 
						||
{
 | 
						||
  struct memstream_info *info = (struct memstream_info *) stream->__cookie;
 | 
						||
  size_t need;
 | 
						||
 | 
						||
  if (stream->__put_limit != stream->__buffer)
 | 
						||
    /* Record how much has actually been written into the buffer.  */
 | 
						||
    *info->bufsize = stream->__bufp - stream->__buffer;
 | 
						||
 | 
						||
  if (stream->__target != -1
 | 
						||
      && stream->__target > *info->bufsize)
 | 
						||
    /* Our target (where the buffer maps to) is always zero except when
 | 
						||
       the user just did a SEEK_END fseek.  If he sought within the
 | 
						||
       buffer, we need do nothing and will zero the target below.  If he
 | 
						||
       sought past the end of the object, grow and zero-fill the buffer
 | 
						||
       up to the target address.  */
 | 
						||
    need = stream->__target;
 | 
						||
  else
 | 
						||
    need = *info->bufsize;
 | 
						||
 | 
						||
  /* We always need an extra character in the buffer.  Either we are
 | 
						||
     writing C, or we are flushing and need to write a NUL terminator.  */
 | 
						||
  ++need;
 | 
						||
 | 
						||
  if (stream->__bufsize < need)
 | 
						||
    {
 | 
						||
      /* Enlarge the buffer.  */
 | 
						||
      char *newbuf;
 | 
						||
      size_t newsize;
 | 
						||
      if (stream->__bufsize * 2 < need)
 | 
						||
	newsize = need;
 | 
						||
      else
 | 
						||
	newsize = stream->__bufsize * 2;
 | 
						||
      newbuf = (char *) realloc ((PTR) stream->__buffer, newsize);
 | 
						||
      if (newbuf == NULL)
 | 
						||
	{
 | 
						||
	  stream->__error = 1;
 | 
						||
	  return;
 | 
						||
	}
 | 
						||
      *info->buffer = stream->__buffer = newbuf;
 | 
						||
      stream->__bufsize = newsize;
 | 
						||
    }
 | 
						||
 | 
						||
  stream->__target = stream->__offset = 0;
 | 
						||
  stream->__get_limit = stream->__bufp = stream->__buffer + *info->bufsize;
 | 
						||
  stream->__put_limit = stream->__buffer + stream->__bufsize;
 | 
						||
 | 
						||
  need -= stream->__bufp - stream->__buffer + 1;
 | 
						||
  if (need > 0)
 | 
						||
    {
 | 
						||
      /* We are extending the buffer after an fseek; zero-fill new space.  */
 | 
						||
      bzero (stream->__bufp, need);
 | 
						||
      stream->__bufp += need;
 | 
						||
    }
 | 
						||
 | 
						||
  if (c != EOF)
 | 
						||
    *stream->__bufp++ = (unsigned char) c;
 | 
						||
  else
 | 
						||
    *stream->__bufp = '\0';
 | 
						||
}
 | 
						||
 | 
						||
/* Seek function for memstreams.
 | 
						||
   There is no external state to munge.  */
 | 
						||
 | 
						||
static int
 | 
						||
DEFUN(seek, (cookie, pos, whence),
 | 
						||
      PTR cookie AND fpos_t *pos AND int whence)
 | 
						||
{
 | 
						||
  switch (whence)
 | 
						||
    {
 | 
						||
    case SEEK_SET:
 | 
						||
    case SEEK_CUR:
 | 
						||
      return 0;
 | 
						||
 | 
						||
    case SEEK_END:
 | 
						||
      /* Return the position relative to the end of the object.
 | 
						||
	 fseek has just flushed us, so the info is consistent.  */
 | 
						||
      *pos += *((struct memstream_info *) cookie)->bufsize;
 | 
						||
      return 0;
 | 
						||
 | 
						||
    default:
 | 
						||
      __libc_fatal ("memstream::seek called with bogus WHENCE\n");
 | 
						||
      return -1;
 | 
						||
    }
 | 
						||
}
 | 
						||
 | 
						||
static int
 | 
						||
DEFUN(free_info, (cookie), PTR cookie)
 | 
						||
{
 | 
						||
#if 0
 | 
						||
  struct memstream_info *info = (struct memstream_info *) cookie;
 | 
						||
  char *buf;
 | 
						||
 | 
						||
  buf = (char *) realloc ((PTR) *info->buffer, *info->bufsize);
 | 
						||
  if (buf != NULL)
 | 
						||
    *info->buffer = buf;
 | 
						||
#endif
 | 
						||
 | 
						||
  free (cookie);
 | 
						||
 | 
						||
  return 0;
 | 
						||
}
 | 
						||
 | 
						||
/* Open a stream that writes into a malloc'd buffer that is expanded as
 | 
						||
   necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
 | 
						||
   and the number of characters written on fflush or fclose.  */
 | 
						||
FILE *
 | 
						||
DEFUN(open_memstream, (bufloc, sizeloc),
 | 
						||
      char **bufloc AND size_t *sizeloc)
 | 
						||
{
 | 
						||
  FILE *stream;
 | 
						||
  struct memstream_info *info;
 | 
						||
 | 
						||
  if (bufloc == NULL || sizeloc == NULL)
 | 
						||
    {
 | 
						||
      errno = EINVAL;
 | 
						||
      return NULL;
 | 
						||
    }
 | 
						||
 | 
						||
  stream = fmemopen ((char *) NULL, BUFSIZ, "w+");
 | 
						||
  if (stream == NULL)
 | 
						||
    return NULL;
 | 
						||
 | 
						||
  info = (struct memstream_info *) malloc (sizeof (struct memstream_info));
 | 
						||
  if (info == NULL)
 | 
						||
    {
 | 
						||
      int save = errno;
 | 
						||
      (void) fclose (stream);
 | 
						||
      errno = save;
 | 
						||
      return NULL;
 | 
						||
    }
 | 
						||
 | 
						||
  stream->__room_funcs.__output = enlarge_buffer;
 | 
						||
  stream->__io_funcs.__seek = seek;
 | 
						||
  stream->__io_funcs.__close = free_info;
 | 
						||
  stream->__cookie = (PTR) info;
 | 
						||
  stream->__userbuf = 1;
 | 
						||
 | 
						||
  info->buffer = bufloc;
 | 
						||
  info->bufsize = sizeloc;
 | 
						||
 | 
						||
  *bufloc = stream->__buffer;
 | 
						||
 | 
						||
  return stream;
 | 
						||
}
 |