xref: /openbsd-src/gnu/usr.bin/perl/reentr.c (revision 897fc685943471cf985a0fe38ba076ea6fe74fa5)
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 void
37 Perl_reentrant_size(pTHX) {
38 	PERL_UNUSED_CONTEXT;
39 #ifdef USE_REENTRANT_API
40 #define REENTRANTSMALLSIZE	 256	/* Make something up. */
41 #define REENTRANTUSUALSIZE	4096	/* Make something up. */
42 #ifdef HAS_ASCTIME_R
43 	PL_reentrant_buffer->_asctime_size = REENTRANTSMALLSIZE;
44 #endif /* HAS_ASCTIME_R */
45 #ifdef HAS_CRYPT_R
46 #endif /* HAS_CRYPT_R */
47 #ifdef HAS_CTIME_R
48 	PL_reentrant_buffer->_ctime_size = REENTRANTSMALLSIZE;
49 #endif /* HAS_CTIME_R */
50 #ifdef HAS_GETGRNAM_R
51 #   if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
52 	PL_reentrant_buffer->_grent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
53 	if (PL_reentrant_buffer->_grent_size == (size_t) -1)
54 		PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
55 #   else
56 #       if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
57 	PL_reentrant_buffer->_grent_size = SIABUFSIZ;
58 #       else
59 #           ifdef __sgi
60 	PL_reentrant_buffer->_grent_size = BUFSIZ;
61 #           else
62 	PL_reentrant_buffer->_grent_size = REENTRANTUSUALSIZE;
63 #           endif
64 #       endif
65 #   endif
66 #endif /* HAS_GETGRNAM_R */
67 #ifdef HAS_GETHOSTBYNAME_R
68 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
69 	PL_reentrant_buffer->_hostent_size = REENTRANTUSUALSIZE;
70 #endif
71 #endif /* HAS_GETHOSTBYNAME_R */
72 #ifdef HAS_GETLOGIN_R
73 	PL_reentrant_buffer->_getlogin_size = REENTRANTSMALLSIZE;
74 #endif /* HAS_GETLOGIN_R */
75 #ifdef HAS_GETNETBYNAME_R
76 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
77 	PL_reentrant_buffer->_netent_size = REENTRANTUSUALSIZE;
78 #endif
79 #endif /* HAS_GETNETBYNAME_R */
80 #ifdef HAS_GETPROTOBYNAME_R
81 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
82 	PL_reentrant_buffer->_protoent_size = REENTRANTUSUALSIZE;
83 #endif
84 #endif /* HAS_GETPROTOBYNAME_R */
85 #ifdef HAS_GETPWNAM_R
86 #   if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
87 	PL_reentrant_buffer->_pwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
88 	if (PL_reentrant_buffer->_pwent_size == (size_t) -1)
89 		PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
90 #   else
91 #       if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
92 	PL_reentrant_buffer->_pwent_size = SIABUFSIZ;
93 #       else
94 #           ifdef __sgi
95 	PL_reentrant_buffer->_pwent_size = BUFSIZ;
96 #           else
97 	PL_reentrant_buffer->_pwent_size = REENTRANTUSUALSIZE;
98 #           endif
99 #       endif
100 #   endif
101 #endif /* HAS_GETPWNAM_R */
102 #ifdef HAS_GETSERVBYNAME_R
103 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
104 	PL_reentrant_buffer->_servent_size = REENTRANTUSUALSIZE;
105 #endif
106 #endif /* HAS_GETSERVBYNAME_R */
107 #ifdef HAS_GETSPNAM_R
108 #   if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
109 	PL_reentrant_buffer->_spent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
110 	if (PL_reentrant_buffer->_spent_size == (size_t) -1)
111 		PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
112 #   else
113 #       if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
114 	PL_reentrant_buffer->_spent_size = SIABUFSIZ;
115 #       else
116 #           ifdef __sgi
117 	PL_reentrant_buffer->_spent_size = BUFSIZ;
118 #           else
119 	PL_reentrant_buffer->_spent_size = REENTRANTUSUALSIZE;
120 #           endif
121 #       endif
122 #   endif
123 #endif /* HAS_GETSPNAM_R */
124 #ifdef HAS_READDIR_R
125 	/* This is the size Solaris recommends.
126 	 * (though we go static, should use pathconf() instead) */
127 	PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
128 #endif /* HAS_READDIR_R */
129 #ifdef HAS_READDIR64_R
130 	/* This is the size Solaris recommends.
131 	 * (though we go static, should use pathconf() instead) */
132 	PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
133 #endif /* HAS_READDIR64_R */
134 #ifdef HAS_SETLOCALE_R
135 	PL_reentrant_buffer->_setlocale_size = REENTRANTSMALLSIZE;
136 #endif /* HAS_SETLOCALE_R */
137 #ifdef HAS_STRERROR_R
138 	PL_reentrant_buffer->_strerror_size = REENTRANTSMALLSIZE;
139 #endif /* HAS_STRERROR_R */
140 #ifdef HAS_TTYNAME_R
141 	PL_reentrant_buffer->_ttyname_size = REENTRANTSMALLSIZE;
142 #endif /* HAS_TTYNAME_R */
143 
144 #endif /* USE_REENTRANT_API */
145 }
146 
147 void
148 Perl_reentrant_init(pTHX) {
149 	PERL_UNUSED_CONTEXT;
150 #ifdef USE_REENTRANT_API
151 	Newx(PL_reentrant_buffer, 1, REENTR);
152 	Perl_reentrant_size(aTHX);
153 #ifdef HAS_ASCTIME_R
154 	Newx(PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
155 #endif /* HAS_ASCTIME_R */
156 #ifdef HAS_CRYPT_R
157 #if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
158 	PL_reentrant_buffer->_crypt_struct_buffer = 0;
159 #endif
160 #endif /* HAS_CRYPT_R */
161 #ifdef HAS_CTIME_R
162 	Newx(PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
163 #endif /* HAS_CTIME_R */
164 #ifdef HAS_GETGRNAM_R
165 #   ifdef USE_GRENT_FPTR
166 	PL_reentrant_buffer->_grent_fptr = NULL;
167 #   endif
168 	Newx(PL_reentrant_buffer->_grent_buffer, PL_reentrant_buffer->_grent_size, char);
169 #endif /* HAS_GETGRNAM_R */
170 #ifdef HAS_GETHOSTBYNAME_R
171 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
172 	Newx(PL_reentrant_buffer->_hostent_buffer, PL_reentrant_buffer->_hostent_size, char);
173 #endif
174 #endif /* HAS_GETHOSTBYNAME_R */
175 #ifdef HAS_GETLOGIN_R
176 	Newx(PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
177 #endif /* HAS_GETLOGIN_R */
178 #ifdef HAS_GETNETBYNAME_R
179 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
180 	Newx(PL_reentrant_buffer->_netent_buffer, PL_reentrant_buffer->_netent_size, char);
181 #endif
182 #endif /* HAS_GETNETBYNAME_R */
183 #ifdef HAS_GETPROTOBYNAME_R
184 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
185 	Newx(PL_reentrant_buffer->_protoent_buffer, PL_reentrant_buffer->_protoent_size, char);
186 #endif
187 #endif /* HAS_GETPROTOBYNAME_R */
188 #ifdef HAS_GETPWNAM_R
189 #   ifdef USE_PWENT_FPTR
190 	PL_reentrant_buffer->_pwent_fptr = NULL;
191 #   endif
192 	Newx(PL_reentrant_buffer->_pwent_buffer, PL_reentrant_buffer->_pwent_size, char);
193 #endif /* HAS_GETPWNAM_R */
194 #ifdef HAS_GETSERVBYNAME_R
195 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
196 	Newx(PL_reentrant_buffer->_servent_buffer, PL_reentrant_buffer->_servent_size, char);
197 #endif
198 #endif /* HAS_GETSERVBYNAME_R */
199 #ifdef HAS_GETSPNAM_R
200 #   ifdef USE_SPENT_FPTR
201 	PL_reentrant_buffer->_spent_fptr = NULL;
202 #   endif
203 	Newx(PL_reentrant_buffer->_spent_buffer, PL_reentrant_buffer->_spent_size, char);
204 #endif /* HAS_GETSPNAM_R */
205 #ifdef HAS_READDIR_R
206 	PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
207 #endif /* HAS_READDIR_R */
208 #ifdef HAS_READDIR64_R
209 	PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
210 #endif /* HAS_READDIR64_R */
211 #ifdef HAS_SETLOCALE_R
212 	Newx(PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
213 #endif /* HAS_SETLOCALE_R */
214 #ifdef HAS_STRERROR_R
215 	Newx(PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
216 #endif /* HAS_STRERROR_R */
217 #ifdef HAS_TTYNAME_R
218 	Newx(PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
219 #endif /* HAS_TTYNAME_R */
220 
221 #endif /* USE_REENTRANT_API */
222 }
223 
224 void
225 Perl_reentrant_free(pTHX) {
226 	PERL_UNUSED_CONTEXT;
227 #ifdef USE_REENTRANT_API
228 #ifdef HAS_ASCTIME_R
229 	Safefree(PL_reentrant_buffer->_asctime_buffer);
230 #endif /* HAS_ASCTIME_R */
231 #ifdef HAS_CRYPT_R
232 #if CRYPT_R_PROTO != REENTRANT_PROTO_B_CCD
233 	Safefree(PL_reentrant_buffer->_crypt_struct_buffer);
234 #endif
235 #endif /* HAS_CRYPT_R */
236 #ifdef HAS_CTIME_R
237 	Safefree(PL_reentrant_buffer->_ctime_buffer);
238 #endif /* HAS_CTIME_R */
239 #ifdef HAS_GETGRNAM_R
240 	Safefree(PL_reentrant_buffer->_grent_buffer);
241 #endif /* HAS_GETGRNAM_R */
242 #ifdef HAS_GETHOSTBYNAME_R
243 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
244 	Safefree(PL_reentrant_buffer->_hostent_buffer);
245 #endif
246 #endif /* HAS_GETHOSTBYNAME_R */
247 #ifdef HAS_GETLOGIN_R
248 	Safefree(PL_reentrant_buffer->_getlogin_buffer);
249 #endif /* HAS_GETLOGIN_R */
250 #ifdef HAS_GETNETBYNAME_R
251 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
252 	Safefree(PL_reentrant_buffer->_netent_buffer);
253 #endif
254 #endif /* HAS_GETNETBYNAME_R */
255 #ifdef HAS_GETPROTOBYNAME_R
256 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
257 	Safefree(PL_reentrant_buffer->_protoent_buffer);
258 #endif
259 #endif /* HAS_GETPROTOBYNAME_R */
260 #ifdef HAS_GETPWNAM_R
261 	Safefree(PL_reentrant_buffer->_pwent_buffer);
262 #endif /* HAS_GETPWNAM_R */
263 #ifdef HAS_GETSERVBYNAME_R
264 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
265 	Safefree(PL_reentrant_buffer->_servent_buffer);
266 #endif
267 #endif /* HAS_GETSERVBYNAME_R */
268 #ifdef HAS_GETSPNAM_R
269 	Safefree(PL_reentrant_buffer->_spent_buffer);
270 #endif /* HAS_GETSPNAM_R */
271 #ifdef HAS_READDIR_R
272 	Safefree(PL_reentrant_buffer->_readdir_struct);
273 #endif /* HAS_READDIR_R */
274 #ifdef HAS_READDIR64_R
275 	Safefree(PL_reentrant_buffer->_readdir64_struct);
276 #endif /* HAS_READDIR64_R */
277 #ifdef HAS_SETLOCALE_R
278 	Safefree(PL_reentrant_buffer->_setlocale_buffer);
279 #endif /* HAS_SETLOCALE_R */
280 #ifdef HAS_STRERROR_R
281 	Safefree(PL_reentrant_buffer->_strerror_buffer);
282 #endif /* HAS_STRERROR_R */
283 #ifdef HAS_TTYNAME_R
284 	Safefree(PL_reentrant_buffer->_ttyname_buffer);
285 #endif /* HAS_TTYNAME_R */
286 
287 	Safefree(PL_reentrant_buffer);
288 #endif /* USE_REENTRANT_API */
289 }
290 
291 void*
292 Perl_reentrant_retry(const char *f, ...)
293 {
294     void *retptr = NULL;
295     va_list ap;
296 #ifdef USE_REENTRANT_API
297     dTHX;
298     /* Easier to special case this here than in embed.pl. (Look at what it
299        generates for proto.h) */
300     PERL_ARGS_ASSERT_REENTRANT_RETRY;
301 #endif
302     va_start(ap, f);
303     {
304 #ifdef USE_REENTRANT_API
305 #  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)
306     void *p0;
307 #  endif
308 #  if defined(USE_SERVENT_BUFFER)
309     void *p1;
310 #  endif
311 #  if defined(USE_HOSTENT_BUFFER)
312     size_t asize;
313 #  endif
314 #  if defined(USE_HOSTENT_BUFFER) || defined(USE_NETENT_BUFFER) || defined(USE_PROTOENT_BUFFER) || defined(USE_SERVENT_BUFFER)
315     int anint;
316 #  endif
317 
318     switch (PL_op->op_type) {
319 #ifdef USE_HOSTENT_BUFFER
320     case OP_GHBYADDR:
321     case OP_GHBYNAME:
322     case OP_GHOSTENT:
323 	{
324 #ifdef PERL_REENTRANT_MAXSIZE
325 	    if (PL_reentrant_buffer->_hostent_size <=
326 		PERL_REENTRANT_MAXSIZE / 2)
327 #endif
328 	    {
329 		PL_reentrant_buffer->_hostent_size *= 2;
330 		Renew(PL_reentrant_buffer->_hostent_buffer,
331 		      PL_reentrant_buffer->_hostent_size, char);
332 		switch (PL_op->op_type) {
333 	        case OP_GHBYADDR:
334 		    p0    = va_arg(ap, void *);
335 		    asize = va_arg(ap, size_t);
336 		    anint  = va_arg(ap, int);
337 		    retptr = gethostbyaddr(p0, asize, anint); break;
338 	        case OP_GHBYNAME:
339 		    p0 = va_arg(ap, void *);
340 		    retptr = gethostbyname((char *)p0); break;
341 	        case OP_GHOSTENT:
342 		    retptr = gethostent(); break;
343 	        default:
344 		    SETERRNO(ERANGE, LIB_INVARG);
345 		    break;
346 	        }
347 	    }
348 	}
349 	break;
350 #endif
351 #ifdef USE_GRENT_BUFFER
352     case OP_GGRNAM:
353     case OP_GGRGID:
354     case OP_GGRENT:
355 	{
356 #ifdef PERL_REENTRANT_MAXSIZE
357 	    if (PL_reentrant_buffer->_grent_size <=
358 		PERL_REENTRANT_MAXSIZE / 2)
359 #endif
360 	    {
361 		Gid_t gid;
362 		PL_reentrant_buffer->_grent_size *= 2;
363 		Renew(PL_reentrant_buffer->_grent_buffer,
364 		      PL_reentrant_buffer->_grent_size, char);
365 		switch (PL_op->op_type) {
366 	        case OP_GGRNAM:
367 		    p0 = va_arg(ap, void *);
368 		    retptr = getgrnam((char *)p0); break;
369 	        case OP_GGRGID:
370 #if Gid_t_size < INTSIZE
371 		    gid = (Gid_t)va_arg(ap, int);
372 #else
373 		    gid = va_arg(ap, Gid_t);
374 #endif
375 		    retptr = getgrgid(gid); break;
376 	        case OP_GGRENT:
377 		    retptr = getgrent(); break;
378 	        default:
379 		    SETERRNO(ERANGE, LIB_INVARG);
380 		    break;
381 	        }
382 	    }
383 	}
384 	break;
385 #endif
386 #ifdef USE_NETENT_BUFFER
387     case OP_GNBYADDR:
388     case OP_GNBYNAME:
389     case OP_GNETENT:
390 	{
391 #ifdef PERL_REENTRANT_MAXSIZE
392 	    if (PL_reentrant_buffer->_netent_size <=
393 		PERL_REENTRANT_MAXSIZE / 2)
394 #endif
395 	    {
396 		Netdb_net_t net;
397 		PL_reentrant_buffer->_netent_size *= 2;
398 		Renew(PL_reentrant_buffer->_netent_buffer,
399 		      PL_reentrant_buffer->_netent_size, char);
400 		switch (PL_op->op_type) {
401 	        case OP_GNBYADDR:
402 		    net = va_arg(ap, Netdb_net_t);
403 		    anint = va_arg(ap, int);
404 		    retptr = getnetbyaddr(net, anint); break;
405 	        case OP_GNBYNAME:
406 		    p0 = va_arg(ap, void *);
407 		    retptr = getnetbyname((char *)p0); break;
408 	        case OP_GNETENT:
409 		    retptr = getnetent(); break;
410 	        default:
411 		    SETERRNO(ERANGE, LIB_INVARG);
412 		    break;
413 	        }
414 	    }
415 	}
416 	break;
417 #endif
418 #ifdef USE_PWENT_BUFFER
419     case OP_GPWNAM:
420     case OP_GPWUID:
421     case OP_GPWENT:
422 	{
423 #ifdef PERL_REENTRANT_MAXSIZE
424 	    if (PL_reentrant_buffer->_pwent_size <=
425 		PERL_REENTRANT_MAXSIZE / 2)
426 #endif
427 	    {
428 		Uid_t uid;
429 		PL_reentrant_buffer->_pwent_size *= 2;
430 		Renew(PL_reentrant_buffer->_pwent_buffer,
431 		      PL_reentrant_buffer->_pwent_size, char);
432 		switch (PL_op->op_type) {
433 	        case OP_GPWNAM:
434 		    p0 = va_arg(ap, void *);
435 		    retptr = getpwnam((char *)p0); break;
436 	        case OP_GPWUID:
437 #if Uid_t_size < INTSIZE
438 		    uid = (Uid_t)va_arg(ap, int);
439 #else
440 		    uid = va_arg(ap, Uid_t);
441 #endif
442 		    retptr = getpwuid(uid); break;
443 #if defined(HAS_GETPWENT) || defined(HAS_GETPWENT_R)
444 	        case OP_GPWENT:
445 		    retptr = getpwent(); break;
446 #endif
447 	        default:
448 		    SETERRNO(ERANGE, LIB_INVARG);
449 		    break;
450 	        }
451 	    }
452 	}
453 	break;
454 #endif
455 #ifdef USE_PROTOENT_BUFFER
456     case OP_GPBYNAME:
457     case OP_GPBYNUMBER:
458     case OP_GPROTOENT:
459 	{
460 #ifdef PERL_REENTRANT_MAXSIZE
461 	    if (PL_reentrant_buffer->_protoent_size <=
462 		PERL_REENTRANT_MAXSIZE / 2)
463 #endif
464 	    {
465 		PL_reentrant_buffer->_protoent_size *= 2;
466 		Renew(PL_reentrant_buffer->_protoent_buffer,
467 		      PL_reentrant_buffer->_protoent_size, char);
468 		switch (PL_op->op_type) {
469 	        case OP_GPBYNAME:
470 		    p0 = va_arg(ap, void *);
471 		    retptr = getprotobyname((char *)p0); break;
472 	        case OP_GPBYNUMBER:
473 		    anint = va_arg(ap, int);
474 		    retptr = getprotobynumber(anint); break;
475 	        case OP_GPROTOENT:
476 		    retptr = getprotoent(); break;
477 	        default:
478 		    SETERRNO(ERANGE, LIB_INVARG);
479 		    break;
480 	        }
481 	    }
482 	}
483 	break;
484 #endif
485 #ifdef USE_SERVENT_BUFFER
486     case OP_GSBYNAME:
487     case OP_GSBYPORT:
488     case OP_GSERVENT:
489 	{
490 #ifdef PERL_REENTRANT_MAXSIZE
491 	    if (PL_reentrant_buffer->_servent_size <=
492 		PERL_REENTRANT_MAXSIZE / 2)
493 #endif
494 	    {
495 		PL_reentrant_buffer->_servent_size *= 2;
496 		Renew(PL_reentrant_buffer->_servent_buffer,
497 		      PL_reentrant_buffer->_servent_size, char);
498 		switch (PL_op->op_type) {
499 	        case OP_GSBYNAME:
500 		    p0 = va_arg(ap, void *);
501 		    p1 = va_arg(ap, void *);
502 		    retptr = getservbyname((char *)p0, (char *)p1); break;
503 	        case OP_GSBYPORT:
504 		    anint = va_arg(ap, int);
505 		    p0 = va_arg(ap, void *);
506 		    retptr = getservbyport(anint, (char *)p0); break;
507 	        case OP_GSERVENT:
508 		    retptr = getservent(); break;
509 	        default:
510 		    SETERRNO(ERANGE, LIB_INVARG);
511 		    break;
512 	        }
513 	    }
514 	}
515 	break;
516 #endif
517     default:
518 	/* Not known how to retry, so just fail. */
519 	break;
520     }
521 #else
522     PERL_UNUSED_ARG(f);
523 #endif
524     }
525     va_end(ap);
526     return retptr;
527 }
528 
529 /* ex: set ro: */
530