xref: /csrg-svn/lib/libc/stdio/findfp.c (revision 24936)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)findfp.c	5.2 (Berkeley) 09/18/85";
9 #endif not lint
10 
11 #include <stdio.h>
12 #include <errno.h>
13 
14 extern int errno;
15 
16 #define active(iop)	((iop)->_flag & (_IOREAD|_IOWRT|_IORW))
17 
18 #define NSTATIC	3	/* stdin + stdout + stderr */
19 
20 FILE _iob[NSTATIC] = {
21 	{ 0, NULL, NULL, 0, _IOREAD,		0 },	/* stdin  */
22 	{ 0, NULL, NULL, 0, _IOWRT,		1 },	/* stdout */
23 	{ 0, NULL, NULL, 0, _IOWRT|_IONBF,	2 },	/* stderr */
24 };
25 
26 static	FILE	*_lastbuf = _iob + NSTATIC;
27 
28 extern	char	*calloc();
29 
30 static	FILE	**iobglue;
31 static	FILE	**endglue;
32 static	int	nfiles;
33 
34 FILE *
35 _findiop()
36 {
37 	register FILE **iov;
38 	register FILE *fp;
39 
40 	if (nfiles <= 0)
41 		nfiles = getdtablesize();
42 
43 	if (iobglue == NULL) {
44 		iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
45 		if (iobglue == NULL)
46 			return (NULL);
47 
48 		endglue = iobglue + nfiles;
49 
50 		iov = iobglue;
51 		for (fp = _iob; fp < _lastbuf; /* void */)
52 			*iov++ = fp++;
53 	}
54 
55 	iov = iobglue;
56 	while (*iov != NULL && active(*iov))
57 		if (++iov >= endglue) {
58 			errno = EMFILE;
59 			return (NULL);
60 		}
61 
62 	if (*iov == NULL)
63 		*iov = (FILE *)calloc(1, sizeof **iov);
64 
65 	return (*iov);
66 }
67 
68 _fwalk(function)
69 	register int (*function)();
70 {
71 	register FILE **iov;
72 	register FILE *fp;
73 
74 	if (function == NULL)
75 		return;
76 
77 	if (iobglue == NULL) {
78 		for (fp = _iob; fp < _lastbuf; fp++)
79 			if (active(fp))
80 				(*function)(fp);
81 	} else {
82 		for (iov = iobglue; iov < endglue; iov++)
83 			if (*iov != NULL && active(*iov))
84 				(*function)(*iov);
85 	}
86 }
87 
88 _cleanup()
89 {
90 	extern int fclose();
91 
92 	_fwalk(fclose);
93 }
94