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