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 7*26645Sdonn #if defined(LIBC_SCCS) && !defined(lint) 8*26645Sdonn static char sccsid[] = "@(#)findfp.c 5.6 (Berkeley) 03/09/86"; 9*26645Sdonn #endif LIBC_SCCS and 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 2626129Skarels extern char *calloc(); 2718248Sserge 2826119Skarels static char sbuf[NSTATIC]; 2926119Skarels char *_smallbuf = sbuf; 3018248Sserge static FILE **iobglue; 3118248Sserge static FILE **endglue; 3218248Sserge 3326119Skarels /* 3426119Skarels * Find a free FILE for fopen et al. 3526119Skarels * We have a fixed static array of entries, and in addition 3626119Skarels * may allocate additional entries dynamically, up to the kernel 3726119Skarels * limit on the number of open files. 3826119Skarels * At first just check for a free slot in the fixed static array. 3926119Skarels * If none are available, then we allocate a structure to glue together 4026119Skarels * the old and new FILE entries, which are then no longer contiguous. 4126119Skarels */ 4217874Sserge FILE * 4317874Sserge _findiop() 4417874Sserge { 4526119Skarels register FILE **iov, *iop; 4617874Sserge register FILE *fp; 4717874Sserge 4826119Skarels if (iobglue == 0) { 4926119Skarels for (iop = _iob; iop < _iob + NSTATIC; iop++) 5026119Skarels if (!active(iop)) 5126119Skarels return (iop); 5226119Skarels 5326119Skarels if (_f_morefiles() == 0) { 5426119Skarels errno = ENOMEM; 5526119Skarels return (NULL); 5626119Skarels } 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) 6726129Skarels *iov = (FILE *)calloc(1, sizeof **iov); 6818248Sserge 6918248Sserge return (*iov); 7017874Sserge } 7117874Sserge 7226119Skarels _f_morefiles() 7326097Skarels { 7426097Skarels register FILE **iov; 7526097Skarels register FILE *fp; 7626119Skarels register char *cp; 7726119Skarels int nfiles; 7826097Skarels 7926097Skarels nfiles = getdtablesize(); 8026097Skarels 8126129Skarels iobglue = (FILE **)calloc(nfiles, sizeof *iobglue); 8226097Skarels if (iobglue == NULL) 8326097Skarels return (0); 8426097Skarels 8526097Skarels endglue = iobglue + nfiles; 8626097Skarels 8726097Skarels for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */) 8826097Skarels *iov++ = fp++; 8926119Skarels 9026129Skarels _smallbuf = calloc(nfiles, sizeof(*_smallbuf)); 9126097Skarels return (1); 9226097Skarels } 9326097Skarels 9426097Skarels f_prealloc() 9526097Skarels { 9626097Skarels register FILE **iov; 9726097Skarels register FILE *fp; 9826097Skarels 9926119Skarels if (iobglue == NULL && _f_morefiles() == 0) 10026097Skarels return; 10126097Skarels 10226097Skarels for (iov = iobglue; iov < endglue; iov++) 10326129Skarels if (*iov == NULL) 10426129Skarels *iov = (FILE *)calloc(1, sizeof **iov); 10526097Skarels } 10626097Skarels 10718248Sserge _fwalk(function) 10818248Sserge register int (*function)(); 10917874Sserge { 11018248Sserge register FILE **iov; 11118248Sserge register FILE *fp; 11217874Sserge 11318248Sserge if (iobglue == NULL) { 11426097Skarels for (fp = _iob; fp < &_iob[NSTATIC]; fp++) 11518248Sserge if (active(fp)) 11618248Sserge (*function)(fp); 11718248Sserge } else { 11818248Sserge for (iov = iobglue; iov < endglue; iov++) 11926097Skarels if (*iov && active(*iov)) 12018248Sserge (*function)(*iov); 12118248Sserge } 12217874Sserge } 12317951Sserge 12418248Sserge _cleanup() 12517951Sserge { 12618248Sserge extern int fclose(); 12718248Sserge 12818248Sserge _fwalk(fclose); 12917951Sserge } 130