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