os/ossrv/genericopenlibs/cstdlib/LSTDIO/FINDFP.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* FINDFP.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-2008 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
/* No user fns here.  Pesch 15apr92. */
sl@0
     8
sl@0
     9
/*
sl@0
    10
 * Copyright (c) 1990 The Regents of the University of California.
sl@0
    11
 * All rights reserved.
sl@0
    12
 *
sl@0
    13
 * Redistribution and use in source and binary forms are permitted
sl@0
    14
 * provided that the above copyright notice and this paragraph are
sl@0
    15
 * duplicated in all such forms and that any documentation,
sl@0
    16
 * advertising materials, and other materials related to such
sl@0
    17
 * distribution and use acknowledge that the software was developed
sl@0
    18
 * by the University of California, Berkeley.  The name of the
sl@0
    19
 * University may not be used to endorse or promote products derived
sl@0
    20
 * from this software without specific prior written permission.
sl@0
    21
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
sl@0
    22
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
sl@0
    23
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
sl@0
    24
 */
sl@0
    25
sl@0
    26
#include <stdio_r.h>
sl@0
    27
#include <stdlib_r.h>
sl@0
    28
#include <errno.h>
sl@0
    29
#include <string.h>
sl@0
    30
#include "LOCAL.H"
sl@0
    31
sl@0
    32
/* Initialise a FILE structure to a starting state */
sl@0
    33
#ifdef __GCCXML__
sl@0
    34
static void
sl@0
    35
_std (FILE *ptr, int flags, int file, struct _reent *data)
sl@0
    36
#else
sl@0
    37
static void
sl@0
    38
std (FILE *ptr, int flags, int file, struct _reent *data)
sl@0
    39
#endif
sl@0
    40
{
sl@0
    41
  ptr->_p = 0;
sl@0
    42
  ptr->_r = 0;
sl@0
    43
  ptr->_w = 0;
sl@0
    44
  ptr->_flags = (short)flags;
sl@0
    45
  ptr->_file = (short)file;
sl@0
    46
  ptr->_bf._base = 0;
sl@0
    47
  ptr->_lbfsize = 0;
sl@0
    48
  ptr->_cookie = ptr;
sl@0
    49
  ptr->_read = __sread;
sl@0
    50
  ptr->_write = __swrite;
sl@0
    51
  ptr->_seek = __sseek;
sl@0
    52
  ptr->_close = __sclose;
sl@0
    53
  ptr->_data = data;
sl@0
    54
}
sl@0
    55
sl@0
    56
struct _glue *
sl@0
    57
__sfmoreglue (struct _reent *d, register int n)
sl@0
    58
{
sl@0
    59
  struct _glue *g;
sl@0
    60
  FILE *p;
sl@0
    61
sl@0
    62
  g = (struct _glue *) _malloc_r (d, sizeof (*g) + n * sizeof (FILE));
sl@0
    63
  if (g == NULL)
sl@0
    64
    return NULL;
sl@0
    65
  p = (FILE *) (g + 1);
sl@0
    66
  g->_next = NULL;
sl@0
    67
  g->_niobs = n;
sl@0
    68
  g->_iobs = p;
sl@0
    69
  memset (p, 0, n * sizeof (FILE));
sl@0
    70
  return g;
sl@0
    71
}
sl@0
    72
sl@0
    73
/*
sl@0
    74
 * Find a free FILE for fopen et al.
sl@0
    75
 */
sl@0
    76
sl@0
    77
FILE *
sl@0
    78
__sfp (struct _reent *d)
sl@0
    79
{
sl@0
    80
  FILE *fp;
sl@0
    81
  int n;
sl@0
    82
  struct _glue *g;
sl@0
    83
sl@0
    84
  if (!d->__sdidinit)
sl@0
    85
    __sinit (d);
sl@0
    86
  for (g = &d->__sglue;; g = g->_next)
sl@0
    87
    {
sl@0
    88
      for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
sl@0
    89
	if (fp->_flags == 0)
sl@0
    90
	  goto found;
sl@0
    91
      if (g->_next == NULL &&
sl@0
    92
	  (g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
sl@0
    93
	break;
sl@0
    94
    }
sl@0
    95
  d->_errno = ENOMEM;
sl@0
    96
  return NULL;
sl@0
    97
sl@0
    98
found:
sl@0
    99
  fp->_flags = 1;		/* reserve this slot; caller sets real flags */
sl@0
   100
  fp->_p = NULL;		/* no current pointer */
sl@0
   101
  fp->_w = 0;			/* nothing to read or write */
sl@0
   102
  fp->_r = 0;
sl@0
   103
  fp->_bf._base = NULL;		/* no buffer */
sl@0
   104
  fp->_bf._size = 0;
sl@0
   105
  fp->_lbfsize = 0;		/* not line buffered */
sl@0
   106
  fp->_file = -1;		/* no file */
sl@0
   107
  /* fp->_cookie = <any>; */	/* caller sets cookie, _read/_write etc */
sl@0
   108
  fp->_ub._base = NULL;		/* no ungetc buffer */
sl@0
   109
  fp->_ub._size = 0;
sl@0
   110
  fp->_lb._base = NULL;		/* no line buffer */
sl@0
   111
  fp->_lb._size = 0;
sl@0
   112
  fp->_data = d;
sl@0
   113
  return fp;
sl@0
   114
}
sl@0
   115
sl@0
   116
/*
sl@0
   117
 * exit() calls _cleanup() through *__cleanup, set whenever we
sl@0
   118
 * open or buffer a file.  This chicanery is done so that programs
sl@0
   119
 * that do not use stdio need not link it all in.
sl@0
   120
 *
sl@0
   121
 * The name `_cleanup' is, alas, fairly well known outside stdio.
sl@0
   122
 */
sl@0
   123
/**
sl@0
   124
A reentrant version of _cleanup().
sl@0
   125
*/
sl@0
   126
EXPORT_C void
sl@0
   127
_cleanup_r (struct _reent *ptr)
sl@0
   128
{
sl@0
   129
  (void) _fwalk(ptr, fclose);
sl@0
   130
}
sl@0
   131
sl@0
   132
#ifndef _REENT_ONLY
sl@0
   133
sl@0
   134
/**
sl@0
   135
Performs cleanup
sl@0
   136
*/
sl@0
   137
EXPORT_C void
sl@0
   138
_cleanup (void)
sl@0
   139
{
sl@0
   140
  _cleanup_r (_REENT);
sl@0
   141
}
sl@0
   142
#endif
sl@0
   143
sl@0
   144
/*
sl@0
   145
 * __sinit() is called whenever stdio's internal variables must be set up.
sl@0
   146
 */
sl@0
   147
sl@0
   148
void
sl@0
   149
__sinit (struct _reent *s)
sl@0
   150
{
sl@0
   151
  /* make sure we clean up on exit */
sl@0
   152
  s->__cleanup = _cleanup_r;	/* conservative */
sl@0
   153
  s->__sdidinit = 1;
sl@0
   154
sl@0
   155
#ifdef __GCCXML__
sl@0
   156
  _std (_stdin_r(s),  __SRD, 0, s);
sl@0
   157
  _std (_stdout_r(s), __SWR, 1, s);
sl@0
   158
  _std (_stderr_r(s), __SWR | __SNBF, 2, s);
sl@0
   159
#else
sl@0
   160
  std (_stdin_r(s),  __SRD, 0, s);
sl@0
   161
  std (_stdout_r(s), __SWR, 1, s);
sl@0
   162
  std (_stderr_r(s), __SWR | __SNBF, 2, s);
sl@0
   163
#endif
sl@0
   164
sl@0
   165
  /* initialise the head of the glue chain to cover stdim/stdout/stderr */
sl@0
   166
  s->__sglue._next = NULL;
sl@0
   167
  s->__sglue._niobs = 3;
sl@0
   168
  s->__sglue._iobs = &s->_sf[0];
sl@0
   169
}
sl@0
   170
sl@0
   171
/* Function interface to stdin/stdout/stderr 
sl@0
   172
 *
sl@0
   173
 * These functions should return a value which is fixed for any given
sl@0
   174
 * reentrancy context, but it doesn't have to be fixed at compile time,
sl@0
   175
 * and we don't need to have initialised stdio either.
sl@0
   176
 */
sl@0
   177
sl@0
   178
/**
sl@0
   179
Function interface to the "constants" stdin.
sl@0
   180
These functions guarantee to return a fixed value, so that it 
sl@0
   181
will be possible to use expressions such as if (fp != stdout) fclose(fp);
sl@0
   182
with complete confidence. Unfortunately it will rule out initialising global
sl@0
   183
variables with stdin/stdout/stderr, as in the common idiom:
sl@0
   184
sl@0
   185
static FILE *log = stderr;
sl@0
   186
sl@0
   187
This isn't currently possible with EPOC32. 
sl@0
   188
*/
sl@0
   189
EXPORT_C FILE *__stdin (void)
sl@0
   190
{
sl@0
   191
	return _stdin_r(_REENT);
sl@0
   192
}
sl@0
   193
sl@0
   194
/**
sl@0
   195
Function interface to the "constants" stdout
sl@0
   196
See __stdin
sl@0
   197
*/
sl@0
   198
EXPORT_C FILE *__stdout (void)
sl@0
   199
{
sl@0
   200
	return _stdout_r(_REENT);
sl@0
   201
}
sl@0
   202
sl@0
   203
/**
sl@0
   204
Function interface to the "constants" stderr
sl@0
   205
See __stdin
sl@0
   206
*/
sl@0
   207
EXPORT_C FILE *__stderr (void)
sl@0
   208
{
sl@0
   209
	return _stderr_r(_REENT);
sl@0
   210
}