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