xref: /csrg-svn/lib/libc/stdio/findfp.c (revision 26097)
1 /*
2  * Copyright (c) 1983, 1985 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.3 (Berkeley) 02/06/86";
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	20	/* stdin + stdout + stderr + the usual */
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 extern	char	*calloc();
27 
28 static	FILE	**iobglue;
29 static	FILE	**endglue;
30 static	int	nfiles;
31 
32 FILE *
33 _findiop()
34 {
35 	register FILE **iov;
36 	register FILE *fp;
37 
38 	if (iobglue == 0 && _stdio_init() == 0) {
39 		errno = ENOMEM;
40 		return (NULL);
41 	}
42 
43 	iov = iobglue;
44 	while (*iov != NULL && active(*iov))
45 		if (++iov >= endglue) {
46 			errno = EMFILE;
47 			return (NULL);
48 		}
49 
50 	if (*iov == NULL)
51 		*iov = (FILE *)calloc(1, sizeof **iov);
52 
53 	return (*iov);
54 }
55 
56 _stdio_init()
57 {
58 	register FILE **iov;
59 	register FILE *fp;
60 
61 	nfiles = getdtablesize();
62 
63 	iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
64 	if (iobglue == NULL)
65 		return (0);
66 
67 	endglue = iobglue + nfiles;
68 
69 	for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */)
70 		*iov++ = fp++;
71 	return (1);
72 }
73 
74 f_prealloc()
75 {
76 	register FILE **iov;
77 	register FILE *fp;
78 
79 	if (iobglue == NULL && _stdio_init() == 0)
80 		return;
81 
82 	for (iov = iobglue; iov < endglue; iov++)
83 		if (*iov == NULL)
84 			*iov = (FILE *)calloc(1, sizeof **iov);
85 }
86 
87 _fwalk(function)
88 	register int (*function)();
89 {
90 	register FILE **iov;
91 	register FILE *fp;
92 
93 	if (iobglue == NULL) {
94 		for (fp = _iob; fp < &_iob[NSTATIC]; fp++)
95 			if (active(fp))
96 				(*function)(fp);
97 	} else {
98 		for (iov = iobglue; iov < endglue; iov++)
99 			if (*iov && active(*iov))
100 				(*function)(*iov);
101 	}
102 }
103 
104 _cleanup()
105 {
106 	extern int fclose();
107 
108 	_fwalk(fclose);
109 }
110