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 = *(size_pointer) * 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 = REENTRANTSMALLSIZE; 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 = REENTRANTSMALLSIZE; 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: */ 681