1/* -*- mode: C; 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 44void 45Perl_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 170void 171Perl_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 275void 276Perl_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 369void* 370Perl_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 ft=c: */ 681