add strdup
[unix-history] / usr / src / lib / libc / stdio / findfp.c
CommitLineData
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 8static 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
14extern 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
20FILE _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 26extern char *calloc();
2801a079 27
d0962cc0
MK
28static char sbuf[NSTATIC];
29char *_smallbuf = sbuf;
2801a079
S
30static FILE **iobglue;
31static 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
42FILE *
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
94f_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}