This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regexec.c: Fix some EBCDIC problems
[perl5.git] / reentr.c
... / ...
CommitLineData
1/* -*- buffer-read-only: t -*-
2 *
3 * reentr.c
4 *
5 * Copyright (C) 2002, 2003, 2005, 2006, 2007 by Larry Wall and others
6 *
7 * You may distribute under the terms of either the GNU General Public
8 * License or the Artistic License, as specified in the README file.
9 *
10 * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
11 * This file is built by regen/reentr.pl from data in regen/reentr.pl.
12 * Any changes made here will be lost!
13 *
14 * "Saruman," I said, standing away from him, "only one hand at a time can
15 * wield the One, and you know that well, so do not trouble to say we!"
16 *
17 * This file contains a collection of automatically created wrappers
18 * (created by running reentr.pl) for reentrant (thread-safe) versions of
19 * various library calls, such as getpwent_r. The wrapping is done so
20 * that other files like pp_sys.c calling those library functions need not
21 * care about the differences between various platforms' idiosyncrasies
22 * regarding these reentrant interfaces.
23 */
24
25#include "EXTERN.h"
26#define PERL_IN_REENTR_C
27#include "perl.h"
28#include "reentr.h"
29
30void
31Perl_reentrant_size(pTHX) {
32#ifdef USE_REENTRANT_API
33#define REENTRANTSMALLSIZE 256 /* Make something up. */
34#define REENTRANTUSUALSIZE 4096 /* Make something up. */
35#ifdef HAS_ASCTIME_R
36 PL_reentrant_buffer->_asctime_size = REENTRANTSMALLSIZE;
37#endif /* HAS_ASCTIME_R */
38#ifdef HAS_CRYPT_R
39#endif /* HAS_CRYPT_R */
40#ifdef HAS_CTIME_R
41 PL_reentrant_buffer->_ctime_size = REENTRANTSMALLSIZE;
42#endif /* HAS_CTIME_R */
43#ifdef HAS_GETGRNAM_R
44# if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
45 PL_reentrant_buffer->_grent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
46 if (PL_reentrant_buffer->_grent_size == (size_t) -1)
47 PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
48# else
49# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
50 PL_reentrant_buffer->_grent_size = SIABUFSIZ;
51# else
52# ifdef __sgi
53 PL_reentrant_buffer->_grent_size = BUFSIZ;
54# else
55 PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
56# endif
57# endif
58# endif
59#endif /* HAS_GETGRNAM_R */
60#ifdef HAS_GETHOSTBYNAME_R
61#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
62 PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE;
63#endif
64#endif /* HAS_GETHOSTBYNAME_R */
65#ifdef HAS_GETLOGIN_R
66 PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
67#endif /* HAS_GETLOGIN_R */
68#ifdef HAS_GETNETBYNAME_R
69#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
70 PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE;
71#endif
72#endif /* HAS_GETNETBYNAME_R */
73#ifdef HAS_GETPROTOBYNAME_R
74#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
75 PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE;
76#endif
77#endif /* HAS_GETPROTOBYNAME_R */
78#ifdef HAS_GETPWNAM_R
79# if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
80 PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
81 if (PL_reentrant_buffer->_pwent_size == (size_t) -1)
82 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
83# else
84# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
85 PL_reentrant_buffer->_pwent_size = SIABUFSIZ;
86# else
87# ifdef __sgi
88 PL_reentrant_buffer->_pwent_size = BUFSIZ;
89# else
90 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
91# endif
92# endif
93# endif
94#endif /* HAS_GETPWNAM_R */
95#ifdef HAS_GETSERVBYNAME_R
96#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
97 PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE;
98#endif
99#endif /* HAS_GETSERVBYNAME_R */
100#ifdef HAS_GETSPNAM_R
101# if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
102 PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
103 if (PL_reentrant_buffer->_spent_size == (size_t) -1)
104 PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
105# else
106# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
107 PL_reentrant_buffer->_spent_size = SIABUFSIZ;
108# else
109# ifdef __sgi
110 PL_reentrant_buffer->_spent_size = BUFSIZ;
111# else
112 PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
113# endif
114# endif
115# endif
116#endif /* HAS_GETSPNAM_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
128 PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
129#endif /* HAS_SETLOCALE_R */
130#ifdef HAS_STRERROR_R
131 PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
132#endif /* HAS_STRERROR_R */
133#ifdef HAS_TTYNAME_R
134 PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
135#endif /* HAS_TTYNAME_R */
136
137#endif /* USE_REENTRANT_API */
138}
139
140void
141Perl_reentrant_init(pTHX) {
142#ifdef USE_REENTRANT_API
143 Newx(PL_reentrant_buffer, 1, REENTR);
144 Perl_reentrant_size(aTHX);
145#ifdef HAS_ASCTIME_R
146 Newx(PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
147#endif /* HAS_ASCTIME_R */
148#ifdef HAS_CRYPT_R
149#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
150 PL_reentrant_buffer->_crypt_struct_buffer = 0;
151#endif
152#endif /* HAS_CRYPT_R */
153#ifdef HAS_CTIME_R
154 Newx(PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
155#endif /* HAS_CTIME_R */
156#ifdef HAS_GETGRNAM_R
157# ifdef USE_GRENT_FPTR
158 PL_reentrant_buffer->_grent_fptr = NULL;
159# endif
160 Newx(PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char);
161#endif /* HAS_GETGRNAM_R */
162#ifdef HAS_GETHOSTBYNAME_R
163#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
164 Newx(PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char);
165#endif
166#endif /* HAS_GETHOSTBYNAME_R */
167#ifdef HAS_GETLOGIN_R
168 Newx(PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
169#endif /* HAS_GETLOGIN_R */
170#ifdef HAS_GETNETBYNAME_R
171#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
172 Newx(PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char);
173#endif
174#endif /* HAS_GETNETBYNAME_R */
175#ifdef HAS_GETPROTOBYNAME_R
176#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
177 Newx(PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char);
178#endif
179#endif /* HAS_GETPROTOBYNAME_R */
180#ifdef HAS_GETPWNAM_R
181# ifdef USE_PWENT_FPTR
182 PL_reentrant_buffer->_pwent_fptr = NULL;
183# endif
184 Newx(PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char);
185#endif /* HAS_GETPWNAM_R */
186#ifdef HAS_GETSERVBYNAME_R
187#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
188 Newx(PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char);
189#endif
190#endif /* HAS_GETSERVBYNAME_R */
191#ifdef HAS_GETSPNAM_R
192# ifdef USE_SPENT_FPTR
193 PL_reentrant_buffer->_spent_fptr = NULL;
194# endif
195 Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
196#endif /* HAS_GETSPNAM_R */
197#ifdef HAS_READDIR_R
198 PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
199#endif /* HAS_READDIR_R */
200#ifdef HAS_READDIR64_R
201 PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
202#endif /* HAS_READDIR64_R */
203#ifdef HAS_SETLOCALE_R
204 Newx(PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
205#endif /* HAS_SETLOCALE_R */
206#ifdef HAS_STRERROR_R
207 Newx(PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
208#endif /* HAS_STRERROR_R */
209#ifdef HAS_TTYNAME_R
210 Newx(PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
211#endif /* HAS_TTYNAME_R */
212
213#endif /* USE_REENTRANT_API */
214}
215
216void
217Perl_reentrant_free(pTHX) {
218#ifdef USE_REENTRANT_API
219#ifdef HAS_ASCTIME_R
220 Safefree(PL_reentrant_buffer->_asctime_buffer);
221#endif /* HAS_ASCTIME_R */
222#ifdef HAS_CRYPT_R
223#if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
224 Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
225#endif
226#endif /* HAS_CRYPT_R */
227#ifdef HAS_CTIME_R
228 Safefree(PL_reentrant_buffer->_ctime_buffer);
229#endif /* HAS_CTIME_R */
230#ifdef HAS_GETGRNAM_R
231 Safefree(PL_reentrant_buffer->_grent_buffer);
232#endif /* HAS_GETGRNAM_R */
233#ifdef HAS_GETHOSTBYNAME_R
234#if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
235 Safefree(PL_reentrant_buffer->_hostent_buffer);
236#endif
237#endif /* HAS_GETHOSTBYNAME_R */
238#ifdef HAS_GETLOGIN_R
239 Safefree(PL_reentrant_buffer->_getlogin_buffer);
240#endif /* HAS_GETLOGIN_R */
241#ifdef HAS_GETNETBYNAME_R
242#if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
243 Safefree(PL_reentrant_buffer->_netent_buffer);
244#endif
245#endif /* HAS_GETNETBYNAME_R */
246#ifdef HAS_GETPROTOBYNAME_R
247#if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
248 Safefree(PL_reentrant_buffer->_protoent_buffer);
249#endif
250#endif /* HAS_GETPROTOBYNAME_R */
251#ifdef HAS_GETPWNAM_R
252 Safefree(PL_reentrant_buffer->_pwent_buffer);
253#endif /* HAS_GETPWNAM_R */
254#ifdef HAS_GETSERVBYNAME_R
255#if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
256 Safefree(PL_reentrant_buffer->_servent_buffer);
257#endif
258#endif /* HAS_GETSERVBYNAME_R */
259#ifdef HAS_GETSPNAM_R
260 Safefree(PL_reentrant_buffer->_spent_buffer);
261#endif /* HAS_GETSPNAM_R */
262#ifdef HAS_READDIR_R
263 Safefree(PL_reentrant_buffer->_readdir_struct);
264#endif /* HAS_READDIR_R */
265#ifdef HAS_READDIR64_R
266 Safefree(PL_reentrant_buffer->_readdir64_struct);
267#endif /* HAS_READDIR64_R */
268#ifdef HAS_SETLOCALE_R
269 Safefree(PL_reentrant_buffer->_setlocale_buffer);
270#endif /* HAS_SETLOCALE_R */
271#ifdef HAS_STRERROR_R
272 Safefree(PL_reentrant_buffer->_strerror_buffer);
273#endif /* HAS_STRERROR_R */
274#ifdef HAS_TTYNAME_R
275 Safefree(PL_reentrant_buffer->_ttyname_buffer);
276#endif /* HAS_TTYNAME_R */
277
278 Safefree(PL_reentrant_buffer);
279#endif /* USE_REENTRANT_API */
280}
281
282void*
283Perl_reentrant_retry(const char *f, ...)
284{
285 void *retptr = NULL;
286 va_list ap;
287#ifdef USE_REENTRANT_API
288 dTHX;
289 /* Easier to special case this here than in embed.pl. (Look at what it
290 generates for proto.h) */
291 PERL_ARGS_ASSERT_REENTRANT_RETRY;
292#endif
293 va_start(ap, f);
294 {
295#ifdef USE_REENTRANT_API
296# if defined(USE_HOSTENT_BUFFER) || defined(USE_GRENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PWENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SERVENT_BUFFER)
297 void *p0;
298# endif
299# if defined(USE_SERVENT_BUFFER)
300 void *p1;
301# endif
302# if defined(USE_HOSTENT_BUFFER)
303 size_t asize;
304# endif
305# if defined(USE_HOSTENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SERVENT_BUFFER)
306 int anint;
307# endif
308
309 switch (PL_op->op_type) {
310#ifdef USE_HOSTENT_BUFFER
311 case OP_GHBYADDR:
312 case OP_GHBYNAME:
313 case OP_GHOSTENT:
314 {
315#ifdef PERL_REENTRANT_MAXSIZE
316 if (PL_reentrant_buffer->_hostent_size <=
317 PERL_REENTRANT_MAXSIZE / 2)
318#endif
319 {
320 PL_reentrant_buffer->_hostent_size *= 2;
321 Renew(PL_reentrant_buffer->_hostent_buffer,
322 PL_reentrant_buffer->_hostent_size, char);
323 switch (PL_op->op_type) {
324 case OP_GHBYADDR:
325 p0 = va_arg(ap, void *);
326 asize = va_arg(ap, size_t);
327 anint = va_arg(ap, int);
328 retptr = gethostbyaddr(p0, asize, anint); break;
329 case OP_GHBYNAME:
330 p0 = va_arg(ap, void *);
331 retptr = gethostbyname((char *)p0); break;
332 case OP_GHOSTENT:
333 retptr = gethostent(); break;
334 default:
335 SETERRNO(ERANGE, LIB_INVARG);
336 break;
337 }
338 }
339 }
340 break;
341#endif
342#ifdef USE_GRENT_BUFFER
343 case OP_GGRNAM:
344 case OP_GGRGID:
345 case OP_GGRENT:
346 {
347#ifdef PERL_REENTRANT_MAXSIZE
348 if (PL_reentrant_buffer->_grent_size <=
349 PERL_REENTRANT_MAXSIZE / 2)
350#endif
351 {
352 Gid_t gid;
353 PL_reentrant_buffer->_grent_size *= 2;
354 Renew(PL_reentrant_buffer->_grent_buffer,
355 PL_reentrant_buffer->_grent_size, char);
356 switch (PL_op->op_type) {
357 case OP_GGRNAM:
358 p0 = va_arg(ap, void *);
359 retptr = getgrnam((char *)p0); break;
360 case OP_GGRGID:
361#if Gid_t_size < INTSIZE
362 gid = (Gid_t)va_arg(ap, int);
363#else
364 gid = va_arg(ap, Gid_t);
365#endif
366 retptr = getgrgid(gid); break;
367 case OP_GGRENT:
368 retptr = getgrent(); break;
369 default:
370 SETERRNO(ERANGE, LIB_INVARG);
371 break;
372 }
373 }
374 }
375 break;
376#endif
377#ifdef USE_NETENT_BUFFER
378 case OP_GNBYADDR:
379 case OP_GNBYNAME:
380 case OP_GNETENT:
381 {
382#ifdef PERL_REENTRANT_MAXSIZE
383 if (PL_reentrant_buffer->_netent_size <=
384 PERL_REENTRANT_MAXSIZE / 2)
385#endif
386 {
387 Netdb_net_t net;
388 PL_reentrant_buffer->_netent_size *= 2;
389 Renew(PL_reentrant_buffer->_netent_buffer,
390 PL_reentrant_buffer->_netent_size, char);
391 switch (PL_op->op_type) {
392 case OP_GNBYADDR:
393 net = va_arg(ap, Netdb_net_t);
394 anint = va_arg(ap, int);
395 retptr = getnetbyaddr(net, anint); break;
396 case OP_GNBYNAME:
397 p0 = va_arg(ap, void *);
398 retptr = getnetbyname((char *)p0); break;
399 case OP_GNETENT:
400 retptr = getnetent(); break;
401 default:
402 SETERRNO(ERANGE, LIB_INVARG);
403 break;
404 }
405 }
406 }
407 break;
408#endif
409#ifdef USE_PWENT_BUFFER
410 case OP_GPWNAM:
411 case OP_GPWUID:
412 case OP_GPWENT:
413 {
414#ifdef PERL_REENTRANT_MAXSIZE
415 if (PL_reentrant_buffer->_pwent_size <=
416 PERL_REENTRANT_MAXSIZE / 2)
417#endif
418 {
419 Uid_t uid;
420 PL_reentrant_buffer->_pwent_size *= 2;
421 Renew(PL_reentrant_buffer->_pwent_buffer,
422 PL_reentrant_buffer->_pwent_size, char);
423 switch (PL_op->op_type) {
424 case OP_GPWNAM:
425 p0 = va_arg(ap, void *);
426 retptr = getpwnam((char *)p0); break;
427 case OP_GPWUID:
428#if Uid_t_size < INTSIZE
429 uid = (Uid_t)va_arg(ap, int);
430#else
431 uid = va_arg(ap, Uid_t);
432#endif
433 retptr = getpwuid(uid); break;
434#if defined(HAS_GETPWENT) || defined(HAS_GETPWENT_R)
435 case OP_GPWENT:
436 retptr = getpwent(); break;
437#endif
438 default:
439 SETERRNO(ERANGE, LIB_INVARG);
440 break;
441 }
442 }
443 }
444 break;
445#endif
446#ifdef USE_PROTOENT_BUFFER
447 case OP_GPBYNAME:
448 case OP_GPBYNUMBER:
449 case OP_GPROTOENT:
450 {
451#ifdef PERL_REENTRANT_MAXSIZE
452 if (PL_reentrant_buffer->_protoent_size <=
453 PERL_REENTRANT_MAXSIZE / 2)
454#endif
455 {
456 PL_reentrant_buffer->_protoent_size *= 2;
457 Renew(PL_reentrant_buffer->_protoent_buffer,
458 PL_reentrant_buffer->_protoent_size, char);
459 switch (PL_op->op_type) {
460 case OP_GPBYNAME:
461 p0 = va_arg(ap, void *);
462 retptr = getprotobyname((char *)p0); break;
463 case OP_GPBYNUMBER:
464 anint = va_arg(ap, int);
465 retptr = getprotobynumber(anint); break;
466 case OP_GPROTOENT:
467 retptr = getprotoent(); break;
468 default:
469 SETERRNO(ERANGE, LIB_INVARG);
470 break;
471 }
472 }
473 }
474 break;
475#endif
476#ifdef USE_SERVENT_BUFFER
477 case OP_GSBYNAME:
478 case OP_GSBYPORT:
479 case OP_GSERVENT:
480 {
481#ifdef PERL_REENTRANT_MAXSIZE
482 if (PL_reentrant_buffer->_servent_size <=
483 PERL_REENTRANT_MAXSIZE / 2)
484#endif
485 {
486 PL_reentrant_buffer->_servent_size *= 2;
487 Renew(PL_reentrant_buffer->_servent_buffer,
488 PL_reentrant_buffer->_servent_size, char);
489 switch (PL_op->op_type) {
490 case OP_GSBYNAME:
491 p0 = va_arg(ap, void *);
492 p1 = va_arg(ap, void *);
493 retptr = getservbyname((char *)p0, (char *)p1); break;
494 case OP_GSBYPORT:
495 anint = va_arg(ap, int);
496 p0 = va_arg(ap, void *);
497 retptr = getservbyport(anint, (char *)p0); break;
498 case OP_GSERVENT:
499 retptr = getservent(); break;
500 default:
501 SETERRNO(ERANGE, LIB_INVARG);
502 break;
503 }
504 }
505 }
506 break;
507#endif
508 default:
509 /* Not known how to retry, so just fail. */
510 break;
511 }
512#else
513 PERL_UNUSED_ARG(f);
514#endif
515 }
516 va_end(ap);
517 return retptr;
518}
519
520/* ex: set ro: */