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