xref: /csrg-svn/lib/libc/stdio/findfp.c (revision 26119)
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