121402Sdist /* 226097Skarels * Copyright (c) 1983, 1985 Regents of the University of California. 321402Sdist * All rights reserved. The Berkeley software License Agreement 421402Sdist * specifies the terms and conditions for redistribution. 521402Sdist */ 621402Sdist 721402Sdist #ifndef lint 8*26119Skarels static char sccsid[] = "@(#)findfp.c 5.4 (Berkeley) 02/09/86"; 921402Sdist #endif not lint 1021402Sdist 1117951Sserge #include <stdio.h> 1224936Slepreau #include <errno.h> 1317874Sserge 1424936Slepreau extern int errno; 1524936Slepreau 1618248Sserge #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW)) 1717874Sserge 1826097Skarels #define NSTATIC 20 /* stdin + stdout + stderr + the usual */ 1917874Sserge 2017874Sserge FILE _iob[NSTATIC] = { 2118248Sserge { 0, NULL, NULL, 0, _IOREAD, 0 }, /* stdin */ 2218248Sserge { 0, NULL, NULL, 0, _IOWRT, 1 }, /* stdout */ 2318248Sserge { 0, NULL, NULL, 0, _IOWRT|_IONBF, 2 }, /* stderr */ 2417874Sserge }; 2517874Sserge 26*26119Skarels extern char *malloc(); 2718248Sserge 28*26119Skarels static char sbuf[NSTATIC]; 29*26119Skarels char *_smallbuf = sbuf; 3018248Sserge static FILE **iobglue; 3118248Sserge static FILE **endglue; 3218248Sserge 33*26119Skarels /* 34*26119Skarels * Find a free FILE for fopen et al. 35*26119Skarels * We have a fixed static array of entries, and in addition 36*26119Skarels * may allocate additional entries dynamically, up to the kernel 37*26119Skarels * limit on the number of open files. 38*26119Skarels * At first just check for a free slot in the fixed static array. 39*26119Skarels * If none are available, then we allocate a structure to glue together 40*26119Skarels * the old and new FILE entries, which are then no longer contiguous. 41*26119Skarels */ 4217874Sserge FILE * 4317874Sserge _findiop() 4417874Sserge { 45*26119Skarels register FILE **iov, *iop; 4617874Sserge register FILE *fp; 4717874Sserge 48*26119Skarels if (iobglue == 0) { 49*26119Skarels for (iop = _iob; iop < _iob + NSTATIC; iop++) 50*26119Skarels if (!active(iop)) 51*26119Skarels return (iop); 52*26119Skarels 53*26119Skarels if (_f_morefiles() == 0) { 54*26119Skarels errno = ENOMEM; 55*26119Skarels return (NULL); 56*26119Skarels } 5717874Sserge } 5817874Sserge 5918248Sserge iov = iobglue; 6018248Sserge while (*iov != NULL && active(*iov)) 6124936Slepreau if (++iov >= endglue) { 6224936Slepreau errno = EMFILE; 6317874Sserge return (NULL); 6424936Slepreau } 6517874Sserge 6618248Sserge if (*iov == NULL) 67*26119Skarels *iov = (FILE *)malloc(sizeof **iov); 68*26119Skarels if (*iov) 69*26119Skarels bzero((char *)*iov, sizeof(**iov)); 7018248Sserge 7118248Sserge return (*iov); 7217874Sserge } 7317874Sserge 74*26119Skarels _f_morefiles() 7526097Skarels { 7626097Skarels register FILE **iov; 7726097Skarels register FILE *fp; 78*26119Skarels register char *cp; 79*26119Skarels int nfiles; 8026097Skarels 8126097Skarels nfiles = getdtablesize(); 8226097Skarels 83*26119Skarels iobglue = (FILE **)malloc(nfiles * sizeof *iobglue); 8426097Skarels if (iobglue == NULL) 8526097Skarels return (0); 8626097Skarels 87*26119Skarels bzero((char *)iobglue, nfiles * sizeof(*iobglue)); 8826097Skarels endglue = iobglue + nfiles; 8926097Skarels 9026097Skarels for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */) 9126097Skarels *iov++ = fp++; 92*26119Skarels 93*26119Skarels _smallbuf = malloc(nfiles * sizeof(*_smallbuf)); 9426097Skarels return (1); 9526097Skarels } 9626097Skarels 9726097Skarels f_prealloc() 9826097Skarels { 9926097Skarels register FILE **iov; 10026097Skarels register FILE *fp; 10126097Skarels 102*26119Skarels if (iobglue == NULL && _f_morefiles() == 0) 10326097Skarels return; 10426097Skarels 10526097Skarels for (iov = iobglue; iov < endglue; iov++) 106*26119Skarels if (*iov == NULL) { 107*26119Skarels *iov = (FILE *)malloc(1, sizeof **iov); 108*26119Skarels if (*iov) 109*26119Skarels bzero((char *)*iov, sizeof(**iov)); 110*26119Skarels } 11126097Skarels } 11226097Skarels 11318248Sserge _fwalk(function) 11418248Sserge register int (*function)(); 11517874Sserge { 11618248Sserge register FILE **iov; 11718248Sserge register FILE *fp; 11817874Sserge 11918248Sserge if (iobglue == NULL) { 12026097Skarels for (fp = _iob; fp < &_iob[NSTATIC]; fp++) 12118248Sserge if (active(fp)) 12218248Sserge (*function)(fp); 12318248Sserge } else { 12418248Sserge for (iov = iobglue; iov < endglue; iov++) 12526097Skarels if (*iov && active(*iov)) 12618248Sserge (*function)(*iov); 12718248Sserge } 12817874Sserge } 12917951Sserge 13018248Sserge _cleanup() 13117951Sserge { 13218248Sserge extern int fclose(); 13318248Sserge 13418248Sserge _fwalk(fclose); 13517951Sserge } 136