binmode(FH); to act like binmode(FH,":bytes") as well as
[p5sagit/p5-mst-13.2.git] / reentr.c
CommitLineData
10bc17b6 1/*
2 * reentr.c
3 *
4 * Copyright (c) 1997-2002, Larry Wall
5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
9 * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
10 * This file is built by reentrl.pl from data in reentr.pl.
11 *
12 * "Saruman," I said, standing away from him, "only one hand at a time can
13 * wield the One, and you know that well, so do not trouble to say we!"
14 *
15 */
16
17#include "EXTERN.h"
18#define PERL_IN_REENTR_C
19#include "perl.h"
20#include "reentr.h"
21
22void
23Perl_reentrant_size(pTHX) {
24#ifdef USE_REENTRANT_API
8695fa85 25#define REENTRANTSMALLSIZE 256 /* Make something up. */
26#define REENTRANTUSUALSIZE 4096 /* Make something up. */
10bc17b6 27#ifdef HAS_ASCTIME_R
8695fa85 28 PL_reentrant_buffer->_asctime_size = REENTRANTSMALLSIZE;
10bc17b6 29#endif /* HAS_ASCTIME_R */
30#ifdef HAS_CRYPT_R
31#endif /* HAS_CRYPT_R */
32#ifdef HAS_CTIME_R
8695fa85 33 PL_reentrant_buffer->_ctime_size = REENTRANTSMALLSIZE;
10bc17b6 34#endif /* HAS_CTIME_R */
35#ifdef HAS_DRAND48_R
36#endif /* HAS_DRAND48_R */
37#ifdef HAS_GETGRNAM_R
f7937171 38# if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
39 PL_reentrant_buffer->_grent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
40 if (PL_reentrant_buffer->_pwent_size == -1)
41 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
10bc17b6 42# else
43# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
f7937171 44 PL_reentrant_buffer->_grent_size = SIABUFSIZ;
10bc17b6 45# else
46# ifdef __sgi
f7937171 47 PL_reentrant_buffer->_grent_size = BUFSIZ;
10bc17b6 48# else
f7937171 49 PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
10bc17b6 50# endif
51# endif
52# endif
53#endif /* HAS_GETGRNAM_R */
54#ifdef HAS_GETHOSTBYNAME_R
55#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 56 PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE;
10bc17b6 57#endif
58#endif /* HAS_GETHOSTBYNAME_R */
59#ifdef HAS_GETLOGIN_R
8695fa85 60 PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
10bc17b6 61#endif /* HAS_GETLOGIN_R */
62#ifdef HAS_GETNETBYNAME_R
63#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 64 PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE;
10bc17b6 65#endif
66#endif /* HAS_GETNETBYNAME_R */
67#ifdef HAS_GETPROTOBYNAME_R
68#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 69 PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE;
10bc17b6 70#endif
71#endif /* HAS_GETPROTOBYNAME_R */
72#ifdef HAS_GETPWNAM_R
73# if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
f7937171 74 PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
75 if (PL_reentrant_buffer->_pwent_size == -1)
76 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
10bc17b6 77# else
78# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
f7937171 79 PL_reentrant_buffer->_pwent_size = SIABUFSIZ;
10bc17b6 80# else
81# ifdef __sgi
f7937171 82 PL_reentrant_buffer->_pwent_size = BUFSIZ;
10bc17b6 83# else
f7937171 84 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
10bc17b6 85# endif
86# endif
87# endif
88#endif /* HAS_GETPWNAM_R */
89#ifdef HAS_GETSERVBYNAME_R
90#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
f7937171 91 PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE;
10bc17b6 92#endif
93#endif /* HAS_GETSERVBYNAME_R */
94#ifdef HAS_GETSPNAM_R
f7937171 95# if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
96 PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
97 if (PL_reentrant_buffer->_pwent_size == -1)
98 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
99# else
100# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
101 PL_reentrant_buffer->_spent_size = SIABUFSIZ;
102# else
103# ifdef __sgi
104 PL_reentrant_buffer->_spent_size = BUFSIZ;
105# else
106 PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
107# endif
108# endif
109# endif
10bc17b6 110#endif /* HAS_GETSPNAM_R */
111#ifdef HAS_GMTIME_R
112#endif /* HAS_GMTIME_R */
113#ifdef HAS_LOCALTIME_R
114#endif /* HAS_LOCALTIME_R */
115#ifdef HAS_RANDOM_R
116#endif /* HAS_RANDOM_R */
117#ifdef HAS_READDIR_R
118 /* This is the size Solaris recommends.
119 * (though we go static, should use pathconf() instead) */
120 PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
121#endif /* HAS_READDIR_R */
122#ifdef HAS_READDIR64_R
123 /* This is the size Solaris recommends.
124 * (though we go static, should use pathconf() instead) */
125 PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
126#endif /* HAS_READDIR64_R */
127#ifdef HAS_SETLOCALE_R
8695fa85 128 PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
10bc17b6 129#endif /* HAS_SETLOCALE_R */
130#ifdef HAS_STRERROR_R
8695fa85 131 PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
10bc17b6 132#endif /* HAS_STRERROR_R */
133#ifdef HAS_TTYNAME_R
8695fa85 134 PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
10bc17b6 135#endif /* HAS_TTYNAME_R */
136
137#endif /* USE_REENTRANT_API */
138}
139
140void
141Perl_reentrant_init(pTHX) {
142#ifdef USE_REENTRANT_API
143 New(31337, PL_reentrant_buffer, 1, REENTR);
144 Perl_reentrant_size(aTHX);
145#ifdef HAS_ASCTIME_R
146 New(31338, PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
147#endif /* HAS_ASCTIME_R */
148#ifdef HAS_CRYPT_R
149#ifdef __GLIBC__
150 PL_reentrant_buffer->_crypt_struct.initialized = 0;
151#endif
152#endif /* HAS_CRYPT_R */
153#ifdef HAS_CTIME_R
154 New(31338, PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
155#endif /* HAS_CTIME_R */
156#ifdef HAS_DRAND48_R
157#endif /* HAS_DRAND48_R */
158#ifdef HAS_GETGRNAM_R
f7937171 159# ifdef USE_GRENT_FPTR
160 PL_reentrant_buffer->_grent_fptr = NULL;
10bc17b6 161# endif
f7937171 162 New(31338, PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char);
10bc17b6 163#endif /* HAS_GETGRNAM_R */
164#ifdef HAS_GETHOSTBYNAME_R
165#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 166 New(31338, PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char);
10bc17b6 167#endif
168#endif /* HAS_GETHOSTBYNAME_R */
169#ifdef HAS_GETLOGIN_R
170 New(31338, PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
171#endif /* HAS_GETLOGIN_R */
172#ifdef HAS_GETNETBYNAME_R
173#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 174 New(31338, PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char);
10bc17b6 175#endif
176#endif /* HAS_GETNETBYNAME_R */
177#ifdef HAS_GETPROTOBYNAME_R
178#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 179 New(31338, PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char);
10bc17b6 180#endif
181#endif /* HAS_GETPROTOBYNAME_R */
182#ifdef HAS_GETPWNAM_R
f7937171 183# ifdef USE_PWENT_FPTR
184 PL_reentrant_buffer->_pwent_fptr = NULL;
10bc17b6 185# endif
f7937171 186 New(31338, PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char);
10bc17b6 187#endif /* HAS_GETPWNAM_R */
188#ifdef HAS_GETSERVBYNAME_R
189#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
f7937171 190 New(31338, PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char);
10bc17b6 191#endif
192#endif /* HAS_GETSERVBYNAME_R */
193#ifdef HAS_GETSPNAM_R
f7937171 194# ifdef USE_SPENT_FPTR
195 PL_reentrant_buffer->_spent_fptr = NULL;
196# endif
197 New(31338, PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
10bc17b6 198#endif /* HAS_GETSPNAM_R */
199#ifdef HAS_GMTIME_R
200#endif /* HAS_GMTIME_R */
201#ifdef HAS_LOCALTIME_R
202#endif /* HAS_LOCALTIME_R */
203#ifdef HAS_RANDOM_R
204#endif /* HAS_RANDOM_R */
205#ifdef HAS_READDIR_R
206 PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
207#endif /* HAS_READDIR_R */
208#ifdef HAS_READDIR64_R
209 PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
210#endif /* HAS_READDIR64_R */
211#ifdef HAS_SETLOCALE_R
212 New(31338, PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
213#endif /* HAS_SETLOCALE_R */
214#ifdef HAS_STRERROR_R
215 New(31338, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
216#endif /* HAS_STRERROR_R */
217#ifdef HAS_TTYNAME_R
218 New(31338, PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
219#endif /* HAS_TTYNAME_R */
220
221#endif /* USE_REENTRANT_API */
222}
223
224void
225Perl_reentrant_free(pTHX) {
226#ifdef USE_REENTRANT_API
227#ifdef HAS_ASCTIME_R
228 Safefree(PL_reentrant_buffer->_asctime_buffer);
229#endif /* HAS_ASCTIME_R */
230#ifdef HAS_CRYPT_R
231#endif /* HAS_CRYPT_R */
232#ifdef HAS_CTIME_R
233 Safefree(PL_reentrant_buffer->_ctime_buffer);
234#endif /* HAS_CTIME_R */
235#ifdef HAS_DRAND48_R
236#endif /* HAS_DRAND48_R */
237#ifdef HAS_GETGRNAM_R
f7937171 238 Safefree(PL_reentrant_buffer->_grent_buffer);
10bc17b6 239#endif /* HAS_GETGRNAM_R */
240#ifdef HAS_GETHOSTBYNAME_R
241#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 242 Safefree(PL_reentrant_buffer->_hostent_buffer);
10bc17b6 243#endif
244#endif /* HAS_GETHOSTBYNAME_R */
245#ifdef HAS_GETLOGIN_R
246 Safefree(PL_reentrant_buffer->_getlogin_buffer);
247#endif /* HAS_GETLOGIN_R */
248#ifdef HAS_GETNETBYNAME_R
249#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 250 Safefree(PL_reentrant_buffer->_netent_buffer);
10bc17b6 251#endif
252#endif /* HAS_GETNETBYNAME_R */
253#ifdef HAS_GETPROTOBYNAME_R
254#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
f7937171 255 Safefree(PL_reentrant_buffer->_protoent_buffer);
10bc17b6 256#endif
257#endif /* HAS_GETPROTOBYNAME_R */
258#ifdef HAS_GETPWNAM_R
f7937171 259 Safefree(PL_reentrant_buffer->_pwent_buffer);
10bc17b6 260#endif /* HAS_GETPWNAM_R */
261#ifdef HAS_GETSERVBYNAME_R
262#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
f7937171 263 Safefree(PL_reentrant_buffer->_servent_buffer);
10bc17b6 264#endif
265#endif /* HAS_GETSERVBYNAME_R */
266#ifdef HAS_GETSPNAM_R
f7937171 267 Safefree(PL_reentrant_buffer->_spent_buffer);
10bc17b6 268#endif /* HAS_GETSPNAM_R */
269#ifdef HAS_GMTIME_R
270#endif /* HAS_GMTIME_R */
271#ifdef HAS_LOCALTIME_R
272#endif /* HAS_LOCALTIME_R */
273#ifdef HAS_RANDOM_R
274#endif /* HAS_RANDOM_R */
275#ifdef HAS_READDIR_R
276 Safefree(PL_reentrant_buffer->_readdir_struct);
277#endif /* HAS_READDIR_R */
278#ifdef HAS_READDIR64_R
279 Safefree(PL_reentrant_buffer->_readdir64_struct);
280#endif /* HAS_READDIR64_R */
281#ifdef HAS_SETLOCALE_R
282 Safefree(PL_reentrant_buffer->_setlocale_buffer);
283#endif /* HAS_SETLOCALE_R */
284#ifdef HAS_STRERROR_R
285 Safefree(PL_reentrant_buffer->_strerror_buffer);
286#endif /* HAS_STRERROR_R */
287#ifdef HAS_TTYNAME_R
288 Safefree(PL_reentrant_buffer->_ttyname_buffer);
289#endif /* HAS_TTYNAME_R */
290
291 Safefree(PL_reentrant_buffer);
292#endif /* USE_REENTRANT_API */
293}
294
edd309b7 295void*
296Perl_reentrant_retry(const char *f, ...)
297{
298 dTHX;
299 void *retptr = NULL;
300#ifdef USE_REENTRANT_API
f7937171 301# if defined(USE_HOSTENT_BUFFER) || defined(USE_GRENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PWENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SRVENT_BUFFER)
e3410746 302 void *p0;
303# endif
f7937171 304# if defined(USE_SERVENT_BUFFER)
e3410746 305 void *p1;
306# endif
f7937171 307# if defined(USE_HOSTENT_BUFFER)
edd309b7 308 size_t asize;
e3410746 309# endif
f7937171 310# if defined(USE_HOSTENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SERVENT_BUFFER)
edd309b7 311 int anint;
e3410746 312# endif
edd309b7 313 va_list ap;
314
315 va_start(ap, f);
316
317#define REENTRANTHALFMAXSIZE 32768 /* The maximum may end up twice this. */
318
319 switch (PL_op->op_type) {
f7937171 320#ifdef USE_HOSTENT_BUFFER
edd309b7 321 case OP_GHBYADDR:
322 case OP_GHBYNAME:
323 case OP_GHOSTENT:
324 {
f7937171 325 if (PL_reentrant_buffer->_hostent_size <= REENTRANTHALFMAXSIZE) {
326 PL_reentrant_buffer->_hostent_size *= 2;
327 Renew(PL_reentrant_buffer->_hostent_buffer,
328 PL_reentrant_buffer->_hostent_size, char);
edd309b7 329 switch (PL_op->op_type) {
330 case OP_GHBYADDR:
331 p0 = va_arg(ap, void *);
332 asize = va_arg(ap, size_t);
333 anint = va_arg(ap, int);
334 retptr = gethostbyaddr(p0, asize, anint); break;
335 case OP_GHBYNAME:
336 p0 = va_arg(ap, void *);
337 retptr = gethostbyname(p0); break;
338 case OP_GHOSTENT:
339 retptr = gethostent(); break;
340 default:
341 break;
342 }
343 }
344 }
345 break;
346#endif
f7937171 347#ifdef USE_GRENT_BUFFER
edd309b7 348 case OP_GGRNAM:
349 case OP_GGRGID:
350 case OP_GGRENT:
351 {
f7937171 352 if (PL_reentrant_buffer->_grent_size <= REENTRANTHALFMAXSIZE) {
edd309b7 353 Gid_t gid;
f7937171 354 PL_reentrant_buffer->_grent_size *= 2;
355 Renew(PL_reentrant_buffer->_grent_buffer,
356 PL_reentrant_buffer->_grent_size, char);
edd309b7 357 switch (PL_op->op_type) {
358 case OP_GGRNAM:
359 p0 = va_arg(ap, void *);
360 retptr = getgrnam(p0); break;
361 case OP_GGRGID:
362 gid = va_arg(ap, Gid_t);
363 retptr = getgrgid(gid); break;
364 case OP_GGRENT:
365 retptr = getgrent(); break;
366 default:
367 break;
368 }
369 }
370 }
371 break;
372#endif
f7937171 373#ifdef USE_NETENT_BUFFER
edd309b7 374 case OP_GNBYADDR:
375 case OP_GNBYNAME:
376 case OP_GNETENT:
377 {
f7937171 378 if (PL_reentrant_buffer->_netent_size <= REENTRANTHALFMAXSIZE) {
edd309b7 379 Netdb_net_t net;
f7937171 380 PL_reentrant_buffer->_netent_size *= 2;
381 Renew(PL_reentrant_buffer->_netent_buffer,
382 PL_reentrant_buffer->_netent_size, char);
edd309b7 383 switch (PL_op->op_type) {
384 case OP_GNBYADDR:
385 net = va_arg(ap, Netdb_net_t);
386 anint = va_arg(ap, int);
387 retptr = getnetbyaddr(net, anint); break;
388 case OP_GNBYNAME:
389 p0 = va_arg(ap, void *);
390 retptr = getnetbyname(p0); break;
391 case OP_GNETENT:
392 retptr = getnetent(); break;
393 default:
394 break;
395 }
396 }
397 }
398 break;
399#endif
f7937171 400#ifdef USE_PWENT_BUFFER
edd309b7 401 case OP_GPWNAM:
402 case OP_GPWUID:
403 case OP_GPWENT:
404 {
f7937171 405 if (PL_reentrant_buffer->_pwent_size <= REENTRANTHALFMAXSIZE) {
edd309b7 406 Uid_t uid;
f7937171 407 PL_reentrant_buffer->_pwent_size *= 2;
408 Renew(PL_reentrant_buffer->_pwent_buffer,
409 PL_reentrant_buffer->_pwent_size, char);
edd309b7 410 switch (PL_op->op_type) {
411 case OP_GPWNAM:
412 p0 = va_arg(ap, void *);
413 retptr = getpwnam(p0); break;
414 case OP_GPWUID:
415 uid = va_arg(ap, Uid_t);
416 retptr = getpwuid(uid); break;
417 case OP_GPWENT:
418 retptr = getpwent(); break;
419 default:
420 break;
421 }
422 }
423 }
424 break;
425#endif
f7937171 426#ifdef USE_PROTOENT_BUFFER
edd309b7 427 case OP_GPBYNAME:
428 case OP_GPBYNUMBER:
429 case OP_GPROTOENT:
430 {
f7937171 431 if (PL_reentrant_buffer->_protoent_size <= REENTRANTHALFMAXSIZE) {
432 PL_reentrant_buffer->_protoent_size *= 2;
433 Renew(PL_reentrant_buffer->_protoent_buffer,
434 PL_reentrant_buffer->_protoent_size, char);
edd309b7 435 switch (PL_op->op_type) {
436 case OP_GPBYNAME:
437 p0 = va_arg(ap, void *);
438 retptr = getprotobyname(p0); break;
439 case OP_GPBYNUMBER:
440 anint = va_arg(ap, int);
441 retptr = getprotobynumber(anint); break;
442 case OP_GPROTOENT:
443 retptr = getprotoent(); break;
444 default:
445 break;
446 }
447 }
448 }
449 break;
450#endif
f7937171 451#ifdef USE_SERVENT_BUFFER
edd309b7 452 case OP_GSBYNAME:
453 case OP_GSBYPORT:
454 case OP_GSERVENT:
455 {
f7937171 456 if (PL_reentrant_buffer->_servent_size <= REENTRANTHALFMAXSIZE) {
457 PL_reentrant_buffer->_servent_size *= 2;
458 Renew(PL_reentrant_buffer->_servent_buffer,
459 PL_reentrant_buffer->_servent_size, char);
edd309b7 460 switch (PL_op->op_type) {
461 case OP_GSBYNAME:
462 p0 = va_arg(ap, void *);
463 p1 = va_arg(ap, void *);
464 retptr = getservbyname(p0, p1); break;
465 case OP_GSBYPORT:
466 anint = va_arg(ap, int);
467 p0 = va_arg(ap, void *);
468 retptr = getservbyport(anint, p0); break;
469 case OP_GSERVENT:
470 retptr = getservent(); break;
471 default:
472 break;
473 }
474 }
475 }
476 break;
477#endif
478 default:
479 /* Not known how to retry, so just fail. */
480 break;
481 }
482
483 va_end(ap);
484#endif
485 return retptr;
486}
487