1 /* -*- buffer-read-only: t -*-
5 * Copyright (C) 2002, 2003, 2005, 2006, 2007 by Larry Wall and others
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.
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!
16 * "Saruman," I said, standing away from him, "only one hand at a time can
17 * wield the One, and you know that well, so do not trouble to say we!"
19 * [p.260 of _The Lord of the Rings_, II/ii: "The Council of Elrond"]
23 * This file contains a collection of automatically created wrappers
24 * (created by running reentr.pl) for reentrant (thread-safe) versions of
25 * various library calls, such as getpwent_r. The wrapping is done so
26 * that other files like pp_sys.c calling those library functions need not
27 * care about the differences between various platforms' idiosyncrasies
28 * regarding these reentrant interfaces.
32 #define PERL_IN_REENTR_C
36 #define RenewDouble(data_pointer, size_pointer, type) \
38 const size_t size = *(size_pointer) * 2; \
39 Renew((data_pointer), (size), type); \
40 *(size_pointer) = size; \
44 Perl_reentrant_size(pTHX) {
47 /* Set the sizes of the reentrant buffers */
49 #ifdef USE_REENTRANT_API
50 #define REENTRANTSMALLSIZE 256 /* Make something up. */
51 #define REENTRANTUSUALSIZE 4096 /* Make something up. */
53 PL_reentrant_buffer->_asctime_size = REENTRANTSMALLSIZE;
54 #endif /* HAS_ASCTIME_R */
56 #endif /* HAS_CRYPT_R */
58 PL_reentrant_buffer->_ctime_size = REENTRANTSMALLSIZE;
59 #endif /* HAS_CTIME_R */
61 # if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
62 PL_reentrant_buffer->_grent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
63 if (PL_reentrant_buffer->_grent_size == (size_t) -1)
64 PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
65 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
66 PL_reentrant_buffer->_grent_size = SIABUFSIZ;
68 PL_reentrant_buffer->_grent_size = BUFSIZ;
70 PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
72 #endif /* HAS_GETGRNAM_R */
73 #ifdef HAS_GETHOSTBYNAME_R
74 #if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
75 PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE;
77 #endif /* HAS_GETHOSTBYNAME_R */
79 PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
80 #endif /* HAS_GETLOGIN_R */
81 #ifdef HAS_GETNETBYNAME_R
82 #if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
83 PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE;
85 #endif /* HAS_GETNETBYNAME_R */
86 #ifdef HAS_GETPROTOBYNAME_R
87 #if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
88 PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE;
90 #endif /* HAS_GETPROTOBYNAME_R */
92 # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
93 PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
94 if (PL_reentrant_buffer->_pwent_size == (size_t) -1)
95 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
96 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
97 PL_reentrant_buffer->_pwent_size = SIABUFSIZ;
99 PL_reentrant_buffer->_pwent_size = BUFSIZ;
101 PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
103 #endif /* HAS_GETPWNAM_R */
104 #ifdef HAS_GETSERVBYNAME_R
105 #if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
106 PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE;
108 #endif /* HAS_GETSERVBYNAME_R */
109 #ifdef HAS_GETSPNAM_R
110 # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
111 PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
112 if (PL_reentrant_buffer->_spent_size == (size_t) -1)
113 PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
114 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
115 PL_reentrant_buffer->_spent_size = SIABUFSIZ;
116 # elif defined(__sgi)
117 PL_reentrant_buffer->_spent_size = BUFSIZ;
119 PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
121 #endif /* HAS_GETSPNAM_R */
123 /* This is the size Solaris recommends.
124 * (though we go static, should use pathconf() instead) */
125 PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
126 #endif /* HAS_READDIR_R */
127 #ifdef HAS_READDIR64_R
128 /* This is the size Solaris recommends.
129 * (though we go static, should use pathconf() instead) */
130 PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
131 #endif /* HAS_READDIR64_R */
132 #ifdef HAS_SETLOCALE_R
133 PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
134 #endif /* HAS_SETLOCALE_R */
135 #ifdef HAS_STRERROR_R
136 PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
137 #endif /* HAS_STRERROR_R */
139 PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
140 #endif /* HAS_TTYNAME_R */
142 #endif /* USE_REENTRANT_API */
146 Perl_reentrant_init(pTHX) {
149 /* Initialize the whole thing */
151 #ifdef USE_REENTRANT_API
152 Newx(PL_reentrant_buffer, 1, REENTR);
153 Perl_reentrant_size(aTHX);
155 Newx(PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
156 #endif /* HAS_ASCTIME_R */
158 #if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
159 PL_reentrant_buffer->_crypt_struct_buffer = 0;
161 #endif /* HAS_CRYPT_R */
163 Newx(PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
164 #endif /* HAS_CTIME_R */
165 #ifdef HAS_GETGRNAM_R
166 # ifdef USE_GRENT_FPTR
167 PL_reentrant_buffer->_grent_fptr = NULL;
169 Newx(PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char);
170 #endif /* HAS_GETGRNAM_R */
171 #ifdef HAS_GETHOSTBYNAME_R
172 #if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
173 Newx(PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char);
175 #endif /* HAS_GETHOSTBYNAME_R */
176 #ifdef HAS_GETLOGIN_R
177 Newx(PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
178 #endif /* HAS_GETLOGIN_R */
179 #ifdef HAS_GETNETBYNAME_R
180 #if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
181 Newx(PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char);
183 #endif /* HAS_GETNETBYNAME_R */
184 #ifdef HAS_GETPROTOBYNAME_R
185 #if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
186 Newx(PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char);
188 #endif /* HAS_GETPROTOBYNAME_R */
189 #ifdef HAS_GETPWNAM_R
190 # ifdef USE_PWENT_FPTR
191 PL_reentrant_buffer->_pwent_fptr = NULL;
193 Newx(PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char);
194 #endif /* HAS_GETPWNAM_R */
195 #ifdef HAS_GETSERVBYNAME_R
196 #if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
197 Newx(PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char);
199 #endif /* HAS_GETSERVBYNAME_R */
200 #ifdef HAS_GETSPNAM_R
201 # ifdef USE_SPENT_FPTR
202 PL_reentrant_buffer->_spent_fptr = NULL;
204 Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
205 #endif /* HAS_GETSPNAM_R */
207 PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
208 #endif /* HAS_READDIR_R */
209 #ifdef HAS_READDIR64_R
210 PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
211 #endif /* HAS_READDIR64_R */
212 #ifdef HAS_SETLOCALE_R
213 Newx(PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
214 #endif /* HAS_SETLOCALE_R */
215 #ifdef HAS_STRERROR_R
216 Newx(PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
217 #endif /* HAS_STRERROR_R */
219 Newx(PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
220 #endif /* HAS_TTYNAME_R */
222 #endif /* USE_REENTRANT_API */
226 Perl_reentrant_free(pTHX) {
231 #ifdef USE_REENTRANT_API
233 Safefree(PL_reentrant_buffer->_asctime_buffer);
234 #endif /* HAS_ASCTIME_R */
236 #if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
237 Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
239 #endif /* HAS_CRYPT_R */
241 Safefree(PL_reentrant_buffer->_ctime_buffer);
242 #endif /* HAS_CTIME_R */
243 #ifdef HAS_GETGRNAM_R
244 Safefree(PL_reentrant_buffer->_grent_buffer);
245 #endif /* HAS_GETGRNAM_R */
246 #ifdef HAS_GETHOSTBYNAME_R
247 #if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
248 Safefree(PL_reentrant_buffer->_hostent_buffer);
250 #endif /* HAS_GETHOSTBYNAME_R */
251 #ifdef HAS_GETLOGIN_R
252 Safefree(PL_reentrant_buffer->_getlogin_buffer);
253 #endif /* HAS_GETLOGIN_R */
254 #ifdef HAS_GETNETBYNAME_R
255 #if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
256 Safefree(PL_reentrant_buffer->_netent_buffer);
258 #endif /* HAS_GETNETBYNAME_R */
259 #ifdef HAS_GETPROTOBYNAME_R
260 #if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
261 Safefree(PL_reentrant_buffer->_protoent_buffer);
263 #endif /* HAS_GETPROTOBYNAME_R */
264 #ifdef HAS_GETPWNAM_R
265 Safefree(PL_reentrant_buffer->_pwent_buffer);
266 #endif /* HAS_GETPWNAM_R */
267 #ifdef HAS_GETSERVBYNAME_R
268 #if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
269 Safefree(PL_reentrant_buffer->_servent_buffer);
271 #endif /* HAS_GETSERVBYNAME_R */
272 #ifdef HAS_GETSPNAM_R
273 Safefree(PL_reentrant_buffer->_spent_buffer);
274 #endif /* HAS_GETSPNAM_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 */
288 Safefree(PL_reentrant_buffer->_ttyname_buffer);
289 #endif /* HAS_TTYNAME_R */
291 Safefree(PL_reentrant_buffer);
292 #endif /* USE_REENTRANT_API */
296 Perl_reentrant_retry(const char *f, ...)
298 /* This function is set up to be called if the normal function returns
299 * failure with errno ERANGE, which indicates the buffer is too small.
300 * This function calls the failing one again with a larger buffer.
302 * What has happened is that, due to the magic of C preprocessor macro
303 * expansion, when the original code called function 'foo(args)', it was
304 * instead compiled into something like a call of 'foo_r(args, buffer)'
305 * Below we retry with 'foo', but the preprocessor has changed that into
306 * 'foo_r', so this function will end up calling itself recursively, each
307 * time with a larger buffer. If PERL_REENTRANT_MAXSIZE is defined, it
308 * won't increase beyond that, instead failing. */
312 #ifdef USE_REENTRANT_API
314 /* Easier to special case this here than in embed.pl. (Look at what it
315 generates for proto.h) */
316 PERL_ARGS_ASSERT_REENTRANT_RETRY;
320 #ifdef USE_REENTRANT_API
321 # 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)
324 # if defined(USE_SERVENT_BUFFER)
327 # if defined(USE_HOSTENT_BUFFER)
330 # if defined(USE_HOSTENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SERVENT_BUFFER)
334 switch (PL_op->op_type) {
335 #ifdef USE_HOSTENT_BUFFER
340 #ifdef PERL_REENTRANT_MAXSIZE
341 if (PL_reentrant_buffer->_hostent_size <=
342 PERL_REENTRANT_MAXSIZE / 2)
345 RenewDouble(PL_reentrant_buffer->_hostent_buffer,
346 &PL_reentrant_buffer->_hostent_size, char);
347 switch (PL_op->op_type) {
349 p0 = va_arg(ap, void *);
350 asize = va_arg(ap, size_t);
351 anint = va_arg(ap, int);
352 retptr = gethostbyaddr((Netdb_host_t) p0, (Netdb_hlen_t) asize, anint); break;
354 p0 = va_arg(ap, void *);
355 retptr = gethostbyname((Netdb_name_t) p0); break;
357 retptr = gethostent(); break;
359 SETERRNO(ERANGE, LIB_INVARG);
366 #ifdef USE_GRENT_BUFFER
371 #ifdef PERL_REENTRANT_MAXSIZE
372 if (PL_reentrant_buffer->_grent_size <=
373 PERL_REENTRANT_MAXSIZE / 2)
377 RenewDouble(PL_reentrant_buffer->_grent_buffer,
378 &PL_reentrant_buffer->_grent_size, char);
379 switch (PL_op->op_type) {
381 p0 = va_arg(ap, void *);
382 retptr = getgrnam((char *)p0); break;
384 #if Gid_t_size < INTSIZE
385 gid = (Gid_t)va_arg(ap, int);
387 gid = va_arg(ap, Gid_t);
389 retptr = getgrgid(gid); break;
391 retptr = getgrent(); break;
393 SETERRNO(ERANGE, LIB_INVARG);
400 #ifdef USE_NETENT_BUFFER
405 #ifdef PERL_REENTRANT_MAXSIZE
406 if (PL_reentrant_buffer->_netent_size <=
407 PERL_REENTRANT_MAXSIZE / 2)
411 RenewDouble(PL_reentrant_buffer->_netent_buffer,
412 &PL_reentrant_buffer->_netent_size, char);
413 switch (PL_op->op_type) {
415 net = va_arg(ap, Netdb_net_t);
416 anint = va_arg(ap, int);
417 retptr = getnetbyaddr(net, anint); break;
419 p0 = va_arg(ap, void *);
420 retptr = getnetbyname((char *)p0); break;
422 retptr = getnetent(); break;
424 SETERRNO(ERANGE, LIB_INVARG);
431 #ifdef USE_PWENT_BUFFER
436 #ifdef PERL_REENTRANT_MAXSIZE
437 if (PL_reentrant_buffer->_pwent_size <=
438 PERL_REENTRANT_MAXSIZE / 2)
442 RenewDouble(PL_reentrant_buffer->_pwent_buffer,
443 &PL_reentrant_buffer->_pwent_size, char);
444 switch (PL_op->op_type) {
446 p0 = va_arg(ap, void *);
447 retptr = getpwnam((char *)p0); break;
449 #if Uid_t_size < INTSIZE
450 uid = (Uid_t)va_arg(ap, int);
452 uid = va_arg(ap, Uid_t);
454 retptr = getpwuid(uid); break;
455 #if defined(HAS_GETPWENT) || defined(HAS_GETPWENT_R)
457 retptr = getpwent(); break;
460 SETERRNO(ERANGE, LIB_INVARG);
467 #ifdef USE_PROTOENT_BUFFER
472 #ifdef PERL_REENTRANT_MAXSIZE
473 if (PL_reentrant_buffer->_protoent_size <=
474 PERL_REENTRANT_MAXSIZE / 2)
477 RenewDouble(PL_reentrant_buffer->_protoent_buffer,
478 &PL_reentrant_buffer->_protoent_size, char);
479 switch (PL_op->op_type) {
481 p0 = va_arg(ap, void *);
482 retptr = getprotobyname((char *)p0); break;
484 anint = va_arg(ap, int);
485 retptr = getprotobynumber(anint); break;
487 retptr = getprotoent(); break;
489 SETERRNO(ERANGE, LIB_INVARG);
496 #ifdef USE_SERVENT_BUFFER
501 #ifdef PERL_REENTRANT_MAXSIZE
502 if (PL_reentrant_buffer->_servent_size <=
503 PERL_REENTRANT_MAXSIZE / 2)
506 RenewDouble(PL_reentrant_buffer->_servent_buffer,
507 &PL_reentrant_buffer->_servent_size, char);
508 switch (PL_op->op_type) {
510 p0 = va_arg(ap, void *);
511 p1 = va_arg(ap, void *);
512 retptr = getservbyname((char *)p0, (char *)p1); break;
514 anint = va_arg(ap, int);
515 p0 = va_arg(ap, void *);
516 retptr = getservbyport(anint, (char *)p0); break;
518 retptr = getservent(); break;
520 SETERRNO(ERANGE, LIB_INVARG);
528 /* Not known how to retry, so just fail. */