1: 2: 3: 4:
5:
6:
7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
38:
39: #include <sys/param.h>
40: #include <unistd.h>
41: #include <stdio.h>
42: #include <errno.h>
43: #include <stdlib.h>
44: #include <string.h>
45: #include "local.h"
46: #include "glue.h"
47: #include "thread_private.h"
48:
49: 50:
51: #define DYN_ALLOC_FILEBUF 1
52:
53:
54: int __sdidinit;
55:
56: #define NDYNAMIC 10
57:
58: #define std(flags, file) \
59: {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
60: {(unsigned char *)(__sFext+file), 0}}
61: 62:
63:
64: struct __sfileext __sFext[3];
65: FILE __sF[3]; static const FILE sF[3] = {
66: std(__SRD, STDIN_FILENO),
67: std(__SWR, STDOUT_FILENO),
68: std(__SWR|__SNBF, STDERR_FILENO)
69: };
70:
71: #if DYN_ALLOC_FILEBUF
72: struct filebuf {
73: struct glue g;
74: FILE f;
75: struct __sfileext fext;
76: };
77: struct glue __sglue = { NULL, 3, __sF };
78: #else
79:
80: static FILE usual[FOPEN_MAX - 3];
81: static struct __sfileext usualext[FOPEN_MAX - 3];
82: static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
83: static struct glue *lastglue = &uglue;
84: struct glue __sglue = { &uglue, 3, __sF };
85: #endif
86:
87: _THREAD_PRIVATE_MUTEX(__sfp_mutex);
88:
89: #if 0
90: static struct glue *moreglue(int n)
91: {
92: struct glue *g;
93: FILE *p;
94: struct __sfileext *pext;
95: static FILE empty;
96: char *data;
97:
98: data = malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)
99: + n * sizeof(struct __sfileext));
100: if (data == NULL)
101: return (NULL);
102: g = (struct glue *)data;
103: p = (FILE *)ALIGN(data + sizeof(*g));
104: pext = (struct __sfileext *)
105: (ALIGN(data + sizeof(*g)) + n * sizeof(FILE));
106: g->next = NULL;
107: g->niobs = n;
108: g->iobs = p;
109: while (--n >= 0) {
110: *p = empty;
111: _FILEEXT_SETUP(p, pext);
112: p++;
113: pext++;
114: }
115: return (g);
116: }
117: #endif
118: 119: 120:
121: FILE *
122: __sfp(void)
123: {
124: FILE *fp;
125: int n;
126: struct glue *g;
127:
128: if (!__sdidinit)
129: __sinit();
130:
131: _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
132: for (g = &__sglue; g != NULL; g = g->next) {
133: for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
134: if (fp->_flags == 0)
135: goto found;
136: }
137:
138:
139: _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
140: #if DYN_ALLOC_FILEBUF
141: { struct filebuf *p;
142: p = (struct filebuf *)malloc(sizeof(struct filebuf));
143: if (p == NULL) return NULL;
144: _FILEEXT_SETUP(&p->f, &p->fext);
145: p->g.niobs = 1;
146: p->g.iobs = &p->f;
147: _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
148: p->g.next = __sglue.next;
149: __sglue.next = g = &p->g;
150: }
151: #else
152: if ((g = NULL) == NULL)
153: return (NULL);
154: _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
155: lastglue->next = g;
156: lastglue = g;
157: #endif
158: fp = g->iobs;
159: found:
160: fp->_flags = 1;
161: _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
162: fp->_p = NULL;
163: fp->_w = 0;
164: fp->_r = 0;
165: fp->_bf._base = NULL;
166: fp->_bf._size = 0;
167: fp->_lbfsize = 0;
168: fp->_file = -1;
169:
170: fp->_lb._base = NULL;
171: fp->_lb._size = 0;
172: _FILEEXT_INIT(fp);
173: return (fp);
174: }
175:
176: 177: 178: 179:
180: #if 0
181:
182: #define getdtablesize() sysconf(_SC_OPEN_MAX)
183:
184: void f_prealloc(void)
185: {
186: struct glue *g;
187: int n;
188:
189: n = getdtablesize() - FOPEN_MAX + 20;
190: for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)
191: ;
192: if (n > 0 && ((g = moreglue(n)) != NULL)) {
193: _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
194: lastglue->next = g;
195: lastglue = g;
196: _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
197: }
198: }
199: #endif
200: 201: 202: 203: 204: 205: 206: 207:
208: void
209: _cleanup(void)
210: {
211:
212: (void) _fwalk(__sflush);
213: }
214:
215: 216: 217:
218: void
219: __sinit(void)
220: {
221: _THREAD_PRIVATE_MUTEX(__sinit_mutex);
222:
223: _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
224: if (__sdidinit)
225: goto out;
226: #if ! DYN_ALLOC_FILEBUF
227: {
228: int i;
229: for (i = 0; i < FOPEN_MAX - 3; i++) {
230: _FILEEXT_SETUP(usual+i, usualext+i);
231: }
232: }
233: #endif
234:
235: __atexit_register_cleanup(_cleanup);
236: __sF[0] = sF[0]; __sF[1] = sF[1]; __sF[2] = sF[2]; __sdidinit = 1;
237: out:
238: _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
239: }