]>
Commit | Line | Data |
---|---|---|
8a0efa53 CF |
1 | /* This header file provides the reentrancy. */ |
2 | ||
3 | /* WARNING: All identifiers here must begin with an underscore. This file is | |
4 | included by stdio.h and others and we therefore must only use identifiers | |
5 | in the namespace allotted to us. */ | |
6 | ||
7 | #ifndef _SYS_REENT_H_ | |
8 | #ifdef __cplusplus | |
9 | extern "C" { | |
10 | #endif | |
11 | #define _SYS_REENT_H_ | |
12 | ||
13 | #include <_ansi.h> | |
9e2a4ef8 | 14 | #include <sys/_types.h> |
8a0efa53 CF |
15 | |
16 | #ifndef __Long | |
17 | #if __LONG_MAX__ == 2147483647L | |
18 | #define __Long long | |
19 | typedef unsigned __Long __ULong; | |
20 | #elif __INT_MAX__ == 2147483647 | |
21 | #define __Long int | |
22 | typedef unsigned __Long __ULong; | |
23 | #endif | |
24 | #endif | |
25 | ||
dee51391 | 26 | #if !defined( __Long) |
a70486d7 | 27 | #include <sys/types.h> |
dee51391 JJ |
28 | #endif |
29 | ||
30 | #ifndef __Long | |
8a0efa53 CF |
31 | #define __Long __int32_t |
32 | typedef __uint32_t __ULong; | |
33 | #endif | |
34 | ||
8195aff7 MG |
35 | /* |
36 | * If _REENT_SMALL is defined, we make struct _reent as small as possible, | |
37 | * by having nearly everything possible allocated at first use. | |
38 | */ | |
39 | ||
8a0efa53 CF |
40 | struct _Bigint |
41 | { | |
42 | struct _Bigint *_next; | |
43 | int _k, _maxwds, _sign, _wds; | |
44 | __ULong _x[1]; | |
45 | }; | |
46 | ||
9e2a4ef8 JJ |
47 | /* needed by reentrant structure */ |
48 | struct __tm | |
49 | { | |
50 | int __tm_sec; | |
51 | int __tm_min; | |
52 | int __tm_hour; | |
53 | int __tm_mday; | |
54 | int __tm_mon; | |
55 | int __tm_year; | |
56 | int __tm_wday; | |
57 | int __tm_yday; | |
58 | int __tm_isdst; | |
59 | }; | |
60 | ||
8a0efa53 | 61 | /* |
8195aff7 | 62 | * atexit() support. For _REENT_SMALL, we limit to 32 max. |
8a0efa53 CF |
63 | */ |
64 | ||
65 | #define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */ | |
66 | ||
75d7d177 NC |
67 | struct _on_exit_args { |
68 | void * _fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */ | |
69 | __ULong _fntypes; /* type of exit routine - | |
70 | Must have at least _ATEXIT_SIZE bits */ | |
71 | }; | |
72 | ||
73 | #ifdef _REENT_SMALL | |
8a0efa53 | 74 | struct _atexit { |
8a0efa53 CF |
75 | int _ind; /* next index in this table */ |
76 | void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */ | |
75d7d177 | 77 | struct _on_exit_args * _on_exit_args_ptr; |
8a0efa53 | 78 | }; |
8195aff7 MG |
79 | #else |
80 | struct _atexit { | |
75d7d177 | 81 | struct _atexit *_next; /* next in list */ |
8195aff7 MG |
82 | int _ind; /* next index in this table */ |
83 | void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */ | |
75d7d177 | 84 | struct _on_exit_args _on_exit_args; |
8195aff7 MG |
85 | }; |
86 | #endif | |
8a0efa53 CF |
87 | |
88 | /* | |
89 | * Stdio buffers. | |
90 | * | |
dee51391 | 91 | * This and __FILE are defined here because we need them for struct _reent, |
8a0efa53 CF |
92 | * but we don't want stdio.h included when stdlib.h is. |
93 | */ | |
94 | ||
95 | struct __sbuf { | |
96 | unsigned char *_base; | |
97 | int _size; | |
98 | }; | |
99 | ||
100 | /* | |
101 | * We need fpos_t for the following, but it doesn't have a leading "_", | |
102 | * so we use _fpos_t instead. | |
103 | */ | |
104 | ||
105 | typedef long _fpos_t; /* XXX must match off_t in <sys/types.h> */ | |
106 | /* (and must be `long' for now) */ | |
107 | ||
dee51391 JJ |
108 | #ifdef __LARGE64_FILES |
109 | typedef _off64_t _fpos64_t; | |
110 | #endif | |
111 | ||
8a0efa53 CF |
112 | /* |
113 | * Stdio state variables. | |
114 | * | |
115 | * The following always hold: | |
116 | * | |
117 | * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), | |
118 | * _lbfsize is -_bf._size, else _lbfsize is 0 | |
119 | * if _flags&__SRD, _w is 0 | |
120 | * if _flags&__SWR, _r is 0 | |
121 | * | |
122 | * This ensures that the getc and putc macros (or inline functions) never | |
123 | * try to write or read from a file that is in `read' or `write' mode. | |
124 | * (Moreover, they can, and do, automatically switch from read mode to | |
125 | * write mode, and back, on "r+" and "w+" files.) | |
126 | * | |
127 | * _lbfsize is used only to make the inline line-buffered output stream | |
128 | * code as compact as possible. | |
129 | * | |
130 | * _ub, _up, and _ur are used when ungetc() pushes back more characters | |
131 | * than fit in the current _bf, or when ungetc() pushes back a character | |
132 | * that does not match the previous one in _bf. When this happens, | |
133 | * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff | |
134 | * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. | |
135 | */ | |
136 | ||
8195aff7 MG |
137 | #ifdef _REENT_SMALL |
138 | /* | |
139 | * struct __sFILE_fake is the start of a struct __sFILE, with only the | |
140 | * minimal fields allocated. In __sinit() we really allocate the 3 | |
141 | * standard streams, etc., and point away from this fake. | |
142 | */ | |
143 | struct __sFILE_fake { | |
144 | unsigned char *_p; /* current position in (some) buffer */ | |
145 | int _r; /* read space left for getc() */ | |
146 | int _w; /* write space left for putc() */ | |
147 | short _flags; /* flags, below; this FILE is free if 0 */ | |
148 | short _file; /* fileno, if Unix descriptor, else -1 */ | |
149 | struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ | |
150 | int _lbfsize; /* 0 or -_bf._size, for inline putc */ | |
151 | ||
152 | struct _reent *_data; | |
153 | }; | |
154 | /* CHECK_INIT() comes from stdio/local.h; be sure to include that. */ | |
155 | # define _REENT_SMALL_CHECK_INIT(fp) CHECK_INIT(fp) | |
156 | #else | |
157 | # define _REENT_SMALL_CHECK_INIT(fp) /* nothing */ | |
158 | #endif | |
159 | ||
8a0efa53 CF |
160 | struct __sFILE { |
161 | unsigned char *_p; /* current position in (some) buffer */ | |
162 | int _r; /* read space left for getc() */ | |
163 | int _w; /* write space left for putc() */ | |
164 | short _flags; /* flags, below; this FILE is free if 0 */ | |
165 | short _file; /* fileno, if Unix descriptor, else -1 */ | |
166 | struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ | |
167 | int _lbfsize; /* 0 or -_bf._size, for inline putc */ | |
168 | ||
8195aff7 MG |
169 | #ifdef _REENT_SMALL |
170 | struct _reent *_data; | |
171 | #endif | |
172 | ||
8a0efa53 CF |
173 | /* operations */ |
174 | _PTR _cookie; /* cookie passed to io functions */ | |
175 | ||
cfc05d96 JJ |
176 | _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); |
177 | _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, | |
178 | int _n)); | |
8a0efa53 CF |
179 | _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); |
180 | int _EXFUN((*_close),(_PTR _cookie)); | |
181 | ||
182 | /* separate buffer for long sequences of ungetc() */ | |
183 | struct __sbuf _ub; /* ungetc buffer */ | |
184 | unsigned char *_up; /* saved _p when _p is doing ungetc data */ | |
185 | int _ur; /* saved _r when _r is counting ungetc data */ | |
186 | ||
187 | /* tricks to meet minimum requirements even when malloc() fails */ | |
188 | unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ | |
189 | unsigned char _nbuf[1]; /* guarantee a getc() buffer */ | |
190 | ||
191 | /* separate buffer for fgetline() when line crosses buffer boundary */ | |
192 | struct __sbuf _lb; /* buffer for fgetline() */ | |
193 | ||
194 | /* Unix stdio files get aligned to block boundaries on fseek() */ | |
195 | int _blksize; /* stat.st_blksize (may be != _bf._size) */ | |
196 | int _offset; /* current lseek offset */ | |
197 | ||
8195aff7 | 198 | #ifndef _REENT_SMALL |
3db40db7 JJ |
199 | struct _reent *_data; /* Here for binary compatibility? Remove? */ |
200 | #endif | |
201 | ||
202 | #ifndef __SINGLE_THREAD__ | |
203 | _flock_t _lock; /* for thread-safety locking */ | |
8195aff7 | 204 | #endif |
8a0efa53 CF |
205 | }; |
206 | ||
dee51391 JJ |
207 | #ifdef __LARGE64_FILES |
208 | struct __sFILE64 { | |
209 | unsigned char *_p; /* current position in (some) buffer */ | |
210 | int _r; /* read space left for getc() */ | |
211 | int _w; /* write space left for putc() */ | |
212 | short _flags; /* flags, below; this FILE is free if 0 */ | |
213 | short _file; /* fileno, if Unix descriptor, else -1 */ | |
214 | struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ | |
215 | int _lbfsize; /* 0 or -_bf._size, for inline putc */ | |
216 | ||
217 | struct _reent *_data; | |
218 | ||
219 | /* operations */ | |
220 | _PTR _cookie; /* cookie passed to io functions */ | |
221 | ||
222 | _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); | |
223 | _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, | |
224 | int _n)); | |
225 | _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); | |
226 | int _EXFUN((*_close),(_PTR _cookie)); | |
227 | ||
228 | /* separate buffer for long sequences of ungetc() */ | |
229 | struct __sbuf _ub; /* ungetc buffer */ | |
230 | unsigned char *_up; /* saved _p when _p is doing ungetc data */ | |
231 | int _ur; /* saved _r when _r is counting ungetc data */ | |
232 | ||
233 | /* tricks to meet minimum requirements even when malloc() fails */ | |
234 | unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ | |
235 | unsigned char _nbuf[1]; /* guarantee a getc() buffer */ | |
236 | ||
237 | /* separate buffer for fgetline() when line crosses buffer boundary */ | |
238 | struct __sbuf _lb; /* buffer for fgetline() */ | |
239 | ||
240 | /* Unix stdio files get aligned to block boundaries on fseek() */ | |
241 | int _blksize; /* stat.st_blksize (may be != _bf._size) */ | |
242 | int _flags2; /* for future use */ | |
3db40db7 | 243 | |
dee51391 JJ |
244 | _off64_t _offset; /* current lseek offset */ |
245 | _fpos64_t _EXFUN((*_seek64),(_PTR _cookie, _fpos64_t _offset, int _whence)); | |
3db40db7 JJ |
246 | |
247 | #ifndef __SINGLE_THREAD__ | |
248 | _flock_t _lock; /* for thread-safety locking */ | |
249 | #endif | |
dee51391 JJ |
250 | }; |
251 | typedef struct __sFILE64 __FILE; | |
252 | #else | |
253 | typedef struct __sFILE __FILE; | |
254 | #endif /* __LARGE64_FILES */ | |
255 | ||
256 | struct _glue | |
257 | { | |
258 | struct _glue *_next; | |
259 | int _niobs; | |
260 | __FILE *_iobs; | |
261 | }; | |
262 | ||
ab4745dc JJ |
263 | /* |
264 | * rand48 family support | |
265 | * | |
266 | * Copyright (c) 1993 Martin Birgmeier | |
267 | * All rights reserved. | |
268 | * | |
269 | * You may redistribute unmodified or modified versions of this source | |
270 | * code provided that the above copyright notice and this and the | |
271 | * following conditions are retained. | |
272 | * | |
273 | * This software is provided ``as is'', and comes with no warranties | |
274 | * of any kind. I shall in no event be liable for anything that happens | |
275 | * to anyone/anything when using this software. | |
276 | */ | |
277 | #define _RAND48_SEED_0 (0x330e) | |
278 | #define _RAND48_SEED_1 (0xabcd) | |
279 | #define _RAND48_SEED_2 (0x1234) | |
280 | #define _RAND48_MULT_0 (0xe66d) | |
281 | #define _RAND48_MULT_1 (0xdeec) | |
282 | #define _RAND48_MULT_2 (0x0005) | |
283 | #define _RAND48_ADD (0x000b) | |
284 | struct _rand48 { | |
285 | unsigned short _seed[3]; | |
286 | unsigned short _mult[3]; | |
287 | unsigned short _add; | |
8195aff7 MG |
288 | #ifdef _REENT_SMALL |
289 | /* Put this in here as well, for good luck. */ | |
290 | __extension__ unsigned long long _rand_next; | |
291 | #endif | |
ab4745dc JJ |
292 | }; |
293 | ||
8195aff7 MG |
294 | /* How big the some arrays are. */ |
295 | #define _REENT_EMERGENCY_SIZE 25 | |
296 | #define _REENT_ASCTIME_SIZE 26 | |
39e65e01 | 297 | #define _REENT_SIGNAL_SIZE 24 |
8195aff7 | 298 | |
8a0efa53 CF |
299 | /* |
300 | * struct _reent | |
301 | * | |
302 | * This structure contains *all* globals needed by the library. | |
303 | * It's raison d'etre is to facilitate threads by making all library routines | |
304 | * reentrant. IE: All state information is contained here. | |
305 | */ | |
306 | ||
8195aff7 MG |
307 | #ifdef _REENT_SMALL |
308 | ||
309 | struct _mprec | |
310 | { | |
311 | /* used by mprec routines */ | |
312 | struct _Bigint *_result; | |
313 | int _result_k; | |
314 | struct _Bigint *_p5s; | |
315 | struct _Bigint **_freelist; | |
316 | }; | |
317 | ||
d4dca0e4 JJ |
318 | |
319 | struct _misc_reent | |
320 | { | |
321 | /* miscellaneous reentrant data */ | |
322 | char *_strtok_last; | |
8d9112f2 TF |
323 | _mbstate_t _mblen_state; |
324 | _mbstate_t _wctomb_state; | |
325 | _mbstate_t _mbtowc_state; | |
c33c3635 | 326 | char _l64a_buf[8]; |
35728d4f | 327 | int _getdate_err; |
9c64d2a7 JJ |
328 | _mbstate_t _mbrlen_state; |
329 | _mbstate_t _mbrtowc_state; | |
330 | _mbstate_t _mbsrtowcs_state; | |
331 | _mbstate_t _wcrtomb_state; | |
332 | _mbstate_t _wcsrtombs_state; | |
d4dca0e4 JJ |
333 | }; |
334 | ||
8195aff7 MG |
335 | /* This version of _reent is layed our with "int"s in pairs, to help |
336 | * ports with 16-bit int's but 32-bit pointers, align nicely. */ | |
337 | struct _reent | |
338 | { | |
339 | ||
340 | /* FILE is a big struct and may change over time. To try to achieve binary | |
341 | compatibility with future versions, put stdin,stdout,stderr here. | |
342 | These are pointers into member __sf defined below. */ | |
dee51391 | 343 | __FILE *_stdin, *_stdout, *_stderr; /* XXX */ |
8195aff7 MG |
344 | |
345 | int _errno; /* local copy of errno */ | |
346 | ||
347 | int _inc; /* used by tmpnam */ | |
348 | ||
349 | char *_emergency; | |
350 | ||
351 | int __sdidinit; /* 1 means stdio has been init'd */ | |
352 | ||
353 | int _current_category; /* used by setlocale */ | |
354 | _CONST char *_current_locale; | |
355 | ||
356 | struct _mprec *_mp; | |
357 | ||
358 | void _EXFUN((*__cleanup),(struct _reent *)); | |
359 | ||
360 | int _gamma_signgam; | |
361 | ||
362 | /* used by some fp conversion routines */ | |
363 | int _cvtlen; /* should be size_t */ | |
364 | char *_cvtbuf; | |
365 | ||
366 | struct _rand48 *_r48; | |
367 | struct __tm *_localtime_buf; | |
368 | char *_asctime_buf; | |
369 | ||
370 | /* signal info */ | |
371 | void (**(_sig_func))(int); | |
372 | ||
373 | /* atexit stuff */ | |
374 | struct _atexit _atexit; | |
375 | ||
376 | struct _glue __sglue; /* root of glue chain */ | |
dee51391 | 377 | __FILE *__sf; /* file descriptors */ |
8195aff7 | 378 | struct __sFILE_fake __sf_fake; /* fake initial stdin/out/err */ |
d4dca0e4 | 379 | struct _misc_reent *_misc; /* strtok, multibyte states */ |
39e65e01 | 380 | char *_signal_buf; /* strsignal */ |
8195aff7 MG |
381 | }; |
382 | ||
383 | #define _REENT_INIT(var) \ | |
dee51391 JJ |
384 | { (__FILE *)&var.__sf_fake, (__FILE *)&var.__sf_fake, \ |
385 | (__FILE *)&var.__sf_fake, 0, 0, _NULL, 0, 0, \ | |
8195aff7 | 386 | "C", _NULL, _NULL, 0, 0, _NULL, _NULL, _NULL, _NULL, _NULL, \ |
39e65e01 | 387 | { 0, _NULL, _NULL, 0 }, { _NULL, 0, _NULL }, _NULL, 0, _NULL, _NULL } |
d4dca0e4 JJ |
388 | |
389 | #define _REENT_INIT_PTR(var) \ | |
dee51391 JJ |
390 | { var->_stdin = (__FILE *)&var->__sf_fake; \ |
391 | var->_stdout = (__FILE *)&var->__sf_fake; \ | |
392 | var->_stderr = (__FILE *)&var->__sf_fake; \ | |
d4dca0e4 JJ |
393 | var->_errno = 0; \ |
394 | var->_inc = 0; \ | |
395 | var->_emergency = _NULL; \ | |
396 | var->__sdidinit = 0; \ | |
397 | var->_current_category = 0; \ | |
398 | var->_current_locale = "C"; \ | |
399 | var->_mp = _NULL; \ | |
400 | var->__cleanup = _NULL; \ | |
401 | var->_gamma_signgam = 0; \ | |
402 | var->_cvtlen = 0; \ | |
403 | var->_cvtbuf = _NULL; \ | |
404 | var->_r48 = _NULL; \ | |
405 | var->_localtime_buf = _NULL; \ | |
406 | var->_asctime_buf = _NULL; \ | |
4608280d | 407 | var->_sig_func = _NULL; \ |
d4dca0e4 | 408 | var->_atexit._ind = 0; \ |
dc824ef7 | 409 | var->_atexit._fns[0] = _NULL; \ |
8266e478 | 410 | var->_atexit._on_exit_args = _NULL; \ |
d4dca0e4 JJ |
411 | var->__sglue._next = _NULL; \ |
412 | var->__sglue._niobs = 0; \ | |
413 | var->__sglue._iobs = _NULL; \ | |
414 | var->__sf = 0; \ | |
415 | var->_misc = _NULL; \ | |
39e65e01 | 416 | var->_signal_buf = _NULL; \ |
35728d4f | 417 | var->_getdate_err = 0; \ |
dc824ef7 JJ |
418 | var->__sf_fake._p = _NULL; \ |
419 | var->__sf_fake._r = 0; \ | |
420 | var->__sf_fake._w = 0; \ | |
421 | var->__sf_fake._flags = 0; \ | |
422 | var->__sf_fake._file = 0; \ | |
423 | var->__sf_fake._lbfsize = 0; \ | |
424 | var->__sf_fake._data = _NULL; \ | |
d4dca0e4 | 425 | } |
8195aff7 MG |
426 | |
427 | /* Only built the assert() calls if we are built with debugging. */ | |
428 | #if DEBUG | |
429 | #include <assert.h> | |
430 | #else | |
431 | #define assert(x) ((void)0) | |
432 | #endif | |
433 | ||
434 | /* Generic _REENT check macro. */ | |
435 | #define _REENT_CHECK(var, what, type, size, init) do { \ | |
436 | struct _reent *_r = (var); \ | |
437 | if (_r->what == NULL) { \ | |
438 | _r->what = (type)malloc(size); \ | |
439 | assert(_r->what); \ | |
440 | init; \ | |
441 | } \ | |
442 | } while (0) | |
443 | ||
444 | #define _REENT_CHECK_TM(var) \ | |
445 | _REENT_CHECK(var, _localtime_buf, struct __tm *, sizeof *((var)->_localtime_buf), \ | |
446 | /* nothing */) | |
447 | ||
448 | #define _REENT_CHECK_ASCTIME_BUF(var) \ | |
449 | _REENT_CHECK(var, _asctime_buf, char *, _REENT_ASCTIME_SIZE, \ | |
450 | memset((var)->_asctime_buf, 0, _REENT_ASCTIME_SIZE)) | |
451 | ||
452 | /* Handle the dynamically allocated rand48 structure. */ | |
453 | #define _REENT_INIT_RAND48(var) do { \ | |
454 | struct _reent *_r = (var); \ | |
455 | _r->_r48->_seed[0] = _RAND48_SEED_0; \ | |
456 | _r->_r48->_seed[1] = _RAND48_SEED_1; \ | |
457 | _r->_r48->_seed[2] = _RAND48_SEED_2; \ | |
458 | _r->_r48->_mult[0] = _RAND48_MULT_0; \ | |
459 | _r->_r48->_mult[1] = _RAND48_MULT_1; \ | |
460 | _r->_r48->_mult[2] = _RAND48_MULT_2; \ | |
461 | _r->_r48->_add = _RAND48_ADD; \ | |
462 | } while (0) | |
463 | #define _REENT_CHECK_RAND48(var) \ | |
464 | _REENT_CHECK(var, _r48, struct _rand48 *, sizeof *((var)->_r48), _REENT_INIT_RAND48((var))) | |
465 | ||
466 | #define _REENT_INIT_MP(var) do { \ | |
467 | struct _reent *_r = (var); \ | |
468 | _r->_mp->_result_k = 0; \ | |
469 | _r->_mp->_result = _r->_mp->_p5s = _NULL; \ | |
470 | _r->_mp->_freelist = _NULL; \ | |
471 | } while (0) | |
472 | #define _REENT_CHECK_MP(var) \ | |
473 | _REENT_CHECK(var, _mp, struct _mprec *, sizeof *((var)->_mp), _REENT_INIT_MP(var)) | |
474 | ||
475 | #define _REENT_CHECK_EMERGENCY(var) \ | |
82b3ac56 | 476 | _REENT_CHECK(var, _emergency, char *, _REENT_EMERGENCY_SIZE, /* nothing */) |
8195aff7 | 477 | |
d4dca0e4 JJ |
478 | #define _REENT_INIT_MISC(var) do { \ |
479 | struct _reent *_r = (var); \ | |
480 | _r->_misc->_strtok_last = _NULL; \ | |
8d9112f2 TF |
481 | _r->_misc->_mblen_state.__count = 0; \ |
482 | _r->_misc->_mblen_state.__value.__wch = 0; \ | |
483 | _r->_misc->_wctomb_state.__count = 0; \ | |
484 | _r->_misc->_wctomb_state.__value.__wch = 0; \ | |
485 | _r->_misc->_mbtowc_state.__count = 0; \ | |
486 | _r->_misc->_mbtowc_state.__value.__wch = 0; \ | |
9c64d2a7 JJ |
487 | _r->_misc->_mbrlen_state.__count = 0; \ |
488 | _r->_misc->_mbrlen_state.__value.__wch = 0; \ | |
489 | _r->_misc->_mbrtowc_state.__count = 0; \ | |
490 | _r->_misc->_mbrtowc_state.__value.__wch = 0; \ | |
491 | _r->_misc->_mbsrtowcs_state.__count = 0; \ | |
492 | _r->_misc->_mbsrtowcs_state.__value.__wch = 0; \ | |
493 | _r->_misc->_wcrtomb_state.__count = 0; \ | |
494 | _r->_misc->_wcrtomb_state.__value.__wch = 0; \ | |
495 | _r->_misc->_wcsrtombs_state.__count = 0; \ | |
496 | _r->_misc->_wcsrtombs_state.__value.__wch = 0; \ | |
c33c3635 | 497 | _r->_misc->_l64a_buf[0] = '\0'; \ |
35728d4f | 498 | _r->_misc->_getdate_err = 0; \ |
d4dca0e4 JJ |
499 | } while (0) |
500 | #define _REENT_CHECK_MISC(var) \ | |
501 | _REENT_CHECK(var, _misc, struct _misc_reent *, sizeof *((var)->_misc), _REENT_INIT_MISC(var)) | |
502 | ||
39e65e01 JJ |
503 | #define _REENT_CHECK_SIGNAL_BUF(var) \ |
504 | _REENT_CHECK(var, _signal_buf, char *, _REENT_SIGNAL_SIZE, /* nothing */) | |
505 | ||
8195aff7 MG |
506 | #define _REENT_SIGNGAM(ptr) ((ptr)->_gamma_signgam) |
507 | #define _REENT_RAND_NEXT(ptr) ((ptr)->_r48->_rand_next) | |
508 | #define _REENT_RAND48_SEED(ptr) ((ptr)->_r48->_seed) | |
509 | #define _REENT_RAND48_MULT(ptr) ((ptr)->_r48->_mult) | |
510 | #define _REENT_RAND48_ADD(ptr) ((ptr)->_r48->_add) | |
511 | #define _REENT_MP_RESULT(ptr) ((ptr)->_mp->_result) | |
512 | #define _REENT_MP_RESULT_K(ptr) ((ptr)->_mp->_result_k) | |
513 | #define _REENT_MP_P5S(ptr) ((ptr)->_mp->_p5s) | |
514 | #define _REENT_MP_FREELIST(ptr) ((ptr)->_mp->_freelist) | |
515 | #define _REENT_ASCTIME_BUF(ptr) ((ptr)->_asctime_buf) | |
516 | #define _REENT_TM(ptr) ((ptr)->_localtime_buf) | |
517 | #define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) | |
d4dca0e4 JJ |
518 | #define _REENT_STRTOK_LAST(ptr) ((ptr)->_misc->_strtok_last) |
519 | #define _REENT_MBLEN_STATE(ptr) ((ptr)->_misc->_mblen_state) | |
520 | #define _REENT_MBTOWC_STATE(ptr)((ptr)->_misc->_mbtowc_state) | |
521 | #define _REENT_WCTOMB_STATE(ptr)((ptr)->_misc->_wctomb_state) | |
9c64d2a7 JJ |
522 | #define _REENT_MBRLEN_STATE(ptr) ((ptr)->_misc->_mbrlen_state) |
523 | #define _REENT_MBRTOWC_STATE(ptr) ((ptr)->_misc->_mbrtowc_state) | |
524 | #define _REENT_MBSRTOWCS_STATE(ptr) ((ptr)->_misc->_mbsrtowcs_state) | |
525 | #define _REENT_WCRTOMB_STATE(ptr) ((ptr)->_misc->_wcrtomb_state) | |
526 | #define _REENT_WCSRTOMBS_STATE(ptr) ((ptr)->_misc->_wcsrtombs_state) | |
c33c3635 | 527 | #define _REENT_L64A_BUF(ptr) ((ptr)->_misc->_l64a_buf) |
35728d4f | 528 | #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_misc->_getdate_err)) |
39e65e01 | 529 | #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_signal_buf) |
8195aff7 MG |
530 | |
531 | #else /* !_REENT_SMALL */ | |
532 | ||
8a0efa53 CF |
533 | struct _reent |
534 | { | |
8195aff7 | 535 | int _errno; /* local copy of errno */ |
8a0efa53 CF |
536 | |
537 | /* FILE is a big struct and may change over time. To try to achieve binary | |
538 | compatibility with future versions, put stdin,stdout,stderr here. | |
539 | These are pointers into member __sf defined below. */ | |
dee51391 | 540 | __FILE *_stdin, *_stdout, *_stderr; |
8a0efa53 CF |
541 | |
542 | int _inc; /* used by tmpnam */ | |
8195aff7 | 543 | char _emergency[_REENT_EMERGENCY_SIZE]; |
8a0efa53 CF |
544 | |
545 | int _current_category; /* used by setlocale */ | |
546 | _CONST char *_current_locale; | |
547 | ||
548 | int __sdidinit; /* 1 means stdio has been init'd */ | |
549 | ||
550 | void _EXFUN((*__cleanup),(struct _reent *)); | |
551 | ||
552 | /* used by mprec routines */ | |
553 | struct _Bigint *_result; | |
554 | int _result_k; | |
555 | struct _Bigint *_p5s; | |
556 | struct _Bigint **_freelist; | |
557 | ||
558 | /* used by some fp conversion routines */ | |
559 | int _cvtlen; /* should be size_t */ | |
560 | char *_cvtbuf; | |
561 | ||
562 | union | |
563 | { | |
564 | struct | |
565 | { | |
46a43a99 | 566 | unsigned int _unused_rand; |
d4dca0e4 | 567 | char * _strtok_last; |
39e65e01 | 568 | char _asctime_buf[_REENT_ASCTIME_SIZE]; |
9e2a4ef8 | 569 | struct __tm _localtime_buf; |
8a0efa53 | 570 | int _gamma_signgam; |
a704d94a | 571 | __extension__ unsigned long long _rand_next; |
ab4745dc | 572 | struct _rand48 _r48; |
8d9112f2 TF |
573 | _mbstate_t _mblen_state; |
574 | _mbstate_t _mbtowc_state; | |
575 | _mbstate_t _wctomb_state; | |
c33c3635 | 576 | char _l64a_buf[8]; |
39e65e01 | 577 | char _signal_buf[_REENT_SIGNAL_SIZE]; |
35728d4f | 578 | int _getdate_err; |
9c64d2a7 JJ |
579 | _mbstate_t _mbrlen_state; |
580 | _mbstate_t _mbrtowc_state; | |
581 | _mbstate_t _mbsrtowcs_state; | |
582 | _mbstate_t _wcrtomb_state; | |
583 | _mbstate_t _wcsrtombs_state; | |
8a0efa53 CF |
584 | } _reent; |
585 | /* Two next two fields were once used by malloc. They are no longer | |
586 | used. They are used to preserve the space used before so as to | |
587 | allow addition of new reent fields and keep binary compatibility. */ | |
588 | struct | |
589 | { | |
590 | #define _N_LISTS 30 | |
591 | unsigned char * _nextf[_N_LISTS]; | |
592 | unsigned int _nmalloc[_N_LISTS]; | |
593 | } _unused; | |
594 | } _new; | |
595 | ||
596 | /* atexit stuff */ | |
597 | struct _atexit *_atexit; /* points to head of LIFO stack */ | |
598 | struct _atexit _atexit0; /* one guaranteed table, required by ANSI */ | |
599 | ||
600 | /* signal info */ | |
601 | void (**(_sig_func))(int); | |
602 | ||
dee51391 | 603 | /* These are here last so that __FILE can grow without changing the offsets |
8a0efa53 CF |
604 | of the above members (on the off chance that future binary compatibility |
605 | would be broken otherwise). */ | |
dee51391 JJ |
606 | struct _glue __sglue; /* root of glue chain */ |
607 | __FILE __sf[3]; /* first three file descriptors */ | |
8a0efa53 CF |
608 | }; |
609 | ||
610 | #define _REENT_INIT(var) \ | |
611 | { 0, &var.__sf[0], &var.__sf[1], &var.__sf[2], 0, "", 0, "C", \ | |
9e2a4ef8 | 612 | 0, _NULL, _NULL, 0, _NULL, _NULL, 0, _NULL, { {0, _NULL, "", \ |
ab4745dc JJ |
613 | { 0,0,0,0,0,0,0,0}, 0, 1, \ |
614 | {{_RAND48_SEED_0, _RAND48_SEED_1, _RAND48_SEED_2}, \ | |
d4dca0e4 | 615 | {_RAND48_MULT_0, _RAND48_MULT_1, _RAND48_MULT_2}, _RAND48_ADD}, \ |
9c64d2a7 | 616 | {0, {0}}, {0, {0}}, {0, {0}}, "", "", 0, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}} } } } |
d4dca0e4 JJ |
617 | |
618 | #define _REENT_INIT_PTR(var) \ | |
619 | { int i; \ | |
620 | char *tmp_ptr; \ | |
621 | var->_errno = 0; \ | |
622 | var->_stdin = &var->__sf[0]; \ | |
623 | var->_stdout = &var->__sf[1]; \ | |
624 | var->_stderr = &var->__sf[2]; \ | |
625 | var->_inc = 0; \ | |
626 | for (i = 0; i < _REENT_EMERGENCY_SIZE; ++i) \ | |
627 | var->_emergency[i] = 0; \ | |
628 | var->_current_category = 0; \ | |
629 | var->_current_locale = "C"; \ | |
630 | var->__sdidinit = 0; \ | |
631 | var->__cleanup = _NULL; \ | |
632 | var->_result = _NULL; \ | |
633 | var->_result_k = 0; \ | |
634 | var->_p5s = _NULL; \ | |
635 | var->_freelist = _NULL; \ | |
636 | var->_cvtlen = 0; \ | |
637 | var->_cvtbuf = _NULL; \ | |
638 | var->_new._reent._unused_rand = 0; \ | |
639 | var->_new._reent._strtok_last = _NULL; \ | |
640 | var->_new._reent._asctime_buf[0] = 0; \ | |
641 | tmp_ptr = (char *)&var->_new._reent._localtime_buf; \ | |
642 | for (i = 0; i < sizeof(struct __tm); ++i) \ | |
643 | tmp_ptr[i] = 0; \ | |
644 | var->_new._reent._gamma_signgam = 0; \ | |
645 | var->_new._reent._rand_next = 1; \ | |
646 | var->_new._reent._r48._seed[0] = _RAND48_SEED_0; \ | |
647 | var->_new._reent._r48._seed[1] = _RAND48_SEED_1; \ | |
648 | var->_new._reent._r48._seed[2] = _RAND48_SEED_2; \ | |
649 | var->_new._reent._r48._mult[0] = _RAND48_MULT_0; \ | |
650 | var->_new._reent._r48._mult[1] = _RAND48_MULT_1; \ | |
651 | var->_new._reent._r48._mult[2] = _RAND48_MULT_2; \ | |
652 | var->_new._reent._r48._add = _RAND48_ADD; \ | |
8d9112f2 TF |
653 | var->_new._reent._mblen_state.__count = 0; \ |
654 | var->_new._reent._mblen_state.__value.__wch = 0; \ | |
655 | var->_new._reent._mbtowc_state.__count = 0; \ | |
656 | var->_new._reent._mbtowc_state.__value.__wch = 0; \ | |
657 | var->_new._reent._wctomb_state.__count = 0; \ | |
658 | var->_new._reent._wctomb_state.__value.__wch = 0; \ | |
9c64d2a7 JJ |
659 | var->_new._reent._mbrlen_state.__count = 0; \ |
660 | var->_new._reent._mbrlen_state.__value.__wch = 0; \ | |
661 | var->_new._reent._mbrtowc_state.__count = 0; \ | |
662 | var->_new._reent._mbrtowc_state.__value.__wch = 0; \ | |
663 | var->_new._reent._mbsrtowcs_state.__count = 0; \ | |
664 | var->_new._reent._mbsrtowcs_state.__value.__wch = 0; \ | |
665 | var->_new._reent._wcrtomb_state.__count = 0; \ | |
666 | var->_new._reent._wcrtomb_state.__value.__wch = 0; \ | |
667 | var->_new._reent._wcsrtombs_state.__count = 0; \ | |
668 | var->_new._reent._wcsrtombs_state.__value.__wch = 0; \ | |
c33c3635 | 669 | var->_new._reent._l64a_buf[0] = '\0'; \ |
39e65e01 | 670 | var->_new._reent._signal_buf[0] = '\0'; \ |
35728d4f | 671 | var->_new._reent._getdate_err = 0; \ |
dc824ef7 JJ |
672 | var->_atexit = _NULL; \ |
673 | var->_atexit0._ind = 0; \ | |
674 | var->_atexit0._fns[0] = _NULL; \ | |
8266e478 JJ |
675 | var->_atexit0._on_exit_args._fntypes = 0; \ |
676 | var->_atexit0._on_exit_args._fnargs[0] = _NULL; \ | |
dc824ef7 JJ |
677 | var->_sig_func = _NULL; \ |
678 | var->__sglue._next = _NULL; \ | |
679 | var->__sglue._niobs = 0; \ | |
680 | var->__sglue._iobs = _NULL; \ | |
681 | memset(var->__sf,0,sizeof(var->__sf)); \ | |
d4dca0e4 | 682 | } |
8a0efa53 | 683 | |
8195aff7 MG |
684 | #define _REENT_CHECK_RAND48(ptr) /* nothing */ |
685 | #define _REENT_CHECK_MP(ptr) /* nothing */ | |
686 | #define _REENT_CHECK_TM(ptr) /* nothing */ | |
687 | #define _REENT_CHECK_ASCTIME_BUF(ptr) /* nothing */ | |
815a37f7 | 688 | #define _REENT_CHECK_EMERGENCY(ptr) /* nothing */ |
d4dca0e4 | 689 | #define _REENT_CHECK_MISC(ptr) /* nothing */ |
39e65e01 | 690 | #define _REENT_CHECK_SIGNAL_BUF(ptr) /* nothing */ |
8195aff7 MG |
691 | |
692 | #define _REENT_SIGNGAM(ptr) ((ptr)->_new._reent._gamma_signgam) | |
693 | #define _REENT_RAND_NEXT(ptr) ((ptr)->_new._reent._rand_next) | |
694 | #define _REENT_RAND48_SEED(ptr) ((ptr)->_new._reent._r48._seed) | |
695 | #define _REENT_RAND48_MULT(ptr) ((ptr)->_new._reent._r48._mult) | |
696 | #define _REENT_RAND48_ADD(ptr) ((ptr)->_new._reent._r48._add) | |
697 | #define _REENT_MP_RESULT(ptr) ((ptr)->_result) | |
698 | #define _REENT_MP_RESULT_K(ptr) ((ptr)->_result_k) | |
699 | #define _REENT_MP_P5S(ptr) ((ptr)->_p5s) | |
700 | #define _REENT_MP_FREELIST(ptr) ((ptr)->_freelist) | |
c9524c0c | 701 | #define _REENT_ASCTIME_BUF(ptr) ((ptr)->_new._reent._asctime_buf) |
8195aff7 MG |
702 | #define _REENT_TM(ptr) (&(ptr)->_new._reent._localtime_buf) |
703 | #define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) | |
d4dca0e4 JJ |
704 | #define _REENT_STRTOK_LAST(ptr) ((ptr)->_new._reent._strtok_last) |
705 | #define _REENT_MBLEN_STATE(ptr) ((ptr)->_new._reent._mblen_state) | |
706 | #define _REENT_MBTOWC_STATE(ptr)((ptr)->_new._reent._mbtowc_state) | |
707 | #define _REENT_WCTOMB_STATE(ptr)((ptr)->_new._reent._wctomb_state) | |
9c64d2a7 JJ |
708 | #define _REENT_MBRLEN_STATE(ptr)((ptr)->_new._reent._mbrlen_state) |
709 | #define _REENT_MBRTOWC_STATE(ptr)((ptr)->_new._reent._mbrtowc_state) | |
710 | #define _REENT_MBSRTOWCS_STATE(ptr)((ptr)->_new._reent._mbsrtowcs_state) | |
711 | #define _REENT_WCRTOMB_STATE(ptr)((ptr)->_new._reent._wcrtomb_state) | |
712 | #define _REENT_WCSRTOMBS_STATE(ptr)((ptr)->_new._reent._wcsrtombs_state) | |
c33c3635 | 713 | #define _REENT_L64A_BUF(ptr) ((ptr)->_new._reent._l64a_buf) |
39e65e01 | 714 | #define _REENT_SIGNAL_BUF(ptr) ((ptr)->_new._reent._signal_buf) |
35728d4f | 715 | #define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_new._reent._getdate_err)) |
8195aff7 MG |
716 | |
717 | #endif /* !_REENT_SMALL */ | |
718 | ||
719 | #define _NULL 0 | |
720 | ||
8a0efa53 CF |
721 | /* |
722 | * All references to struct _reent are via this pointer. | |
723 | * Internally, newlib routines that need to reference it should use _REENT. | |
724 | */ | |
725 | ||
726 | #ifndef __ATTRIBUTE_IMPURE_PTR__ | |
727 | #define __ATTRIBUTE_IMPURE_PTR__ | |
728 | #endif | |
729 | ||
730 | extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__; | |
731 | ||
732 | void _reclaim_reent _PARAMS ((struct _reent *)); | |
733 | ||
734 | /* #define _REENT_ONLY define this to get only reentrant routines */ | |
735 | ||
736 | #ifndef _REENT_ONLY | |
5e2cbfb6 JJ |
737 | |
738 | #if defined(__DYNAMIC_REENT__) && !defined(__SINGLE_THREAD__) | |
739 | struct _reent * _EXFUN(__getreent, (void)); | |
740 | # define _REENT (__getreent()) | |
741 | #else /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */ | |
742 | # define _REENT _impure_ptr | |
743 | #endif /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */ | |
744 | ||
d4dca0e4 | 745 | #endif /* !_REENT_ONLY */ |
8a0efa53 | 746 | |
9fc9e1c9 JJ |
747 | #define _GLOBAL_REENT _impure_ptr |
748 | ||
8a0efa53 CF |
749 | #ifdef __cplusplus |
750 | } | |
751 | #endif | |
752 | #endif /* _SYS_REENT_H_ */ |