This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
ext/POSIX/t/posix.t -- neuter final test on VOS
[perl5.git] / reentr.c
CommitLineData
10bc17b6
JH
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
SR
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
JH
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
JH
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
SR
40 if (PL_reentrant_buffer->_getgrent_size == -1)
41 PL_reentrant_buffer->_getgrent_size = REENTRANTUSUALSIZE;
10bc17b6
JH
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
JH
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
JH
57#endif
58#endif /* HAS_GETHOSTBYNAME_R */
59#ifdef HAS_GETLOGIN_R
8695fa85 60 PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
10bc17b6
JH
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
JH
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
JH
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);
8695fa85
SR
75 if (PL_reentrant_buffer->_getgrent_size == -1)
76 PL_reentrant_buffer->_getgrent_size = REENTRANTUSUALSIZE;
10bc17b6
JH
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
JH
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
JH
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
JH
115#endif /* HAS_SETLOCALE_R */
116#ifdef HAS_STRERROR_R
8695fa85 117 PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
10bc17b6
JH
118#endif /* HAS_STRERROR_R */
119#ifdef HAS_TTYNAME_R
8695fa85 120 PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
10bc17b6
JH
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
JH
278void*
279Perl_reentrant_retry(const char *f, ...)
280{
281 dTHX;
282 void *retptr = NULL;
283#ifdef USE_REENTRANT_API
284 void *p0, *p1;
285 size_t asize;
286 int anint;
287 va_list ap;
288
289 va_start(ap, f);
290
291#define REENTRANTHALFMAXSIZE 32768 /* The maximum may end up twice this. */
292
293 switch (PL_op->op_type) {
294#ifdef USE_GETHOSTENT_BUFFER
295 case OP_GHBYADDR:
296 case OP_GHBYNAME:
297 case OP_GHOSTENT:
298 {
299 if (PL_reentrant_buffer->_gethostent_size <= REENTRANTHALFMAXSIZE) {
300 PL_reentrant_buffer->_gethostent_size *= 2;
301 Renew(PL_reentrant_buffer->_gethostent_buffer,
302 PL_reentrant_buffer->_gethostent_size, char);
303 switch (PL_op->op_type) {
304 case OP_GHBYADDR:
305 p0 = va_arg(ap, void *);
306 asize = va_arg(ap, size_t);
307 anint = va_arg(ap, int);
308 retptr = gethostbyaddr(p0, asize, anint); break;
309 case OP_GHBYNAME:
310 p0 = va_arg(ap, void *);
311 retptr = gethostbyname(p0); break;
312 case OP_GHOSTENT:
313 retptr = gethostent(); break;
314 default:
315 break;
316 }
317 }
318 }
319 break;
320#endif
321#ifdef USE_GETGRENT_BUFFER
322 case OP_GGRNAM:
323 case OP_GGRGID:
324 case OP_GGRENT:
325 {
326 if (PL_reentrant_buffer->_getgrent_size <= REENTRANTHALFMAXSIZE) {
327 Gid_t gid;
328 PL_reentrant_buffer->_getgrent_size *= 2;
329 Renew(PL_reentrant_buffer->_getgrent_buffer,
330 PL_reentrant_buffer->_getgrent_size, char);
331 switch (PL_op->op_type) {
332 case OP_GGRNAM:
333 p0 = va_arg(ap, void *);
334 retptr = getgrnam(p0); break;
335 case OP_GGRGID:
336 gid = va_arg(ap, Gid_t);
337 retptr = getgrgid(gid); break;
338 case OP_GGRENT:
339 retptr = getgrent(); break;
340 default:
341 break;
342 }
343 }
344 }
345 break;
346#endif
347#ifdef USE_GETNETENT_BUFFER
348 case OP_GNBYADDR:
349 case OP_GNBYNAME:
350 case OP_GNETENT:
351 {
352 if (PL_reentrant_buffer->_getnetent_size <= REENTRANTHALFMAXSIZE) {
353 Netdb_net_t net;
354 PL_reentrant_buffer->_getnetent_size *= 2;
355 Renew(PL_reentrant_buffer->_getnetent_buffer,
356 PL_reentrant_buffer->_getnetent_size, char);
357 switch (PL_op->op_type) {
358 case OP_GNBYADDR:
359 net = va_arg(ap, Netdb_net_t);
360 anint = va_arg(ap, int);
361 retptr = getnetbyaddr(net, anint); break;
362 case OP_GNBYNAME:
363 p0 = va_arg(ap, void *);
364 retptr = getnetbyname(p0); break;
365 case OP_GNETENT:
366 retptr = getnetent(); break;
367 default:
368 break;
369 }
370 }
371 }
372 break;
373#endif
374#ifdef USE_GETPWENT_BUFFER
375 case OP_GPWNAM:
376 case OP_GPWUID:
377 case OP_GPWENT:
378 {
379 if (PL_reentrant_buffer->_getpwent_size <= REENTRANTHALFMAXSIZE) {
380 Uid_t uid;
381 PL_reentrant_buffer->_getpwent_size *= 2;
382 Renew(PL_reentrant_buffer->_getpwent_buffer,
383 PL_reentrant_buffer->_getpwent_size, char);
384 switch (PL_op->op_type) {
385 case OP_GPWNAM:
386 p0 = va_arg(ap, void *);
387 retptr = getpwnam(p0); break;
388 case OP_GPWUID:
389 uid = va_arg(ap, Uid_t);
390 retptr = getpwuid(uid); break;
391 case OP_GPWENT:
392 retptr = getpwent(); break;
393 default:
394 break;
395 }
396 }
397 }
398 break;
399#endif
400#ifdef USE_GETPROTOENT_BUFFER
401 case OP_GPBYNAME:
402 case OP_GPBYNUMBER:
403 case OP_GPROTOENT:
404 {
405 if (PL_reentrant_buffer->_getprotoent_size <= REENTRANTHALFMAXSIZE) {
406 PL_reentrant_buffer->_getprotoent_size *= 2;
407 Renew(PL_reentrant_buffer->_getprotoent_buffer,
408 PL_reentrant_buffer->_getprotoent_size, char);
409 switch (PL_op->op_type) {
410 case OP_GPBYNAME:
411 p0 = va_arg(ap, void *);
412 retptr = getprotobyname(p0); break;
413 case OP_GPBYNUMBER:
414 anint = va_arg(ap, int);
415 retptr = getprotobynumber(anint); break;
416 case OP_GPROTOENT:
417 retptr = getprotoent(); break;
418 default:
419 break;
420 }
421 }
422 }
423 break;
424#endif
425#ifdef USE_GETSERVENT_BUFFER
426 case OP_GSBYNAME:
427 case OP_GSBYPORT:
428 case OP_GSERVENT:
429 {
430 if (PL_reentrant_buffer->_getservent_size <= REENTRANTHALFMAXSIZE) {
431 PL_reentrant_buffer->_getservent_size *= 2;
432 Renew(PL_reentrant_buffer->_getservent_buffer,
433 PL_reentrant_buffer->_getservent_size, char);
434 switch (PL_op->op_type) {
435 case OP_GSBYNAME:
436 p0 = va_arg(ap, void *);
437 p1 = va_arg(ap, void *);
438 retptr = getservbyname(p0, p1); break;
439 case OP_GSBYPORT:
440 anint = va_arg(ap, int);
441 p0 = va_arg(ap, void *);
442 retptr = getservbyport(anint, p0); break;
443 case OP_GSERVENT:
444 retptr = getservent(); break;
445 default:
446 break;
447 }
448 }
449 }
450 break;
451#endif
452 default:
453 /* Not known how to retry, so just fail. */
454 break;
455 }
456
457 va_end(ap);
458#endif
459 return retptr;
460}
461