Commit | Line | Data |
---|---|---|
586c39b1 | 1 | /* |
78d51389 | 2 | * Copyright (c) 1983, 1985 Regents of the University of California. |
586c39b1 DF |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
2ce81398 | 7 | #if defined(LIBC_SCCS) && !defined(lint) |
40754574 | 8 | static char sccsid[] = "@(#)findfp.c 5.7 (Berkeley) %G%"; |
2ce81398 | 9 | #endif LIBC_SCCS and not lint |
586c39b1 | 10 | |
41e01b3e | 11 | #include <stdio.h> |
dc08ce09 JL |
12 | #include <errno.h> |
13 | ||
14 | extern int errno; | |
f9f3c5fb | 15 | |
2801a079 | 16 | #define active(iop) ((iop)->_flag & (_IOREAD|_IOWRT|_IORW)) |
f9f3c5fb | 17 | |
78d51389 | 18 | #define NSTATIC 20 /* stdin + stdout + stderr + the usual */ |
f9f3c5fb S |
19 | |
20 | FILE _iob[NSTATIC] = { | |
2801a079 S |
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 */ | |
f9f3c5fb S |
24 | }; |
25 | ||
7fb21e1a | 26 | extern char *calloc(); |
2801a079 | 27 | |
d0962cc0 MK |
28 | static char sbuf[NSTATIC]; |
29 | char *_smallbuf = sbuf; | |
2801a079 S |
30 | static FILE **iobglue; |
31 | static FILE **endglue; | |
41e01b3e | 32 | |
d0962cc0 MK |
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 | */ | |
f9f3c5fb S |
42 | FILE * |
43 | _findiop() | |
44 | { | |
d0962cc0 | 45 | register FILE **iov, *iop; |
f9f3c5fb | 46 | register FILE *fp; |
41e01b3e | 47 | |
d0962cc0 MK |
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 | } | |
f9f3c5fb S |
57 | } |
58 | ||
2801a079 S |
59 | iov = iobglue; |
60 | while (*iov != NULL && active(*iov)) | |
dc08ce09 JL |
61 | if (++iov >= endglue) { |
62 | errno = EMFILE; | |
f9f3c5fb | 63 | return (NULL); |
dc08ce09 | 64 | } |
f9f3c5fb | 65 | |
2801a079 | 66 | if (*iov == NULL) |
7fb21e1a | 67 | *iov = (FILE *)calloc(1, sizeof **iov); |
2801a079 S |
68 | |
69 | return (*iov); | |
f9f3c5fb S |
70 | } |
71 | ||
d0962cc0 | 72 | _f_morefiles() |
f9f3c5fb | 73 | { |
2801a079 S |
74 | register FILE **iov; |
75 | register FILE *fp; | |
d0962cc0 MK |
76 | register char *cp; |
77 | int nfiles; | |
2801a079 | 78 | |
78d51389 MK |
79 | nfiles = getdtablesize(); |
80 | ||
7fb21e1a | 81 | iobglue = (FILE **)calloc(nfiles, sizeof *iobglue); |
78d51389 MK |
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++; | |
d0962cc0 | 89 | |
7fb21e1a | 90 | _smallbuf = calloc(nfiles, sizeof(*_smallbuf)); |
78d51389 MK |
91 | return (1); |
92 | } | |
93 | ||
94 | f_prealloc() | |
95 | { | |
96 | register FILE **iov; | |
97 | register FILE *fp; | |
98 | ||
d0962cc0 | 99 | if (iobglue == NULL && _f_morefiles() == 0) |
2801a079 S |
100 | return; |
101 | ||
78d51389 | 102 | for (iov = iobglue; iov < endglue; iov++) |
7fb21e1a MK |
103 | if (*iov == NULL) |
104 | *iov = (FILE *)calloc(1, sizeof **iov); | |
78d51389 MK |
105 | } |
106 | ||
107 | _fwalk(function) | |
108 | register int (*function)(); | |
109 | { | |
110 | register FILE **iov; | |
111 | register FILE *fp; | |
112 | ||
2801a079 | 113 | if (iobglue == NULL) { |
78d51389 | 114 | for (fp = _iob; fp < &_iob[NSTATIC]; fp++) |
2801a079 S |
115 | if (active(fp)) |
116 | (*function)(fp); | |
117 | } else { | |
118 | for (iov = iobglue; iov < endglue; iov++) | |
78d51389 | 119 | if (*iov && active(*iov)) |
2801a079 S |
120 | (*function)(*iov); |
121 | } | |
f9f3c5fb | 122 | } |