findfp.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       findfp.c (4610B)
       ---
            1 /*-
            2  * Copyright (c) 1990, 1993
            3  *        The Regents of the University of California.  All rights reserved.
            4  *
            5  * This code is derived from software contributed to Berkeley by
            6  * Chris Torek.
            7  *
            8  * Redistribution and use in source and binary forms, with or without
            9  * modification, are permitted provided that the following conditions
           10  * are met:
           11  * 1. Redistributions of source code must retain the above copyright
           12  *    notice, this list of conditions and the following disclaimer.
           13  * 2. Redistributions in binary form must reproduce the above copyright
           14  *    notice, this list of conditions and the following disclaimer in the
           15  *    documentation and/or other materials provided with the distribution.
           16  * 3. All advertising materials mentioning features or use of this software
           17  *    must display the following acknowledgement:
           18  *        This product includes software developed by the University of
           19  *        California, Berkeley and its contributors.
           20  * 4. Neither the name of the University nor the names of its contributors
           21  *    may be used to endorse or promote products derived from this software
           22  *    without specific prior written permission.
           23  *
           24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
           25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
           26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
           27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
           28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
           29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
           30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
           31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
           32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
           33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
           34  * SUCH DAMAGE.
           35  */
           36 
           37 #if defined(LIBC_SCCS) && !defined(lint)
           38 static char rcsid[] = "$OpenBSD: findfp.c,v 1.2 1996/08/19 08:32:36 tholo Exp $";
           39 #endif /* LIBC_SCCS and not lint */
           40 
           41 #include <unistd.h>
           42 #include <stdio.h>
           43 #include <errno.h>
           44 #include <stdlib.h>
           45 #include <string.h>
           46 #include "local.h"
           47 #include "glue.h"
           48 
           49 int        __sdidinit;
           50 
           51 #define        NDYNAMIC 10                /* add ten more whenever necessary */
           52 
           53 #define        std(flags, file) \
           54         {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite}
           55 /*         p r w flags file _bf z  cookie      close    read    seek    write */
           56 
           57                                 /* the usual - (stdin + stdout + stderr) */
           58 static FILE usual[FOPEN_MAX - 3];
           59 static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
           60 
           61 FILE __sF[3] = {
           62         std(__SRD, STDIN_FILENO),                /* stdin */
           63         std(__SWR, STDOUT_FILENO),                /* stdout */
           64         std(__SWR|__SNBF, STDERR_FILENO)        /* stderr */
           65 };
           66 struct glue __sglue = { &uglue, 3, __sF };
           67 
           68 static struct glue *
           69 moreglue(n)
           70         register int n;
           71 {
           72         register struct glue *g;
           73         register FILE *p;
           74         static FILE empty;
           75 
           76         g = (struct glue *)malloc(sizeof(*g) + n * sizeof(FILE));
           77         if (g == NULL)
           78                 return (NULL);
           79         p = (FILE *)(g+1);
           80         g->next = NULL;
           81         g->niobs = n;
           82         g->iobs = p;
           83         while (--n >= 0)
           84                 *p++ = empty;
           85         return (g);
           86 }
           87 
           88 /*
           89  * Find a free FILE for fopen et al.
           90  */
           91 FILE *
           92 __sfp()
           93 {
           94         register FILE *fp;
           95         register int n;
           96         register struct glue *g;
           97 
           98         if (!__sdidinit)
           99                 __sinit();
          100         for (g = &__sglue;; g = g->next) {
          101                 for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
          102                         if (fp->_flags == 0)
          103                                 goto found;
          104                 if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL)
          105                         break;
          106         }
          107         return (NULL);
          108 found:
          109         fp->_flags = 1;                /* reserve this slot; caller sets real flags */
          110         fp->_p = NULL;                /* no current pointer */
          111         fp->_w = 0;                /* nothing to read or write */
          112         fp->_r = 0;
          113         fp->_bf._base = NULL;        /* no buffer */
          114         fp->_bf._size = 0;
          115         fp->_lbfsize = 0;        /* not line buffered */
          116         fp->_file = -1;                /* no file */
          117 /*        fp->_cookie = <any>; */        /* caller sets cookie, _read/_write etc */
          118         fp->_ub._base = NULL;        /* no ungetc buffer */
          119         fp->_ub._size = 0;
          120         fp->_lb._base = NULL;        /* no line buffer */
          121         fp->_lb._size = 0;
          122         return (fp);
          123 }
          124 
          125 /*
          126  * exit() calls _cleanup() through *__cleanup, set whenever we
          127  * open or buffer a file.  This chicanery is done so that programs
          128  * that do not use stdio need not link it all in.
          129  *
          130  * The name `_cleanup' is, alas, fairly well known outside stdio.
          131  */
          132 void
          133 _cleanup()
          134 {
          135         /* (void) _fwalk(fclose); */
          136         (void) _fwalk(__sflush);                /* `cheating' */
          137 }
          138 
          139 /*
          140  * __sinit() is called whenever stdio's internal variables must be set up.
          141  */
          142 void
          143 __sinit()
          144 {
          145         extern void (*__exit_flush)(void);
          146 
          147         /* make sure we clean up on exit */
          148         __exit_flush = _cleanup;                /* conservative */
          149         __sdidinit = 1;
          150 }