xref: /csrg-svn/lib/libc/stdio/findfp.c (revision 17951)
1 /* @(#)findfp.c	1.2 (Berkeley) 02/13/85 */
2 #include <stdio.h>
3 
4 #define NSTATIC	10	/* stdin, stdout, stderr, plus slack */
5 
6 extern char *calloc();
7 
8 static FILE *dummy[NSTATIC];
9 static FILE **iov = NULL;
10 static FILE **iovend;
11 
12 FILE _iob[NSTATIC] = {
13 	{ 0, NULL, NULL, NULL, _IOREAD,		0 },	/* stdin  */
14 	{ 0, NULL, NULL, NULL, _IOWRT,		1 },	/* stdout */
15 	{ 0, NULL, NULL, NULL, _IOWRT|_IONBF,	2 },	/* stderr */
16 };
17 
18 static char smallbuf[NSTATIC];
19 static char *unbufp = NULL;
20 
21 FILE *
22 _findiop()
23 {
24 	register FILE **iovp;
25 	register FILE *fp;
26 	register int nfiles;
27 
28 	if (iov == NULL) {
29 		unbufp	= NULL;
30 		iov	= NULL;
31 		fp	= NULL;
32 
33 		nfiles = getdtablesize();
34 		if (nfiles > NSTATIC) {
35 			fp = (FILE *)calloc(nfiles - NSTATIC, sizeof *fp);
36 			if (fp != NULL) {
37 				iov = (FILE **)calloc(nfiles, sizeof *iov);
38 				if (iov != NULL)
39 					unbufp = calloc(nfiles, sizeof *unbufp);
40 			}
41 		}
42 
43 		if (unbufp != NULL) {
44 			iovend = iov + nfiles;
45 			for (iovp = iov + NSTATIC; iovp < iovend; /* void */)
46 				*iovp++ = fp++;
47 		} else {
48 			if (fp != NULL) {
49 				free((char *)fp);
50 				if (iov != NULL)
51 					free((char *)iov);
52 			}
53 
54 			iovend	= dummy + NSTATIC;
55 			iov	= dummy;
56 		}
57 
58 		iovp = iov;
59 		for (fp = _iob; fp < _iob + NSTATIC; /* void */)
60 			*iovp++ = fp++;
61 	}
62 
63 	for (iovp = iov; (*iovp)->_flag & (_IOREAD|_IOWRT|_IORW); /* void */)
64 		if (++iovp >= iovend)
65 			return (NULL);
66 
67 	return (*iovp);
68 }
69 
70 _cleanup()
71 {
72 	register FILE *_lastbuf = _iob + NSTATIC;
73 	register FILE **iovp;
74 	register FILE *iop;
75 
76 	if (iov == NULL)
77 		for (iop = _iob; iop < _lastbuf; iop++)
78 			fclose(iop);
79 	else
80 		for (iovp = iov; iovp < iovend; iovp++)
81 			fclose(*iovp);
82 }
83 
84 char *
85 _smallbuf(iop)
86 	register FILE *iop;
87 {
88 	if (unbufp == NULL)
89 		return (&smallbuf[iop - _iob]);
90 	else
91 		return (&unbufp[fileno(iop)]);
92 }
93