| 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 | |
| 15 | /* |
| 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!" |
| 18 | * |
| 19 | * [p.260 of _The Lord of the Rings_, II/ii: "The Council of Elrond"] |
| 20 | */ |
| 21 | |
| 22 | /* |
| 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. |
| 29 | */ |
| 30 | |
| 31 | #include "EXTERN.h" |
| 32 | #define PERL_IN_REENTR_C |
| 33 | #include "perl.h" |
| 34 | #include "reentr.h" |
| 35 | #include "keywords.h" |
| 36 | |
| 37 | #define RenewDouble(data_pointer, size_pointer, type) \ |
| 38 | STMT_START { \ |
| 39 | const size_t size = MAX(*(size_pointer), 1) * 2; \ |
| 40 | Renew((data_pointer), (size), type); \ |
| 41 | *(size_pointer) = size; \ |
| 42 | } STMT_END |
| 43 | |
| 44 | void |
| 45 | Perl_reentrant_size(pTHX) { |
| 46 | PERL_UNUSED_CONTEXT; |
| 47 | |
| 48 | /* Set the sizes of the reentrant buffers */ |
| 49 | |
| 50 | #ifdef USE_REENTRANT_API |
| 51 | # define REENTRANTSMALLSIZE 256 /* Make something up. */ |
| 52 | # define REENTRANTUSUALSIZE 4096 /* Make something up. */ |
| 53 | |
| 54 | # ifdef HAS_ASCTIME_R |
| 55 | PL_reentrant_buffer->_asctime_size = 26; |
| 56 | # endif /* HAS_ASCTIME_R */ |
| 57 | |
| 58 | # ifdef HAS_CRYPT_R |
| 59 | # endif /* HAS_CRYPT_R */ |
| 60 | |
| 61 | # ifdef HAS_CTIME_R |
| 62 | PL_reentrant_buffer->_ctime_size = 26; |
| 63 | # endif /* HAS_CTIME_R */ |
| 64 | |
| 65 | # ifdef HAS_GETGRNAM_R |
| 66 | # if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__) |
| 67 | PL_reentrant_buffer->_grent_size = sysconf(_SC_GETGR_R_SIZE_MAX); |
| 68 | if (PL_reentrant_buffer->_grent_size == (size_t) -1) |
| 69 | PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE; |
| 70 | # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ) |
| 71 | PL_reentrant_buffer->_grent_size = SIABUFSIZ; |
| 72 | # elif defined(__sgi) |
| 73 | PL_reentrant_buffer->_grent_size = BUFSIZ; |
| 74 | # else |
| 75 | PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE; |
| 76 | # endif |
| 77 | # endif /* HAS_GETGRNAM_R */ |
| 78 | |
| 79 | # ifdef HAS_GETHOSTBYNAME_R |
| 80 | # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 81 | PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE; |
| 82 | # endif |
| 83 | # endif /* HAS_GETHOSTBYNAME_R */ |
| 84 | |
| 85 | # ifdef HAS_GETLOGIN_R |
| 86 | PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE; |
| 87 | # endif /* HAS_GETLOGIN_R */ |
| 88 | |
| 89 | # ifdef HAS_GETNETBYNAME_R |
| 90 | # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 91 | PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE; |
| 92 | # endif |
| 93 | # endif /* HAS_GETNETBYNAME_R */ |
| 94 | |
| 95 | # ifdef HAS_GETPROTOBYNAME_R |
| 96 | # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 97 | PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE; |
| 98 | # endif |
| 99 | # endif /* HAS_GETPROTOBYNAME_R */ |
| 100 | |
| 101 | # ifdef HAS_GETPWNAM_R |
| 102 | # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__) |
| 103 | PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX); |
| 104 | if (PL_reentrant_buffer->_pwent_size == (size_t) -1) |
| 105 | PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE; |
| 106 | # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ) |
| 107 | PL_reentrant_buffer->_pwent_size = SIABUFSIZ; |
| 108 | # elif defined(__sgi) |
| 109 | PL_reentrant_buffer->_pwent_size = BUFSIZ; |
| 110 | # else |
| 111 | PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE; |
| 112 | # endif |
| 113 | # endif /* HAS_GETPWNAM_R */ |
| 114 | |
| 115 | # ifdef HAS_GETSERVBYNAME_R |
| 116 | # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD) |
| 117 | PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE; |
| 118 | # endif |
| 119 | # endif /* HAS_GETSERVBYNAME_R */ |
| 120 | |
| 121 | # ifdef HAS_GETSPNAM_R |
| 122 | # if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__) |
| 123 | PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX); |
| 124 | if (PL_reentrant_buffer->_spent_size == (size_t) -1) |
| 125 | PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE; |
| 126 | # elif defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ) |
| 127 | PL_reentrant_buffer->_spent_size = SIABUFSIZ; |
| 128 | # elif defined(__sgi) |
| 129 | PL_reentrant_buffer->_spent_size = BUFSIZ; |
| 130 | # else |
| 131 | PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE; |
| 132 | # endif |
| 133 | # endif /* HAS_GETSPNAM_R */ |
| 134 | |
| 135 | # ifdef HAS_GMTIME_R |
| 136 | # endif /* HAS_GMTIME_R */ |
| 137 | |
| 138 | # ifdef HAS_LOCALTIME_R |
| 139 | # endif /* HAS_LOCALTIME_R */ |
| 140 | |
| 141 | # ifdef HAS_READDIR_R |
| 142 | /* This is the size Solaris recommends. |
| 143 | * (though we go static, should use pathconf() instead) */ |
| 144 | PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1; |
| 145 | # endif /* HAS_READDIR_R */ |
| 146 | |
| 147 | # ifdef HAS_READDIR64_R |
| 148 | /* This is the size Solaris recommends. |
| 149 | * (though we go static, should use pathconf() instead) */ |
| 150 | PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1; |
| 151 | # endif /* HAS_READDIR64_R */ |
| 152 | |
| 153 | # ifdef HAS_SETLOCALE_R |
| 154 | PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE; |
| 155 | # endif /* HAS_SETLOCALE_R */ |
| 156 | |
| 157 | # ifdef HAS_STRERROR_R |
| 158 | PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE; |
| 159 | # endif /* HAS_STRERROR_R */ |
| 160 | |
| 161 | # ifdef HAS_TTYNAME_R |
| 162 | PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE; |
| 163 | # endif /* HAS_TTYNAME_R */ |
| 164 | |
| 165 | |
| 166 | #endif /* USE_REENTRANT_API */ |
| 167 | |
| 168 | } |
| 169 | |
| 170 | void |
| 171 | Perl_reentrant_init(pTHX) { |
| 172 | PERL_UNUSED_CONTEXT; |
| 173 | |
| 174 | /* Initialize the whole thing */ |
| 175 | |
| 176 | #ifdef USE_REENTRANT_API |
| 177 | |
| 178 | Newx(PL_reentrant_buffer, 1, REENTR); |
| 179 | Perl_reentrant_size(aTHX); |
| 180 | |
| 181 | # ifdef HAS_ASCTIME_R |
| 182 | Newx(PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char); |
| 183 | # endif /* HAS_ASCTIME_R */ |
| 184 | |
| 185 | # ifdef HAS_CRYPT_R |
| 186 | # if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD |
| 187 | PL_reentrant_buffer->_crypt_struct_buffer = 0; |
| 188 | # endif |
| 189 | # endif /* HAS_CRYPT_R */ |
| 190 | |
| 191 | # ifdef HAS_CTIME_R |
| 192 | Newx(PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char); |
| 193 | # endif /* HAS_CTIME_R */ |
| 194 | |
| 195 | # ifdef HAS_GETGRNAM_R |
| 196 | # ifdef USE_GRENT_FPTR |
| 197 | PL_reentrant_buffer->_grent_fptr = NULL; |
| 198 | # endif |
| 199 | Newx(PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char); |
| 200 | # endif /* HAS_GETGRNAM_R */ |
| 201 | |
| 202 | # ifdef HAS_GETHOSTBYNAME_R |
| 203 | # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 204 | Newx(PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char); |
| 205 | # endif |
| 206 | # endif /* HAS_GETHOSTBYNAME_R */ |
| 207 | |
| 208 | # ifdef HAS_GETLOGIN_R |
| 209 | Newx(PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char); |
| 210 | # endif /* HAS_GETLOGIN_R */ |
| 211 | |
| 212 | # ifdef HAS_GETNETBYNAME_R |
| 213 | # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 214 | Newx(PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char); |
| 215 | # endif |
| 216 | # endif /* HAS_GETNETBYNAME_R */ |
| 217 | |
| 218 | # ifdef HAS_GETPROTOBYNAME_R |
| 219 | # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 220 | Newx(PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char); |
| 221 | # endif |
| 222 | # endif /* HAS_GETPROTOBYNAME_R */ |
| 223 | |
| 224 | # ifdef HAS_GETPWNAM_R |
| 225 | # ifdef USE_PWENT_FPTR |
| 226 | PL_reentrant_buffer->_pwent_fptr = NULL; |
| 227 | # endif |
| 228 | Newx(PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char); |
| 229 | # endif /* HAS_GETPWNAM_R */ |
| 230 | |
| 231 | # ifdef HAS_GETSERVBYNAME_R |
| 232 | # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD) |
| 233 | Newx(PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char); |
| 234 | # endif |
| 235 | # endif /* HAS_GETSERVBYNAME_R */ |
| 236 | |
| 237 | # ifdef HAS_GETSPNAM_R |
| 238 | # ifdef USE_SPENT_FPTR |
| 239 | PL_reentrant_buffer->_spent_fptr = NULL; |
| 240 | # endif |
| 241 | Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char); |
| 242 | # endif /* HAS_GETSPNAM_R */ |
| 243 | |
| 244 | # ifdef HAS_GMTIME_R |
| 245 | # endif /* HAS_GMTIME_R */ |
| 246 | |
| 247 | # ifdef HAS_LOCALTIME_R |
| 248 | # endif /* HAS_LOCALTIME_R */ |
| 249 | |
| 250 | # ifdef HAS_READDIR_R |
| 251 | PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size); |
| 252 | # endif /* HAS_READDIR_R */ |
| 253 | |
| 254 | # ifdef HAS_READDIR64_R |
| 255 | PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size); |
| 256 | # endif /* HAS_READDIR64_R */ |
| 257 | |
| 258 | # ifdef HAS_SETLOCALE_R |
| 259 | Newx(PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char); |
| 260 | # endif /* HAS_SETLOCALE_R */ |
| 261 | |
| 262 | # ifdef HAS_STRERROR_R |
| 263 | Newx(PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char); |
| 264 | # endif /* HAS_STRERROR_R */ |
| 265 | |
| 266 | # ifdef HAS_TTYNAME_R |
| 267 | Newx(PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char); |
| 268 | # endif /* HAS_TTYNAME_R */ |
| 269 | |
| 270 | |
| 271 | #endif /* USE_REENTRANT_API */ |
| 272 | |
| 273 | } |
| 274 | |
| 275 | void |
| 276 | Perl_reentrant_free(pTHX) { |
| 277 | PERL_UNUSED_CONTEXT; |
| 278 | |
| 279 | /* Tear down */ |
| 280 | |
| 281 | #ifdef USE_REENTRANT_API |
| 282 | |
| 283 | # ifdef HAS_ASCTIME_R |
| 284 | Safefree(PL_reentrant_buffer->_asctime_buffer); |
| 285 | # endif /* HAS_ASCTIME_R */ |
| 286 | |
| 287 | # ifdef HAS_CRYPT_R |
| 288 | # if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD |
| 289 | Safefree(PL_reentrant_buffer->_crypt_struct_buffer); |
| 290 | # endif |
| 291 | # endif /* HAS_CRYPT_R */ |
| 292 | |
| 293 | # ifdef HAS_CTIME_R |
| 294 | Safefree(PL_reentrant_buffer->_ctime_buffer); |
| 295 | # endif /* HAS_CTIME_R */ |
| 296 | |
| 297 | # ifdef HAS_GETGRNAM_R |
| 298 | Safefree(PL_reentrant_buffer->_grent_buffer); |
| 299 | # endif /* HAS_GETGRNAM_R */ |
| 300 | |
| 301 | # ifdef HAS_GETHOSTBYNAME_R |
| 302 | # if !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 303 | Safefree(PL_reentrant_buffer->_hostent_buffer); |
| 304 | # endif |
| 305 | # endif /* HAS_GETHOSTBYNAME_R */ |
| 306 | |
| 307 | # ifdef HAS_GETLOGIN_R |
| 308 | Safefree(PL_reentrant_buffer->_getlogin_buffer); |
| 309 | # endif /* HAS_GETLOGIN_R */ |
| 310 | |
| 311 | # ifdef HAS_GETNETBYNAME_R |
| 312 | # if !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 313 | Safefree(PL_reentrant_buffer->_netent_buffer); |
| 314 | # endif |
| 315 | # endif /* HAS_GETNETBYNAME_R */ |
| 316 | |
| 317 | # ifdef HAS_GETPROTOBYNAME_R |
| 318 | # if !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD) |
| 319 | Safefree(PL_reentrant_buffer->_protoent_buffer); |
| 320 | # endif |
| 321 | # endif /* HAS_GETPROTOBYNAME_R */ |
| 322 | |
| 323 | # ifdef HAS_GETPWNAM_R |
| 324 | Safefree(PL_reentrant_buffer->_pwent_buffer); |
| 325 | # endif /* HAS_GETPWNAM_R */ |
| 326 | |
| 327 | # ifdef HAS_GETSERVBYNAME_R |
| 328 | # if !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD) |
| 329 | Safefree(PL_reentrant_buffer->_servent_buffer); |
| 330 | # endif |
| 331 | # endif /* HAS_GETSERVBYNAME_R */ |
| 332 | |
| 333 | # ifdef HAS_GETSPNAM_R |
| 334 | Safefree(PL_reentrant_buffer->_spent_buffer); |
| 335 | # endif /* HAS_GETSPNAM_R */ |
| 336 | |
| 337 | # ifdef HAS_GMTIME_R |
| 338 | # endif /* HAS_GMTIME_R */ |
| 339 | |
| 340 | # ifdef HAS_LOCALTIME_R |
| 341 | # endif /* HAS_LOCALTIME_R */ |
| 342 | |
| 343 | # ifdef HAS_READDIR_R |
| 344 | Safefree(PL_reentrant_buffer->_readdir_struct); |
| 345 | # endif /* HAS_READDIR_R */ |
| 346 | |
| 347 | # ifdef HAS_READDIR64_R |
| 348 | Safefree(PL_reentrant_buffer->_readdir64_struct); |
| 349 | # endif /* HAS_READDIR64_R */ |
| 350 | |
| 351 | # ifdef HAS_SETLOCALE_R |
| 352 | Safefree(PL_reentrant_buffer->_setlocale_buffer); |
| 353 | # endif /* HAS_SETLOCALE_R */ |
| 354 | |
| 355 | # ifdef HAS_STRERROR_R |
| 356 | Safefree(PL_reentrant_buffer->_strerror_buffer); |
| 357 | # endif /* HAS_STRERROR_R */ |
| 358 | |
| 359 | # ifdef HAS_TTYNAME_R |
| 360 | Safefree(PL_reentrant_buffer->_ttyname_buffer); |
| 361 | # endif /* HAS_TTYNAME_R */ |
| 362 | |
| 363 | |
| 364 | Safefree(PL_reentrant_buffer); |
| 365 | |
| 366 | #endif /* USE_REENTRANT_API */ |
| 367 | } |
| 368 | |
| 369 | void* |
| 370 | Perl_reentrant_retry(const char *f, ...) |
| 371 | { |
| 372 | /* This function is set up to be called if the normal function returns |
| 373 | * failure with errno ERANGE, which indicates the buffer is too small. |
| 374 | * This function calls the failing one again with a larger buffer. |
| 375 | * |
| 376 | * What has happened is that, due to the magic of C preprocessor macro |
| 377 | * expansion, when the original code called function 'foo(args)', it was |
| 378 | * instead compiled into something like a call of 'foo_r(args, buffer)' |
| 379 | * Below we retry with 'foo', but the preprocessor has changed that into |
| 380 | * 'foo_r', so this function will end up calling itself recursively, each |
| 381 | * time with a larger buffer. If PERL_REENTRANT_MAXSIZE is defined, it |
| 382 | * won't increase beyond that, instead failing. */ |
| 383 | |
| 384 | void *retptr = NULL; |
| 385 | va_list ap; |
| 386 | |
| 387 | I32 key = 0; |
| 388 | |
| 389 | #ifdef USE_REENTRANT_API |
| 390 | |
| 391 | dTHX; |
| 392 | |
| 393 | key = Perl_keyword (aTHX_ f, strlen(f), FALSE /* not feature enabled */); |
| 394 | |
| 395 | /* Easier to special case this here than in embed.pl. (Look at what it |
| 396 | generates for proto.h) */ |
| 397 | PERL_ARGS_ASSERT_REENTRANT_RETRY; |
| 398 | |
| 399 | #endif |
| 400 | |
| 401 | if (key == 0) { |
| 402 | |
| 403 | #ifdef HAS_GETSPNAM_R |
| 404 | |
| 405 | /* This is a #define as has no corresponding keyword */ |
| 406 | if (strEQ(f, "getspnam")) { |
| 407 | key = KEY_getspnam; |
| 408 | } |
| 409 | |
| 410 | #endif |
| 411 | |
| 412 | } |
| 413 | else if (key < 0) { |
| 414 | key = -key; |
| 415 | } |
| 416 | |
| 417 | va_start(ap, f); |
| 418 | |
| 419 | #ifdef USE_REENTRANT_API |
| 420 | |
| 421 | switch (key) { |
| 422 | |
| 423 | # ifdef USE_HOSTENT_BUFFER |
| 424 | |
| 425 | case KEY_gethostbyaddr: |
| 426 | case KEY_gethostbyname: |
| 427 | case KEY_endhostent: |
| 428 | { |
| 429 | char * host_addr; |
| 430 | Size_t asize; |
| 431 | char * host_name; |
| 432 | int anint; |
| 433 | |
| 434 | # ifdef PERL_REENTRANT_MAXSIZE |
| 435 | if (PL_reentrant_buffer->_hostent_size <= |
| 436 | PERL_REENTRANT_MAXSIZE / 2) |
| 437 | # endif |
| 438 | RenewDouble(PL_reentrant_buffer->_hostent_buffer, |
| 439 | &PL_reentrant_buffer->_hostent_size, char); |
| 440 | switch (key) { |
| 441 | case KEY_gethostbyaddr: |
| 442 | host_addr = va_arg(ap, char *); |
| 443 | asize = va_arg(ap, Size_t); |
| 444 | anint = va_arg(ap, int); |
| 445 | /* socklen_t is what Posix 2001 says this should be */ |
| 446 | retptr = gethostbyaddr(host_addr, (socklen_t) asize, anint); break; |
| 447 | case KEY_gethostbyname: |
| 448 | host_name = va_arg(ap, char *); |
| 449 | retptr = gethostbyname(host_name); break; |
| 450 | case KEY_endhostent: |
| 451 | retptr = gethostent(); break; |
| 452 | default: |
| 453 | SETERRNO(ERANGE, LIB_INVARG); |
| 454 | break; |
| 455 | } |
| 456 | } |
| 457 | break; |
| 458 | |
| 459 | # endif |
| 460 | # ifdef USE_GRENT_BUFFER |
| 461 | |
| 462 | case KEY_getgrent: |
| 463 | case KEY_getgrgid: |
| 464 | case KEY_getgrnam: |
| 465 | { |
| 466 | char * name; |
| 467 | Gid_t gid; |
| 468 | |
| 469 | # ifdef PERL_REENTRANT_MAXSIZE |
| 470 | if (PL_reentrant_buffer->_grent_size <= |
| 471 | PERL_REENTRANT_MAXSIZE / 2) |
| 472 | # endif |
| 473 | RenewDouble(PL_reentrant_buffer->_grent_buffer, |
| 474 | &PL_reentrant_buffer->_grent_size, char); |
| 475 | switch (key) { |
| 476 | case KEY_getgrnam: |
| 477 | name = va_arg(ap, char *); |
| 478 | retptr = getgrnam(name); break; |
| 479 | case KEY_getgrgid: |
| 480 | # if Gid_t_size < INTSIZE |
| 481 | gid = (Gid_t)va_arg(ap, int); |
| 482 | # else |
| 483 | gid = va_arg(ap, Gid_t); |
| 484 | # endif |
| 485 | retptr = getgrgid(gid); break; |
| 486 | case KEY_getgrent: |
| 487 | retptr = getgrent(); break; |
| 488 | default: |
| 489 | SETERRNO(ERANGE, LIB_INVARG); |
| 490 | break; |
| 491 | } |
| 492 | } |
| 493 | break; |
| 494 | |
| 495 | # endif |
| 496 | # ifdef USE_NETENT_BUFFER |
| 497 | |
| 498 | case KEY_getnetbyaddr: |
| 499 | case KEY_getnetbyname: |
| 500 | case KEY_getnetent: |
| 501 | { |
| 502 | char * name; |
| 503 | Netdb_net_t net; |
| 504 | int anint; |
| 505 | |
| 506 | # ifdef PERL_REENTRANT_MAXSIZE |
| 507 | if (PL_reentrant_buffer->_netent_size <= |
| 508 | PERL_REENTRANT_MAXSIZE / 2) |
| 509 | # endif |
| 510 | RenewDouble(PL_reentrant_buffer->_netent_buffer, |
| 511 | &PL_reentrant_buffer->_netent_size, char); |
| 512 | switch (key) { |
| 513 | case KEY_getnetbyaddr: |
| 514 | net = va_arg(ap, Netdb_net_t); |
| 515 | anint = va_arg(ap, int); |
| 516 | retptr = getnetbyaddr(net, anint); break; |
| 517 | case KEY_getnetbyname: |
| 518 | name = va_arg(ap, char *); |
| 519 | retptr = getnetbyname(name); break; |
| 520 | case KEY_getnetent: |
| 521 | retptr = getnetent(); break; |
| 522 | default: |
| 523 | SETERRNO(ERANGE, LIB_INVARG); |
| 524 | break; |
| 525 | } |
| 526 | } |
| 527 | break; |
| 528 | |
| 529 | # endif |
| 530 | # ifdef USE_PWENT_BUFFER |
| 531 | |
| 532 | case KEY_getpwnam: |
| 533 | case KEY_getpwuid: |
| 534 | case KEY_getpwent: |
| 535 | { |
| 536 | Uid_t uid; |
| 537 | char * name; |
| 538 | |
| 539 | # ifdef PERL_REENTRANT_MAXSIZE |
| 540 | if (PL_reentrant_buffer->_pwent_size <= |
| 541 | PERL_REENTRANT_MAXSIZE / 2) |
| 542 | |
| 543 | # endif |
| 544 | RenewDouble(PL_reentrant_buffer->_pwent_buffer, |
| 545 | &PL_reentrant_buffer->_pwent_size, char); |
| 546 | switch (key) { |
| 547 | case KEY_getpwnam: |
| 548 | name = va_arg(ap, char *); |
| 549 | retptr = getpwnam(name); break; |
| 550 | case KEY_getpwuid: |
| 551 | |
| 552 | # if Uid_t_size < INTSIZE |
| 553 | uid = (Uid_t)va_arg(ap, int); |
| 554 | # else |
| 555 | uid = va_arg(ap, Uid_t); |
| 556 | # endif |
| 557 | retptr = getpwuid(uid); break; |
| 558 | |
| 559 | # if defined(HAS_GETPWENT) || defined(HAS_GETPWENT_R) |
| 560 | |
| 561 | case KEY_getpwent: |
| 562 | retptr = getpwent(); break; |
| 563 | # endif |
| 564 | default: |
| 565 | SETERRNO(ERANGE, LIB_INVARG); |
| 566 | break; |
| 567 | } |
| 568 | } |
| 569 | break; |
| 570 | |
| 571 | # endif |
| 572 | # ifdef USE_SPENT_BUFFER |
| 573 | |
| 574 | case KEY_getspnam: |
| 575 | { |
| 576 | char * name; |
| 577 | |
| 578 | # ifdef PERL_REENTRANT_MAXSIZE |
| 579 | if (PL_reentrant_buffer->_spent_size <= |
| 580 | PERL_REENTRANT_MAXSIZE / 2) |
| 581 | |
| 582 | # endif |
| 583 | RenewDouble(PL_reentrant_buffer->_spent_buffer, |
| 584 | &PL_reentrant_buffer->_spent_size, char); |
| 585 | switch (key) { |
| 586 | case KEY_getspnam: |
| 587 | name = va_arg(ap, char *); |
| 588 | retptr = getspnam(name); break; |
| 589 | default: |
| 590 | SETERRNO(ERANGE, LIB_INVARG); |
| 591 | break; |
| 592 | } |
| 593 | } |
| 594 | break; |
| 595 | |
| 596 | # endif |
| 597 | # ifdef USE_PROTOENT_BUFFER |
| 598 | |
| 599 | case KEY_getprotobyname: |
| 600 | case KEY_getprotobynumber: |
| 601 | case KEY_getprotoent: |
| 602 | { |
| 603 | char * name; |
| 604 | int anint; |
| 605 | |
| 606 | # ifdef PERL_REENTRANT_MAXSIZE |
| 607 | if (PL_reentrant_buffer->_protoent_size <= |
| 608 | PERL_REENTRANT_MAXSIZE / 2) |
| 609 | # endif |
| 610 | RenewDouble(PL_reentrant_buffer->_protoent_buffer, |
| 611 | &PL_reentrant_buffer->_protoent_size, char); |
| 612 | switch (key) { |
| 613 | case KEY_getprotobyname: |
| 614 | name = va_arg(ap, char *); |
| 615 | retptr = getprotobyname(name); break; |
| 616 | case KEY_getprotobynumber: |
| 617 | anint = va_arg(ap, int); |
| 618 | retptr = getprotobynumber(anint); break; |
| 619 | case KEY_getprotoent: |
| 620 | retptr = getprotoent(); break; |
| 621 | default: |
| 622 | SETERRNO(ERANGE, LIB_INVARG); |
| 623 | break; |
| 624 | } |
| 625 | } |
| 626 | break; |
| 627 | |
| 628 | # endif |
| 629 | # ifdef USE_SERVENT_BUFFER |
| 630 | |
| 631 | case KEY_getservbyname: |
| 632 | case KEY_getservbyport: |
| 633 | case KEY_getservent: |
| 634 | { |
| 635 | char * name; |
| 636 | char * proto; |
| 637 | int anint; |
| 638 | |
| 639 | # ifdef PERL_REENTRANT_MAXSIZE |
| 640 | if (PL_reentrant_buffer->_servent_size <= |
| 641 | PERL_REENTRANT_MAXSIZE / 2) |
| 642 | # endif |
| 643 | RenewDouble(PL_reentrant_buffer->_servent_buffer, |
| 644 | &PL_reentrant_buffer->_servent_size, char); |
| 645 | switch (key) { |
| 646 | case KEY_getservbyname: |
| 647 | name = va_arg(ap, char *); |
| 648 | proto = va_arg(ap, char *); |
| 649 | retptr = getservbyname(name, proto); break; |
| 650 | case KEY_getservbyport: |
| 651 | anint = va_arg(ap, int); |
| 652 | name = va_arg(ap, char *); |
| 653 | retptr = getservbyport(anint, name); break; |
| 654 | case KEY_getservent: |
| 655 | retptr = getservent(); break; |
| 656 | default: |
| 657 | SETERRNO(ERANGE, LIB_INVARG); |
| 658 | break; |
| 659 | } |
| 660 | } |
| 661 | break; |
| 662 | |
| 663 | # endif |
| 664 | |
| 665 | default: |
| 666 | /* Not known how to retry, so just fail. */ |
| 667 | break; |
| 668 | } |
| 669 | |
| 670 | #else |
| 671 | |
| 672 | PERL_UNUSED_ARG(f); |
| 673 | |
| 674 | #endif |
| 675 | |
| 676 | va_end(ap); |
| 677 | return retptr; |
| 678 | } |
| 679 | |
| 680 | /* ex: set ro: */ |