source: vendor/perl/5.8.8/reentr.c@ 3181

Last change on this file since 3181 was 3181, checked in by bird, 18 years ago

perl 5.8.8

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