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: #if defined(LIBC_SCCS) && !defined(lint)
8: static char sccsid[] = "@(#)findiop.c 5.6 (Berkeley) 3/9/86";
9: #endif LIBC_SCCS and 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 char sbuf[NSTATIC];
29: char *_smallbuf = sbuf;
30: static FILE **iobglue;
31: static FILE **endglue;
32:
33: /*
34: * Find a free FILE for fopen et al.
35: * We have a fixed static array of entries, and in addition
36: * may allocate additional entries dynamically, up to the kernel
37: * limit on the number of open files.
38: * At first just check for a free slot in the fixed static array.
39: * If none are available, then we allocate a structure to glue together
40: * the old and new FILE entries, which are then no longer contiguous.
41: */
42: FILE *
43: _findiop()
44: {
45: register FILE **iov, *iop;
46: register FILE *fp;
47:
48: if (iobglue == 0) {
49: for (iop = _iob; iop < _iob + NSTATIC; iop++)
50: if (!active(iop))
51: return (iop);
52:
53: if (_f_morefiles() == 0) {
54: errno = ENOMEM;
55: return (NULL);
56: }
57: }
58:
59: iov = iobglue;
60: while (*iov != NULL && active(*iov))
61: if (++iov >= endglue) {
62: errno = EMFILE;
63: return (NULL);
64: }
65:
66: if (*iov == NULL)
67: *iov = (FILE *)calloc(1, sizeof **iov);
68:
69: return (*iov);
70: }
71:
72: _f_morefiles()
73: {
74: register FILE **iov;
75: register FILE *fp;
76: register char *cp;
77: int nfiles;
78:
79: nfiles = getdtablesize();
80:
81: iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
82: if (iobglue == NULL)
83: return (0);
84:
85: endglue = iobglue + nfiles;
86:
87: for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */)
88: *iov++ = fp++;
89:
90: _smallbuf = calloc(nfiles, sizeof(*_smallbuf));
91: return (1);
92: }
93:
94: f_prealloc()
95: {
96: register FILE **iov;
97: register FILE *fp;
98:
99: if (iobglue == NULL && _f_morefiles() == 0)
100: return;
101:
102: for (iov = iobglue; iov < endglue; iov++)
103: if (*iov == NULL)
104: *iov = (FILE *)calloc(1, sizeof **iov);
105: }
106:
107: _fwalk(function)
108: register int (*function)();
109: {
110: register FILE **iov;
111: register FILE *fp;
112:
113: if (iobglue == NULL) {
114: for (fp = _iob; fp < &_iob[NSTATIC]; fp++)
115: if (active(fp))
116: (*function)(fp);
117: } else {
118: for (iov = iobglue; iov < endglue; iov++)
119: if (*iov && active(*iov))
120: (*function)(*iov);
121: }
122: }
123:
124: _cleanup()
125: {
126: extern int fclose();
127:
128: _fwalk(fclose);
129: }
Defined functions
Defined variables
sbuf
defined in line
28; used 1 times
sccsid
defined in line
8;
never used
Defined macros