allow pushback even in unbuffered streams
[unix-history] / usr / src / lib / libc / stdio / findfp.c
CommitLineData
41e01b3e
S
1/* @(#)findfp.c 1.2 (Berkeley) %G% */
2#include <stdio.h>
f9f3c5fb 3
41e01b3e 4#define NSTATIC 10 /* stdin, stdout, stderr, plus slack */
f9f3c5fb
S
5
6extern char *calloc();
7
f9f3c5fb 8static FILE *dummy[NSTATIC];
41e01b3e
S
9static FILE **iov = NULL;
10static FILE **iovend;
f9f3c5fb
S
11
12FILE _iob[NSTATIC] = {
41e01b3e
S
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 */
f9f3c5fb
S
16};
17
41e01b3e
S
18static char smallbuf[NSTATIC];
19static char *unbufp = NULL;
20
f9f3c5fb
S
21FILE *
22_findiop()
23{
24 register FILE **iovp;
25 register FILE *fp;
26 register int nfiles;
f9f3c5fb
S
27
28 if (iov == NULL) {
41e01b3e
S
29 unbufp = NULL;
30 iov = NULL;
31 fp = NULL;
32
f9f3c5fb 33 nfiles = getdtablesize();
41e01b3e
S
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 }
f9f3c5fb 42
41e01b3e
S
43 if (unbufp != NULL) {
44 iovend = iov + nfiles;
f9f3c5fb
S
45 for (iovp = iov + NSTATIC; iovp < iovend; /* void */)
46 *iovp++ = fp++;
41e01b3e
S
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;
f9f3c5fb
S
56 }
57
41e01b3e
S
58 iovp = iov;
59 for (fp = _iob; fp < _iob + NSTATIC; /* void */)
60 *iovp++ = fp++;
f9f3c5fb
S
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}
41e01b3e
S
83
84char *
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}