Integrate perlio:
[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
38# if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
39 PL_reentrant_buffer->_getgrent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
8695fa85 40 if (PL_reentrant_buffer->_getgrent_size == -1)
41 PL_reentrant_buffer->_getgrent_size = REENTRANTUSUALSIZE;
10bc17b6 42# else
43# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
44 PL_reentrant_buffer->_getgrent_size = SIABUFSIZ;
45# else
46# ifdef __sgi
47 PL_reentrant_buffer->_getgrent_size = BUFSIZ;
48# else
8695fa85 49 PL_reentrant_buffer->_getgrent_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)
8695fa85 56 PL_reentrant_buffer->_gethostent_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)
8695fa85 64 PL_reentrant_buffer->_getnetent_size = REENTRANTUSUALSIZE;
10bc17b6 65#endif
66#endif /* HAS_GETNETBYNAME_R */
67#ifdef HAS_GETPROTOBYNAME_R
68#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
8695fa85 69 PL_reentrant_buffer->_getprotoent_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__)
74 PL_reentrant_buffer->_getpwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
e3410746 75 if (PL_reentrant_buffer->_getpwent_size == -1)
76 PL_reentrant_buffer->_getpwent_size = REENTRANTUSUALSIZE;
10bc17b6 77# else
78# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
79 PL_reentrant_buffer->_getpwent_size = SIABUFSIZ;
80# else
81# ifdef __sgi
82 PL_reentrant_buffer->_getpwent_size = BUFSIZ;
83# else
8695fa85 84 PL_reentrant_buffer->_getpwent_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)
8695fa85 91 PL_reentrant_buffer->_getservent_size = REENTRANTUSUALSIZE;
10bc17b6 92#endif
93#endif /* HAS_GETSERVBYNAME_R */
94#ifdef HAS_GETSPNAM_R
95 PL_reentrant_buffer->_getspent_size = 1024;
96#endif /* HAS_GETSPNAM_R */
97#ifdef HAS_GMTIME_R
98#endif /* HAS_GMTIME_R */
99#ifdef HAS_LOCALTIME_R
100#endif /* HAS_LOCALTIME_R */
101#ifdef HAS_RANDOM_R
102#endif /* HAS_RANDOM_R */
103#ifdef HAS_READDIR_R
104 /* This is the size Solaris recommends.
105 * (though we go static, should use pathconf() instead) */
106 PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
107#endif /* HAS_READDIR_R */
108#ifdef HAS_READDIR64_R
109 /* This is the size Solaris recommends.
110 * (though we go static, should use pathconf() instead) */
111 PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
112#endif /* HAS_READDIR64_R */
113#ifdef HAS_SETLOCALE_R
8695fa85 114 PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
10bc17b6 115#endif /* HAS_SETLOCALE_R */
116#ifdef HAS_STRERROR_R
8695fa85 117 PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
10bc17b6 118#endif /* HAS_STRERROR_R */
119#ifdef HAS_TTYNAME_R
8695fa85 120 PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
10bc17b6 121#endif /* HAS_TTYNAME_R */
122
123#endif /* USE_REENTRANT_API */
124}
125
126void
127Perl_reentrant_init(pTHX) {
128#ifdef USE_REENTRANT_API
129 New(31337, PL_reentrant_buffer, 1, REENTR);
130 Perl_reentrant_size(aTHX);
131#ifdef HAS_ASCTIME_R
132 New(31338, PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
133#endif /* HAS_ASCTIME_R */
134#ifdef HAS_CRYPT_R
135#ifdef __GLIBC__
136 PL_reentrant_buffer->_crypt_struct.initialized = 0;
137#endif
138#endif /* HAS_CRYPT_R */
139#ifdef HAS_CTIME_R
140 New(31338, PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
141#endif /* HAS_CTIME_R */
142#ifdef HAS_DRAND48_R
143#endif /* HAS_DRAND48_R */
144#ifdef HAS_GETGRNAM_R
145# ifdef USE_GETGRENT_FPTR
146 PL_reentrant_buffer->_getgrent_fptr = NULL;
147# endif
148 New(31338, PL_reentrant_buffer->_getgrent_buffer, PL_reentrant_buffer->_getgrent_size, char);
149#endif /* HAS_GETGRNAM_R */
150#ifdef HAS_GETHOSTBYNAME_R
151#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
152 New(31338, PL_reentrant_buffer->_gethostent_buffer, PL_reentrant_buffer->_gethostent_size, char);
153#endif
154#endif /* HAS_GETHOSTBYNAME_R */
155#ifdef HAS_GETLOGIN_R
156 New(31338, PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
157#endif /* HAS_GETLOGIN_R */
158#ifdef HAS_GETNETBYNAME_R
159#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
160 New(31338, PL_reentrant_buffer->_getnetent_buffer, PL_reentrant_buffer->_getnetent_size, char);
161#endif
162#endif /* HAS_GETNETBYNAME_R */
163#ifdef HAS_GETPROTOBYNAME_R
164#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
165 New(31338, PL_reentrant_buffer->_getprotoent_buffer, PL_reentrant_buffer->_getprotoent_size, char);
166#endif
167#endif /* HAS_GETPROTOBYNAME_R */
168#ifdef HAS_GETPWNAM_R
169# ifdef USE_GETPWENT_FPTR
170 PL_reentrant_buffer->_getpwent_fptr = NULL;
171# endif
172 New(31338, PL_reentrant_buffer->_getpwent_buffer, PL_reentrant_buffer->_getpwent_size, char);
173#endif /* HAS_GETPWNAM_R */
174#ifdef HAS_GETSERVBYNAME_R
175#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
176 New(31338, PL_reentrant_buffer->_getservent_buffer, PL_reentrant_buffer->_getservent_size, char);
177#endif
178#endif /* HAS_GETSERVBYNAME_R */
179#ifdef HAS_GETSPNAM_R
180 New(31338, PL_reentrant_buffer->_getspent_buffer, PL_reentrant_buffer->_getspent_size, char);
181#endif /* HAS_GETSPNAM_R */
182#ifdef HAS_GMTIME_R
183#endif /* HAS_GMTIME_R */
184#ifdef HAS_LOCALTIME_R
185#endif /* HAS_LOCALTIME_R */
186#ifdef HAS_RANDOM_R
187#endif /* HAS_RANDOM_R */
188#ifdef HAS_READDIR_R
189 PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
190#endif /* HAS_READDIR_R */
191#ifdef HAS_READDIR64_R
192 PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
193#endif /* HAS_READDIR64_R */
194#ifdef HAS_SETLOCALE_R
195 New(31338, PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
196#endif /* HAS_SETLOCALE_R */
197#ifdef HAS_STRERROR_R
198 New(31338, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
199#endif /* HAS_STRERROR_R */
200#ifdef HAS_TTYNAME_R
201 New(31338, PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
202#endif /* HAS_TTYNAME_R */
203
204#endif /* USE_REENTRANT_API */
205}
206
207void
208Perl_reentrant_free(pTHX) {
209#ifdef USE_REENTRANT_API
210#ifdef HAS_ASCTIME_R
211 Safefree(PL_reentrant_buffer->_asctime_buffer);
212#endif /* HAS_ASCTIME_R */
213#ifdef HAS_CRYPT_R
214#endif /* HAS_CRYPT_R */
215#ifdef HAS_CTIME_R
216 Safefree(PL_reentrant_buffer->_ctime_buffer);
217#endif /* HAS_CTIME_R */
218#ifdef HAS_DRAND48_R
219#endif /* HAS_DRAND48_R */
220#ifdef HAS_GETGRNAM_R
221 Safefree(PL_reentrant_buffer->_getgrent_buffer);
222#endif /* HAS_GETGRNAM_R */
223#ifdef HAS_GETHOSTBYNAME_R
224#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
225 Safefree(PL_reentrant_buffer->_gethostent_buffer);
226#endif
227#endif /* HAS_GETHOSTBYNAME_R */
228#ifdef HAS_GETLOGIN_R
229 Safefree(PL_reentrant_buffer->_getlogin_buffer);
230#endif /* HAS_GETLOGIN_R */
231#ifdef HAS_GETNETBYNAME_R
232#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
233 Safefree(PL_reentrant_buffer->_getnetent_buffer);
234#endif
235#endif /* HAS_GETNETBYNAME_R */
236#ifdef HAS_GETPROTOBYNAME_R
237#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
238 Safefree(PL_reentrant_buffer->_getprotoent_buffer);
239#endif
240#endif /* HAS_GETPROTOBYNAME_R */
241#ifdef HAS_GETPWNAM_R
242 Safefree(PL_reentrant_buffer->_getpwent_buffer);
243#endif /* HAS_GETPWNAM_R */
244#ifdef HAS_GETSERVBYNAME_R
245#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
246 Safefree(PL_reentrant_buffer->_getservent_buffer);
247#endif
248#endif /* HAS_GETSERVBYNAME_R */
249#ifdef HAS_GETSPNAM_R
250 Safefree(PL_reentrant_buffer->_getspent_buffer);
251#endif /* HAS_GETSPNAM_R */
252#ifdef HAS_GMTIME_R
253#endif /* HAS_GMTIME_R */
254#ifdef HAS_LOCALTIME_R
255#endif /* HAS_LOCALTIME_R */
256#ifdef HAS_RANDOM_R
257#endif /* HAS_RANDOM_R */
258#ifdef HAS_READDIR_R
259 Safefree(PL_reentrant_buffer->_readdir_struct);
260#endif /* HAS_READDIR_R */
261#ifdef HAS_READDIR64_R
262 Safefree(PL_reentrant_buffer->_readdir64_struct);
263#endif /* HAS_READDIR64_R */
264#ifdef HAS_SETLOCALE_R
265 Safefree(PL_reentrant_buffer->_setlocale_buffer);
266#endif /* HAS_SETLOCALE_R */
267#ifdef HAS_STRERROR_R
268 Safefree(PL_reentrant_buffer->_strerror_buffer);
269#endif /* HAS_STRERROR_R */
270#ifdef HAS_TTYNAME_R
271 Safefree(PL_reentrant_buffer->_ttyname_buffer);
272#endif /* HAS_TTYNAME_R */
273
274 Safefree(PL_reentrant_buffer);
275#endif /* USE_REENTRANT_API */
276}
277
edd309b7 278void*
279Perl_reentrant_retry(const char *f, ...)
280{
281 dTHX;
282 void *retptr = NULL;
283#ifdef USE_REENTRANT_API
e3410746 284# if defined(USE_GETHOSTENT_BUFFER) || defined(USE_GETGRENT_BUFFER) || defined(USE_GETNETENT_BUFFER) || defined(USE_GETPWENT_BUFFER) || defined(USE_GETPROTOENT_BUFFER) || defined(USE_GETSERVENT_BUFFER)
285 void *p0;
286# endif
287# if defined(USE_GETSERVENT_BUFFER)
288 void *p1;
289# endif
290# if defined(USE_GETHOSTENT_BUFFER)
edd309b7 291 size_t asize;
e3410746 292# endif
293# if defined(USE_GETHOSTENT_BUFFER) || defined(USE_GETNETENT_BUFFER) || defined(USE_GETPROTOENT_BUFFER) || defined(USE_GETSERVENT_BUFFER)
edd309b7 294 int anint;
e3410746 295# endif
edd309b7 296 va_list ap;
297
298 va_start(ap, f);
299
300#define REENTRANTHALFMAXSIZE 32768 /* The maximum may end up twice this. */
301
302 switch (PL_op->op_type) {
303#ifdef USE_GETHOSTENT_BUFFER
304 case OP_GHBYADDR:
305 case OP_GHBYNAME:
306 case OP_GHOSTENT:
307 {
308 if (PL_reentrant_buffer->_gethostent_size <= REENTRANTHALFMAXSIZE) {
309 PL_reentrant_buffer->_gethostent_size *= 2;
310 Renew(PL_reentrant_buffer->_gethostent_buffer,
311 PL_reentrant_buffer->_gethostent_size, char);
312 switch (PL_op->op_type) {
313 case OP_GHBYADDR:
314 p0 = va_arg(ap, void *);
315 asize = va_arg(ap, size_t);
316 anint = va_arg(ap, int);
317 retptr = gethostbyaddr(p0, asize, anint); break;
318 case OP_GHBYNAME:
319 p0 = va_arg(ap, void *);
320 retptr = gethostbyname(p0); break;
321 case OP_GHOSTENT:
322 retptr = gethostent(); break;
323 default:
324 break;
325 }
326 }
327 }
328 break;
329#endif
330#ifdef USE_GETGRENT_BUFFER
331 case OP_GGRNAM:
332 case OP_GGRGID:
333 case OP_GGRENT:
334 {
335 if (PL_reentrant_buffer->_getgrent_size <= REENTRANTHALFMAXSIZE) {
336 Gid_t gid;
337 PL_reentrant_buffer->_getgrent_size *= 2;
338 Renew(PL_reentrant_buffer->_getgrent_buffer,
339 PL_reentrant_buffer->_getgrent_size, char);
340 switch (PL_op->op_type) {
341 case OP_GGRNAM:
342 p0 = va_arg(ap, void *);
343 retptr = getgrnam(p0); break;
344 case OP_GGRGID:
345 gid = va_arg(ap, Gid_t);
346 retptr = getgrgid(gid); break;
347 case OP_GGRENT:
348 retptr = getgrent(); break;
349 default:
350 break;
351 }
352 }
353 }
354 break;
355#endif
356#ifdef USE_GETNETENT_BUFFER
357 case OP_GNBYADDR:
358 case OP_GNBYNAME:
359 case OP_GNETENT:
360 {
361 if (PL_reentrant_buffer->_getnetent_size <= REENTRANTHALFMAXSIZE) {
362 Netdb_net_t net;
363 PL_reentrant_buffer->_getnetent_size *= 2;
364 Renew(PL_reentrant_buffer->_getnetent_buffer,
365 PL_reentrant_buffer->_getnetent_size, char);
366 switch (PL_op->op_type) {
367 case OP_GNBYADDR:
368 net = va_arg(ap, Netdb_net_t);
369 anint = va_arg(ap, int);
370 retptr = getnetbyaddr(net, anint); break;
371 case OP_GNBYNAME:
372 p0 = va_arg(ap, void *);
373 retptr = getnetbyname(p0); break;
374 case OP_GNETENT:
375 retptr = getnetent(); break;
376 default:
377 break;
378 }
379 }
380 }
381 break;
382#endif
383#ifdef USE_GETPWENT_BUFFER
384 case OP_GPWNAM:
385 case OP_GPWUID:
386 case OP_GPWENT:
387 {
388 if (PL_reentrant_buffer->_getpwent_size <= REENTRANTHALFMAXSIZE) {
389 Uid_t uid;
390 PL_reentrant_buffer->_getpwent_size *= 2;
391 Renew(PL_reentrant_buffer->_getpwent_buffer,
392 PL_reentrant_buffer->_getpwent_size, char);
393 switch (PL_op->op_type) {
394 case OP_GPWNAM:
395 p0 = va_arg(ap, void *);
396 retptr = getpwnam(p0); break;
397 case OP_GPWUID:
398 uid = va_arg(ap, Uid_t);
399 retptr = getpwuid(uid); break;
400 case OP_GPWENT:
401 retptr = getpwent(); break;
402 default:
403 break;
404 }
405 }
406 }
407 break;
408#endif
409#ifdef USE_GETPROTOENT_BUFFER
410 case OP_GPBYNAME:
411 case OP_GPBYNUMBER:
412 case OP_GPROTOENT:
413 {
414 if (PL_reentrant_buffer->_getprotoent_size <= REENTRANTHALFMAXSIZE) {
415 PL_reentrant_buffer->_getprotoent_size *= 2;
416 Renew(PL_reentrant_buffer->_getprotoent_buffer,
417 PL_reentrant_buffer->_getprotoent_size, char);
418 switch (PL_op->op_type) {
419 case OP_GPBYNAME:
420 p0 = va_arg(ap, void *);
421 retptr = getprotobyname(p0); break;
422 case OP_GPBYNUMBER:
423 anint = va_arg(ap, int);
424 retptr = getprotobynumber(anint); break;
425 case OP_GPROTOENT:
426 retptr = getprotoent(); break;
427 default:
428 break;
429 }
430 }
431 }
432 break;
433#endif
434#ifdef USE_GETSERVENT_BUFFER
435 case OP_GSBYNAME:
436 case OP_GSBYPORT:
437 case OP_GSERVENT:
438 {
439 if (PL_reentrant_buffer->_getservent_size <= REENTRANTHALFMAXSIZE) {
440 PL_reentrant_buffer->_getservent_size *= 2;
441 Renew(PL_reentrant_buffer->_getservent_buffer,
442 PL_reentrant_buffer->_getservent_size, char);
443 switch (PL_op->op_type) {
444 case OP_GSBYNAME:
445 p0 = va_arg(ap, void *);
446 p1 = va_arg(ap, void *);
447 retptr = getservbyname(p0, p1); break;
448 case OP_GSBYPORT:
449 anint = va_arg(ap, int);
450 p0 = va_arg(ap, void *);
451 retptr = getservbyport(anint, p0); break;
452 case OP_GSERVENT:
453 retptr = getservent(); break;
454 default:
455 break;
456 }
457 }
458 }
459 break;
460#endif
461 default:
462 /* Not known how to retry, so just fail. */
463 break;
464 }
465
466 va_end(ap);
467#endif
468 return retptr;
469}
470