1*e0680481Safresh1 /* -*- mode: C; buffer-read-only: t -*-
252bd00bfSmillert *
355745691Smillert * reentr.c
455745691Smillert *
5850e2753Smillert * Copyright (C) 2002, 2003, 2005, 2006, 2007 by Larry Wall and others
655745691Smillert *
755745691Smillert * You may distribute under the terms of either the GNU General Public
855745691Smillert * License or the Artistic License, as specified in the README file.
955745691Smillert *
1055745691Smillert * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
11898184e3Ssthen * This file is built by regen/reentr.pl from data in regen/reentr.pl.
12898184e3Ssthen * Any changes made here will be lost!
13b8851fccSafresh1 */
14b8851fccSafresh1
15b8851fccSafresh1 /*
1655745691Smillert * "Saruman," I said, standing away from him, "only one hand at a time can
1755745691Smillert * wield the One, and you know that well, so do not trouble to say we!"
1855745691Smillert *
19b8851fccSafresh1 * [p.260 of _The Lord of the Rings_, II/ii: "The Council of Elrond"]
20b8851fccSafresh1 */
21b8851fccSafresh1
22b8851fccSafresh1 /*
235b2d2359Smillert * This file contains a collection of automatically created wrappers
245b2d2359Smillert * (created by running reentr.pl) for reentrant (thread-safe) versions of
255b2d2359Smillert * various library calls, such as getpwent_r. The wrapping is done so
265b2d2359Smillert * that other files like pp_sys.c calling those library functions need not
275b2d2359Smillert * care about the differences between various platforms' idiosyncrasies
285b2d2359Smillert * regarding these reentrant interfaces.
2955745691Smillert */
3055745691Smillert
3155745691Smillert #include "EXTERN.h"
3255745691Smillert #define PERL_IN_REENTR_C
3355745691Smillert #include "perl.h"
3455745691Smillert #include "reentr.h"
3556d68f1eSafresh1 #include "keywords.h"
3655745691Smillert
379f11ffb7Safresh1 #define RenewDouble(data_pointer, size_pointer, type) \
389f11ffb7Safresh1 STMT_START { \
39eac174f2Safresh1 const size_t size = MAX(*(size_pointer), 1) * 2; \
409f11ffb7Safresh1 Renew((data_pointer), (size), type); \
419f11ffb7Safresh1 *(size_pointer) = size; \
429f11ffb7Safresh1 } STMT_END
439f11ffb7Safresh1
4455745691Smillert void
Perl_reentrant_size(pTHX)4555745691Smillert Perl_reentrant_size(pTHX) {
46b8851fccSafresh1 PERL_UNUSED_CONTEXT;
4756d68f1eSafresh1
4856d68f1eSafresh1 /* Set the sizes of the reentrant buffers */
4956d68f1eSafresh1
5055745691Smillert #ifdef USE_REENTRANT_API
5155745691Smillert # define REENTRANTSMALLSIZE 256 /* Make something up. */
5255745691Smillert # define REENTRANTUSUALSIZE 4096 /* Make something up. */
5356d68f1eSafresh1
5455745691Smillert # ifdef HAS_ASCTIME_R
55eac174f2Safresh1 PL_reentrant_buffer->_asctime_size = 26;
5655745691Smillert # endif /* HAS_ASCTIME_R */
5756d68f1eSafresh1
5855745691Smillert # ifdef HAS_CRYPT_R
5955745691Smillert # endif /* HAS_CRYPT_R */
6056d68f1eSafresh1
6155745691Smillert # ifdef HAS_CTIME_R
62eac174f2Safresh1 PL_reentrant_buffer->_ctime_size = 26;
6355745691Smillert # endif /* HAS_CTIME_R */
6456d68f1eSafresh1
6555745691Smillert # ifdef HAS_GETGRNAM_R
6685009909Smillert # if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
6785009909Smillert PL_reentrant_buffer->_grent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
68850e2753Smillert if (PL_reentrant_buffer->_grent_size == (size_t) -1)
6985009909Smillert PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
709f11ffb7Safresh1 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
7155745691Smillert PL_reentrant_buffer->_grent_size = SIABUFSIZ;
729f11ffb7Safresh1 # elif defined(__sgi)
7355745691Smillert PL_reentrant_buffer->_grent_size = BUFSIZ;
7455745691Smillert # else
7555745691Smillert PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
7655745691Smillert # endif
7755745691Smillert # endif /* HAS_GETGRNAM_R */
7856d68f1eSafresh1
7955745691Smillert # ifdef HAS_GETHOSTBYNAME_R
8055745691Smillert # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
8155745691Smillert PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE;
8255745691Smillert # endif
8355745691Smillert # endif /* HAS_GETHOSTBYNAME_R */
8456d68f1eSafresh1
8555745691Smillert # ifdef HAS_GETLOGIN_R
8655745691Smillert PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
8755745691Smillert # endif /* HAS_GETLOGIN_R */
8856d68f1eSafresh1
8955745691Smillert # ifdef HAS_GETNETBYNAME_R
9055745691Smillert # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
9155745691Smillert PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE;
9255745691Smillert # endif
9355745691Smillert # endif /* HAS_GETNETBYNAME_R */
9456d68f1eSafresh1
9555745691Smillert # ifdef HAS_GETPROTOBYNAME_R
9655745691Smillert # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
9755745691Smillert PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE;
9855745691Smillert # endif
9955745691Smillert # endif /* HAS_GETPROTOBYNAME_R */
10056d68f1eSafresh1
10155745691Smillert # ifdef HAS_GETPWNAM_R
10255745691Smillert # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
10355745691Smillert PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
104850e2753Smillert if (PL_reentrant_buffer->_pwent_size == (size_t) -1)
10555745691Smillert PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
1069f11ffb7Safresh1 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
10755745691Smillert PL_reentrant_buffer->_pwent_size = SIABUFSIZ;
1089f11ffb7Safresh1 # elif defined(__sgi)
10955745691Smillert PL_reentrant_buffer->_pwent_size = BUFSIZ;
11055745691Smillert # else
11155745691Smillert PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
11255745691Smillert # endif
11355745691Smillert # endif /* HAS_GETPWNAM_R */
11456d68f1eSafresh1
11555745691Smillert # ifdef HAS_GETSERVBYNAME_R
11655745691Smillert # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
11755745691Smillert PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE;
11855745691Smillert # endif
11955745691Smillert # endif /* HAS_GETSERVBYNAME_R */
12056d68f1eSafresh1
12155745691Smillert # ifdef HAS_GETSPNAM_R
12255745691Smillert # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
12355745691Smillert PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
124850e2753Smillert if (PL_reentrant_buffer->_spent_size == (size_t) -1)
12585009909Smillert PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
1269f11ffb7Safresh1 # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
12755745691Smillert PL_reentrant_buffer->_spent_size = SIABUFSIZ;
1289f11ffb7Safresh1 # elif defined(__sgi)
12955745691Smillert PL_reentrant_buffer->_spent_size = BUFSIZ;
13055745691Smillert # else
13155745691Smillert PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
13255745691Smillert # endif
13355745691Smillert # endif /* HAS_GETSPNAM_R */
13456d68f1eSafresh1
13556d68f1eSafresh1 # ifdef HAS_GMTIME_R
13656d68f1eSafresh1 # endif /* HAS_GMTIME_R */
13756d68f1eSafresh1
13856d68f1eSafresh1 # ifdef HAS_LOCALTIME_R
13956d68f1eSafresh1 # endif /* HAS_LOCALTIME_R */
14056d68f1eSafresh1
14155745691Smillert # ifdef HAS_READDIR_R
14255745691Smillert /* This is the size Solaris recommends.
14355745691Smillert * (though we go static, should use pathconf() instead) */
14455745691Smillert PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
14555745691Smillert # endif /* HAS_READDIR_R */
14656d68f1eSafresh1
14755745691Smillert # ifdef HAS_READDIR64_R
14855745691Smillert /* This is the size Solaris recommends.
14955745691Smillert * (though we go static, should use pathconf() instead) */
15055745691Smillert PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
15155745691Smillert # endif /* HAS_READDIR64_R */
15256d68f1eSafresh1
15355745691Smillert # ifdef HAS_SETLOCALE_R
15455745691Smillert PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
15555745691Smillert # endif /* HAS_SETLOCALE_R */
15656d68f1eSafresh1
15755745691Smillert # ifdef HAS_STRERROR_R
15855745691Smillert PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
15955745691Smillert # endif /* HAS_STRERROR_R */
16056d68f1eSafresh1
16155745691Smillert # ifdef HAS_TTYNAME_R
16255745691Smillert PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
16355745691Smillert # endif /* HAS_TTYNAME_R */
16455745691Smillert
16556d68f1eSafresh1
16655745691Smillert #endif /* USE_REENTRANT_API */
16756d68f1eSafresh1
16855745691Smillert }
16955745691Smillert
17055745691Smillert void
Perl_reentrant_init(pTHX)17155745691Smillert Perl_reentrant_init(pTHX) {
172b8851fccSafresh1 PERL_UNUSED_CONTEXT;
17356d68f1eSafresh1
17456d68f1eSafresh1 /* Initialize the whole thing */
17556d68f1eSafresh1
17655745691Smillert #ifdef USE_REENTRANT_API
17756d68f1eSafresh1
17852bd00bfSmillert Newx(PL_reentrant_buffer, 1, REENTR);
17955745691Smillert Perl_reentrant_size(aTHX);
18056d68f1eSafresh1
18155745691Smillert # ifdef HAS_ASCTIME_R
18252bd00bfSmillert Newx(PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
18355745691Smillert # endif /* HAS_ASCTIME_R */
18456d68f1eSafresh1
18555745691Smillert # ifdef HAS_CRYPT_R
18685009909Smillert # if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
18785009909Smillert PL_reentrant_buffer->_crypt_struct_buffer = 0;
18855745691Smillert # endif
18955745691Smillert # endif /* HAS_CRYPT_R */
19056d68f1eSafresh1
19155745691Smillert # ifdef HAS_CTIME_R
19252bd00bfSmillert Newx(PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
19355745691Smillert # endif /* HAS_CTIME_R */
19456d68f1eSafresh1
19555745691Smillert # ifdef HAS_GETGRNAM_R
19655745691Smillert # ifdef USE_GRENT_FPTR
19755745691Smillert PL_reentrant_buffer->_grent_fptr = NULL;
19855745691Smillert # endif
19952bd00bfSmillert Newx(PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char);
20055745691Smillert # endif /* HAS_GETGRNAM_R */
20156d68f1eSafresh1
20255745691Smillert # ifdef HAS_GETHOSTBYNAME_R
20355745691Smillert # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
20452bd00bfSmillert Newx(PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char);
20555745691Smillert # endif
20655745691Smillert # endif /* HAS_GETHOSTBYNAME_R */
20756d68f1eSafresh1
20855745691Smillert # ifdef HAS_GETLOGIN_R
20952bd00bfSmillert Newx(PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
21055745691Smillert # endif /* HAS_GETLOGIN_R */
21156d68f1eSafresh1
21255745691Smillert # ifdef HAS_GETNETBYNAME_R
21355745691Smillert # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
21452bd00bfSmillert Newx(PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char);
21555745691Smillert # endif
21655745691Smillert # endif /* HAS_GETNETBYNAME_R */
21756d68f1eSafresh1
21855745691Smillert # ifdef HAS_GETPROTOBYNAME_R
21955745691Smillert # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
22052bd00bfSmillert Newx(PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char);
22155745691Smillert # endif
22255745691Smillert # endif /* HAS_GETPROTOBYNAME_R */
22356d68f1eSafresh1
22455745691Smillert # ifdef HAS_GETPWNAM_R
22555745691Smillert # ifdef USE_PWENT_FPTR
22655745691Smillert PL_reentrant_buffer->_pwent_fptr = NULL;
22755745691Smillert # endif
22852bd00bfSmillert Newx(PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char);
22955745691Smillert # endif /* HAS_GETPWNAM_R */
23056d68f1eSafresh1
23155745691Smillert # ifdef HAS_GETSERVBYNAME_R
23255745691Smillert # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
23352bd00bfSmillert Newx(PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char);
23455745691Smillert # endif
23555745691Smillert # endif /* HAS_GETSERVBYNAME_R */
23656d68f1eSafresh1
23755745691Smillert # ifdef HAS_GETSPNAM_R
23855745691Smillert # ifdef USE_SPENT_FPTR
23955745691Smillert PL_reentrant_buffer->_spent_fptr = NULL;
24055745691Smillert # endif
24152bd00bfSmillert Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
24255745691Smillert # endif /* HAS_GETSPNAM_R */
24356d68f1eSafresh1
24456d68f1eSafresh1 # ifdef HAS_GMTIME_R
24556d68f1eSafresh1 # endif /* HAS_GMTIME_R */
24656d68f1eSafresh1
24756d68f1eSafresh1 # ifdef HAS_LOCALTIME_R
24856d68f1eSafresh1 # endif /* HAS_LOCALTIME_R */
24956d68f1eSafresh1
25055745691Smillert # ifdef HAS_READDIR_R
25155745691Smillert PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
25255745691Smillert # endif /* HAS_READDIR_R */
25356d68f1eSafresh1
25455745691Smillert # ifdef HAS_READDIR64_R
25555745691Smillert PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
25655745691Smillert # endif /* HAS_READDIR64_R */
25756d68f1eSafresh1
25855745691Smillert # ifdef HAS_SETLOCALE_R
25952bd00bfSmillert Newx(PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
26055745691Smillert # endif /* HAS_SETLOCALE_R */
26156d68f1eSafresh1
26255745691Smillert # ifdef HAS_STRERROR_R
26352bd00bfSmillert Newx(PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
26455745691Smillert # endif /* HAS_STRERROR_R */
26556d68f1eSafresh1
26655745691Smillert # ifdef HAS_TTYNAME_R
26752bd00bfSmillert Newx(PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
26855745691Smillert # endif /* HAS_TTYNAME_R */
26955745691Smillert
27056d68f1eSafresh1
27155745691Smillert #endif /* USE_REENTRANT_API */
27256d68f1eSafresh1
27355745691Smillert }
27455745691Smillert
27555745691Smillert void
Perl_reentrant_free(pTHX)27655745691Smillert Perl_reentrant_free(pTHX) {
277b8851fccSafresh1 PERL_UNUSED_CONTEXT;
27856d68f1eSafresh1
27956d68f1eSafresh1 /* Tear down */
28056d68f1eSafresh1
28155745691Smillert #ifdef USE_REENTRANT_API
28256d68f1eSafresh1
28355745691Smillert # ifdef HAS_ASCTIME_R
28455745691Smillert Safefree(PL_reentrant_buffer->_asctime_buffer);
28555745691Smillert # endif /* HAS_ASCTIME_R */
28656d68f1eSafresh1
28755745691Smillert # ifdef HAS_CRYPT_R
28885009909Smillert # if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
28985009909Smillert Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
29085009909Smillert # endif
29155745691Smillert # endif /* HAS_CRYPT_R */
29256d68f1eSafresh1
29355745691Smillert # ifdef HAS_CTIME_R
29455745691Smillert Safefree(PL_reentrant_buffer->_ctime_buffer);
29555745691Smillert # endif /* HAS_CTIME_R */
29656d68f1eSafresh1
29755745691Smillert # ifdef HAS_GETGRNAM_R
29855745691Smillert Safefree(PL_reentrant_buffer->_grent_buffer);
29955745691Smillert # endif /* HAS_GETGRNAM_R */
30056d68f1eSafresh1
30155745691Smillert # ifdef HAS_GETHOSTBYNAME_R
30255745691Smillert # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
30355745691Smillert Safefree(PL_reentrant_buffer->_hostent_buffer);
30455745691Smillert # endif
30555745691Smillert # endif /* HAS_GETHOSTBYNAME_R */
30656d68f1eSafresh1
30755745691Smillert # ifdef HAS_GETLOGIN_R
30855745691Smillert Safefree(PL_reentrant_buffer->_getlogin_buffer);
30955745691Smillert # endif /* HAS_GETLOGIN_R */
31056d68f1eSafresh1
31155745691Smillert # ifdef HAS_GETNETBYNAME_R
31255745691Smillert # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
31355745691Smillert Safefree(PL_reentrant_buffer->_netent_buffer);
31455745691Smillert # endif
31555745691Smillert # endif /* HAS_GETNETBYNAME_R */
31656d68f1eSafresh1
31755745691Smillert # ifdef HAS_GETPROTOBYNAME_R
31855745691Smillert # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
31955745691Smillert Safefree(PL_reentrant_buffer->_protoent_buffer);
32055745691Smillert # endif
32155745691Smillert # endif /* HAS_GETPROTOBYNAME_R */
32256d68f1eSafresh1
32355745691Smillert # ifdef HAS_GETPWNAM_R
32455745691Smillert Safefree(PL_reentrant_buffer->_pwent_buffer);
32555745691Smillert # endif /* HAS_GETPWNAM_R */
32656d68f1eSafresh1
32755745691Smillert # ifdef HAS_GETSERVBYNAME_R
32855745691Smillert # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
32955745691Smillert Safefree(PL_reentrant_buffer->_servent_buffer);
33055745691Smillert # endif
33155745691Smillert # endif /* HAS_GETSERVBYNAME_R */
33256d68f1eSafresh1
33355745691Smillert # ifdef HAS_GETSPNAM_R
33455745691Smillert Safefree(PL_reentrant_buffer->_spent_buffer);
33555745691Smillert # endif /* HAS_GETSPNAM_R */
33656d68f1eSafresh1
33756d68f1eSafresh1 # ifdef HAS_GMTIME_R
33856d68f1eSafresh1 # endif /* HAS_GMTIME_R */
33956d68f1eSafresh1
34056d68f1eSafresh1 # ifdef HAS_LOCALTIME_R
34156d68f1eSafresh1 # endif /* HAS_LOCALTIME_R */
34256d68f1eSafresh1
34355745691Smillert # ifdef HAS_READDIR_R
34455745691Smillert Safefree(PL_reentrant_buffer->_readdir_struct);
34555745691Smillert # endif /* HAS_READDIR_R */
34656d68f1eSafresh1
34755745691Smillert # ifdef HAS_READDIR64_R
34855745691Smillert Safefree(PL_reentrant_buffer->_readdir64_struct);
34955745691Smillert # endif /* HAS_READDIR64_R */
35056d68f1eSafresh1
35155745691Smillert # ifdef HAS_SETLOCALE_R
35255745691Smillert Safefree(PL_reentrant_buffer->_setlocale_buffer);
35355745691Smillert # endif /* HAS_SETLOCALE_R */
35456d68f1eSafresh1
35555745691Smillert # ifdef HAS_STRERROR_R
35655745691Smillert Safefree(PL_reentrant_buffer->_strerror_buffer);
35755745691Smillert # endif /* HAS_STRERROR_R */
35856d68f1eSafresh1
35955745691Smillert # ifdef HAS_TTYNAME_R
36055745691Smillert Safefree(PL_reentrant_buffer->_ttyname_buffer);
36155745691Smillert # endif /* HAS_TTYNAME_R */
36255745691Smillert
36356d68f1eSafresh1
36455745691Smillert Safefree(PL_reentrant_buffer);
36556d68f1eSafresh1
36655745691Smillert #endif /* USE_REENTRANT_API */
36755745691Smillert }
36855745691Smillert
36955745691Smillert void*
Perl_reentrant_retry(const char * f,...)37055745691Smillert Perl_reentrant_retry(const char *f, ...)
37155745691Smillert {
37256d68f1eSafresh1 /* This function is set up to be called if the normal function returns
37356d68f1eSafresh1 * failure with errno ERANGE, which indicates the buffer is too small.
37456d68f1eSafresh1 * This function calls the failing one again with a larger buffer.
37556d68f1eSafresh1 *
37656d68f1eSafresh1 * What has happened is that, due to the magic of C preprocessor macro
37756d68f1eSafresh1 * expansion, when the original code called function 'foo(args)', it was
37856d68f1eSafresh1 * instead compiled into something like a call of 'foo_r(args, buffer)'
37956d68f1eSafresh1 * Below we retry with 'foo', but the preprocessor has changed that into
38056d68f1eSafresh1 * 'foo_r', so this function will end up calling itself recursively, each
38156d68f1eSafresh1 * time with a larger buffer. If PERL_REENTRANT_MAXSIZE is defined, it
38256d68f1eSafresh1 * won't increase beyond that, instead failing. */
38356d68f1eSafresh1
38455745691Smillert void *retptr = NULL;
385850e2753Smillert va_list ap;
38656d68f1eSafresh1
38756d68f1eSafresh1 I32 key = 0;
38856d68f1eSafresh1
38943003dfeSmillert #ifdef USE_REENTRANT_API
39056d68f1eSafresh1
39191f110e0Safresh1 dTHX;
39256d68f1eSafresh1
39356d68f1eSafresh1 key = Perl_keyword (aTHX_ f, strlen(f), FALSE /* not feature enabled */);
39456d68f1eSafresh1
39543003dfeSmillert /* Easier to special case this here than in embed.pl. (Look at what it
39643003dfeSmillert generates for proto.h) */
39743003dfeSmillert PERL_ARGS_ASSERT_REENTRANT_RETRY;
39856d68f1eSafresh1
39955745691Smillert #endif
40055745691Smillert
40156d68f1eSafresh1 if (key == 0) {
40256d68f1eSafresh1
40356d68f1eSafresh1 #ifdef HAS_GETSPNAM_R
40456d68f1eSafresh1
40556d68f1eSafresh1 /* This is a #define as has no corresponding keyword */
40656d68f1eSafresh1 if (strEQ(f, "getspnam")) {
40756d68f1eSafresh1 key = KEY_getspnam;
40856d68f1eSafresh1 }
40956d68f1eSafresh1
41056d68f1eSafresh1 #endif
41156d68f1eSafresh1
41256d68f1eSafresh1 }
41356d68f1eSafresh1 else if (key < 0) {
41456d68f1eSafresh1 key = -key;
41556d68f1eSafresh1 }
41656d68f1eSafresh1
41756d68f1eSafresh1 va_start(ap, f);
41856d68f1eSafresh1
41956d68f1eSafresh1 #ifdef USE_REENTRANT_API
42056d68f1eSafresh1
42156d68f1eSafresh1 switch (key) {
42256d68f1eSafresh1
42355745691Smillert # ifdef USE_HOSTENT_BUFFER
42456d68f1eSafresh1
42556d68f1eSafresh1 case KEY_gethostbyaddr:
42656d68f1eSafresh1 case KEY_gethostbyname:
42756d68f1eSafresh1 case KEY_endhostent:
42855745691Smillert {
42956d68f1eSafresh1 char * host_addr;
43056d68f1eSafresh1 Size_t asize;
43156d68f1eSafresh1 char * host_name;
43256d68f1eSafresh1 int anint;
43356d68f1eSafresh1
43485009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
43585009909Smillert if (PL_reentrant_buffer->_hostent_size <=
43685009909Smillert PERL_REENTRANT_MAXSIZE / 2)
43785009909Smillert # endif
4389f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_hostent_buffer,
4399f11ffb7Safresh1 &PL_reentrant_buffer->_hostent_size, char);
44056d68f1eSafresh1 switch (key) {
44156d68f1eSafresh1 case KEY_gethostbyaddr:
44256d68f1eSafresh1 host_addr = va_arg(ap, char *);
44356d68f1eSafresh1 asize = va_arg(ap, Size_t);
44455745691Smillert anint = va_arg(ap, int);
44556d68f1eSafresh1 /* socklen_t is what Posix 2001 says this should be */
44656d68f1eSafresh1 retptr = gethostbyaddr(host_addr, (socklen_t) asize, anint); break;
44756d68f1eSafresh1 case KEY_gethostbyname:
44856d68f1eSafresh1 host_name = va_arg(ap, char *);
44956d68f1eSafresh1 retptr = gethostbyname(host_name); break;
45056d68f1eSafresh1 case KEY_endhostent:
45155745691Smillert retptr = gethostent(); break;
45255745691Smillert default:
45385009909Smillert SETERRNO(ERANGE, LIB_INVARG);
45455745691Smillert break;
45555745691Smillert }
45655745691Smillert }
45755745691Smillert break;
45856d68f1eSafresh1
45955745691Smillert # endif
46055745691Smillert # ifdef USE_GRENT_BUFFER
46156d68f1eSafresh1
46256d68f1eSafresh1 case KEY_getgrent:
46356d68f1eSafresh1 case KEY_getgrgid:
46456d68f1eSafresh1 case KEY_getgrnam:
46555745691Smillert {
46656d68f1eSafresh1 char * name;
46756d68f1eSafresh1 Gid_t gid;
46856d68f1eSafresh1
46985009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
47085009909Smillert if (PL_reentrant_buffer->_grent_size <=
47185009909Smillert PERL_REENTRANT_MAXSIZE / 2)
47285009909Smillert # endif
4739f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_grent_buffer,
4749f11ffb7Safresh1 &PL_reentrant_buffer->_grent_size, char);
47556d68f1eSafresh1 switch (key) {
47656d68f1eSafresh1 case KEY_getgrnam:
47756d68f1eSafresh1 name = va_arg(ap, char *);
47856d68f1eSafresh1 retptr = getgrnam(name); break;
47956d68f1eSafresh1 case KEY_getgrgid:
48085009909Smillert # if Gid_t_size < INTSIZE
48185009909Smillert gid = (Gid_t)va_arg(ap, int);
48285009909Smillert # else
48355745691Smillert gid = va_arg(ap, Gid_t);
48485009909Smillert # endif
48555745691Smillert retptr = getgrgid(gid); break;
48656d68f1eSafresh1 case KEY_getgrent:
48755745691Smillert retptr = getgrent(); break;
48855745691Smillert default:
48985009909Smillert SETERRNO(ERANGE, LIB_INVARG);
49055745691Smillert break;
49155745691Smillert }
49255745691Smillert }
49355745691Smillert break;
49456d68f1eSafresh1
49555745691Smillert # endif
49655745691Smillert # ifdef USE_NETENT_BUFFER
49756d68f1eSafresh1
49856d68f1eSafresh1 case KEY_getnetbyaddr:
49956d68f1eSafresh1 case KEY_getnetbyname:
50056d68f1eSafresh1 case KEY_getnetent:
50155745691Smillert {
50256d68f1eSafresh1 char * name;
50356d68f1eSafresh1 Netdb_net_t net;
50456d68f1eSafresh1 int anint;
50556d68f1eSafresh1
50685009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
50785009909Smillert if (PL_reentrant_buffer->_netent_size <=
50885009909Smillert PERL_REENTRANT_MAXSIZE / 2)
50985009909Smillert # endif
5109f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_netent_buffer,
5119f11ffb7Safresh1 &PL_reentrant_buffer->_netent_size, char);
51256d68f1eSafresh1 switch (key) {
51356d68f1eSafresh1 case KEY_getnetbyaddr:
51455745691Smillert net = va_arg(ap, Netdb_net_t);
51555745691Smillert anint = va_arg(ap, int);
51655745691Smillert retptr = getnetbyaddr(net, anint); break;
51756d68f1eSafresh1 case KEY_getnetbyname:
51856d68f1eSafresh1 name = va_arg(ap, char *);
51956d68f1eSafresh1 retptr = getnetbyname(name); break;
52056d68f1eSafresh1 case KEY_getnetent:
52155745691Smillert retptr = getnetent(); break;
52255745691Smillert default:
52385009909Smillert SETERRNO(ERANGE, LIB_INVARG);
52455745691Smillert break;
52555745691Smillert }
52655745691Smillert }
52755745691Smillert break;
52856d68f1eSafresh1
52955745691Smillert # endif
53055745691Smillert # ifdef USE_PWENT_BUFFER
53156d68f1eSafresh1
53256d68f1eSafresh1 case KEY_getpwnam:
53356d68f1eSafresh1 case KEY_getpwuid:
53456d68f1eSafresh1 case KEY_getpwent:
53555745691Smillert {
53656d68f1eSafresh1 Uid_t uid;
53756d68f1eSafresh1 char * name;
53856d68f1eSafresh1
53985009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
54085009909Smillert if (PL_reentrant_buffer->_pwent_size <=
54185009909Smillert PERL_REENTRANT_MAXSIZE / 2)
54256d68f1eSafresh1
54385009909Smillert # endif
5449f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_pwent_buffer,
5459f11ffb7Safresh1 &PL_reentrant_buffer->_pwent_size, char);
54656d68f1eSafresh1 switch (key) {
54756d68f1eSafresh1 case KEY_getpwnam:
54856d68f1eSafresh1 name = va_arg(ap, char *);
54956d68f1eSafresh1 retptr = getpwnam(name); break;
55056d68f1eSafresh1 case KEY_getpwuid:
55156d68f1eSafresh1
55285009909Smillert # if Uid_t_size < INTSIZE
55385009909Smillert uid = (Uid_t)va_arg(ap, int);
55485009909Smillert # else
55555745691Smillert uid = va_arg(ap, Uid_t);
55685009909Smillert # endif
55755745691Smillert retptr = getpwuid(uid); break;
55856d68f1eSafresh1
5596fb12b70Safresh1 # if defined(HAS_GETPWENT) || defined(HAS_GETPWENT_R)
56056d68f1eSafresh1
56156d68f1eSafresh1 case KEY_getpwent:
56255745691Smillert retptr = getpwent(); break;
5636fb12b70Safresh1 # endif
56455745691Smillert default:
56585009909Smillert SETERRNO(ERANGE, LIB_INVARG);
56655745691Smillert break;
56755745691Smillert }
56855745691Smillert }
56956d68f1eSafresh1 break;
57056d68f1eSafresh1
57156d68f1eSafresh1 # endif
57256d68f1eSafresh1 # ifdef USE_SPENT_BUFFER
57356d68f1eSafresh1
57456d68f1eSafresh1 case KEY_getspnam:
57556d68f1eSafresh1 {
57656d68f1eSafresh1 char * name;
57756d68f1eSafresh1
57856d68f1eSafresh1 # ifdef PERL_REENTRANT_MAXSIZE
57956d68f1eSafresh1 if (PL_reentrant_buffer->_spent_size <=
58056d68f1eSafresh1 PERL_REENTRANT_MAXSIZE / 2)
58156d68f1eSafresh1
58256d68f1eSafresh1 # endif
58356d68f1eSafresh1 RenewDouble(PL_reentrant_buffer->_spent_buffer,
58456d68f1eSafresh1 &PL_reentrant_buffer->_spent_size, char);
58556d68f1eSafresh1 switch (key) {
58656d68f1eSafresh1 case KEY_getspnam:
58756d68f1eSafresh1 name = va_arg(ap, char *);
58856d68f1eSafresh1 retptr = getspnam(name); break;
58956d68f1eSafresh1 default:
59056d68f1eSafresh1 SETERRNO(ERANGE, LIB_INVARG);
59156d68f1eSafresh1 break;
59256d68f1eSafresh1 }
59355745691Smillert }
59455745691Smillert break;
59556d68f1eSafresh1
59655745691Smillert # endif
59755745691Smillert # ifdef USE_PROTOENT_BUFFER
59856d68f1eSafresh1
59956d68f1eSafresh1 case KEY_getprotobyname:
60056d68f1eSafresh1 case KEY_getprotobynumber:
60156d68f1eSafresh1 case KEY_getprotoent:
60255745691Smillert {
60356d68f1eSafresh1 char * name;
60456d68f1eSafresh1 int anint;
60556d68f1eSafresh1
60685009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
60785009909Smillert if (PL_reentrant_buffer->_protoent_size <=
60885009909Smillert PERL_REENTRANT_MAXSIZE / 2)
60985009909Smillert # endif
6109f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_protoent_buffer,
6119f11ffb7Safresh1 &PL_reentrant_buffer->_protoent_size, char);
61256d68f1eSafresh1 switch (key) {
61356d68f1eSafresh1 case KEY_getprotobyname:
61456d68f1eSafresh1 name = va_arg(ap, char *);
61556d68f1eSafresh1 retptr = getprotobyname(name); break;
61656d68f1eSafresh1 case KEY_getprotobynumber:
61755745691Smillert anint = va_arg(ap, int);
61855745691Smillert retptr = getprotobynumber(anint); break;
61956d68f1eSafresh1 case KEY_getprotoent:
62055745691Smillert retptr = getprotoent(); break;
62155745691Smillert default:
62285009909Smillert SETERRNO(ERANGE, LIB_INVARG);
62355745691Smillert break;
62455745691Smillert }
62555745691Smillert }
62655745691Smillert break;
62756d68f1eSafresh1
62855745691Smillert # endif
62955745691Smillert # ifdef USE_SERVENT_BUFFER
63056d68f1eSafresh1
63156d68f1eSafresh1 case KEY_getservbyname:
63256d68f1eSafresh1 case KEY_getservbyport:
63356d68f1eSafresh1 case KEY_getservent:
63455745691Smillert {
63556d68f1eSafresh1 char * name;
63656d68f1eSafresh1 char * proto;
63756d68f1eSafresh1 int anint;
63856d68f1eSafresh1
63985009909Smillert # ifdef PERL_REENTRANT_MAXSIZE
64085009909Smillert if (PL_reentrant_buffer->_servent_size <=
64185009909Smillert PERL_REENTRANT_MAXSIZE / 2)
64285009909Smillert # endif
6439f11ffb7Safresh1 RenewDouble(PL_reentrant_buffer->_servent_buffer,
6449f11ffb7Safresh1 &PL_reentrant_buffer->_servent_size, char);
64556d68f1eSafresh1 switch (key) {
64656d68f1eSafresh1 case KEY_getservbyname:
64756d68f1eSafresh1 name = va_arg(ap, char *);
64856d68f1eSafresh1 proto = va_arg(ap, char *);
64956d68f1eSafresh1 retptr = getservbyname(name, proto); break;
65056d68f1eSafresh1 case KEY_getservbyport:
65155745691Smillert anint = va_arg(ap, int);
65256d68f1eSafresh1 name = va_arg(ap, char *);
65356d68f1eSafresh1 retptr = getservbyport(anint, name); break;
65456d68f1eSafresh1 case KEY_getservent:
65555745691Smillert retptr = getservent(); break;
65655745691Smillert default:
65785009909Smillert SETERRNO(ERANGE, LIB_INVARG);
65855745691Smillert break;
65955745691Smillert }
66055745691Smillert }
66155745691Smillert break;
66256d68f1eSafresh1
66355745691Smillert # endif
66456d68f1eSafresh1
66555745691Smillert default:
66655745691Smillert /* Not known how to retry, so just fail. */
66755745691Smillert break;
66855745691Smillert }
66956d68f1eSafresh1
670850e2753Smillert #else
67156d68f1eSafresh1
672850e2753Smillert PERL_UNUSED_ARG(f);
67356d68f1eSafresh1
67455745691Smillert #endif
67556d68f1eSafresh1
676850e2753Smillert va_end(ap);
67755745691Smillert return retptr;
67855745691Smillert }
67955745691Smillert
680*e0680481Safresh1 /* ex: set ro ft=c: */
681