Remove Encode::Tcl::Extended, suggested by
[p5sagit/p5-mst-13.2.git] / reentr.c
1 /*
2  *    reentr.c
3  *
4  *    Copyright (c) 1997-2002, Larry Wall
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  *  !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
10  *  This file is built by reentrl.pl from data in reentr.pl.
11  *
12  * "Saruman," I said, standing away from him, "only one hand at a time can
13  *  wield the One, and you know that well, so do not trouble to say we!"
14  *
15  */
16
17 #include "EXTERN.h"
18 #define PERL_IN_REENTR_C
19 #include "perl.h"
20 #include "reentr.h"
21
22 void
23 Perl_reentrant_size(pTHX) {
24 #ifdef USE_REENTRANT_API
25 #ifdef HAS_ASCTIME_R
26         PL_reentrant_buffer->_asctime_size = 256; /* Make something up. */
27 #endif /* HAS_ASCTIME_R */
28 #ifdef HAS_CRYPT_R
29 #endif /* HAS_CRYPT_R */
30 #ifdef HAS_CTIME_R
31         PL_reentrant_buffer->_ctime_size = 256; /* Make something up. */
32 #endif /* HAS_CTIME_R */
33 #ifdef HAS_DRAND48_R
34 #endif /* HAS_DRAND48_R */
35 #ifdef HAS_GETGRNAM_R
36 #   if defined(HAS_SYSCONF) && defined(_SC_GETGR_R_SIZE_MAX) && !defined(__GLIBC__)
37         PL_reentrant_buffer->_getgrent_size = sysconf(_SC_GETGR_R_SIZE_MAX);
38 #   else
39 #       if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
40         PL_reentrant_buffer->_getgrent_size = SIABUFSIZ;
41 #       else
42 #           ifdef __sgi
43         PL_reentrant_buffer->_getgrent_size = BUFSIZ;
44 #           else
45         PL_reentrant_buffer->_getgrent_size = 256;
46 #           endif
47 #       endif
48 #   endif 
49 #endif /* HAS_GETGRNAM_R */
50 #ifdef HAS_GETHOSTBYNAME_R
51 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
52         PL_reentrant_buffer->_gethostent_size = 2048; /* Any better ideas? */
53 #endif
54 #endif /* HAS_GETHOSTBYNAME_R */
55 #ifdef HAS_GETLOGIN_R
56         PL_reentrant_buffer->_getlogin_size = 256; /* Make something up. */
57 #endif /* HAS_GETLOGIN_R */
58 #ifdef HAS_GETNETBYNAME_R
59 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
60         PL_reentrant_buffer->_getnetent_size = 2048; /* Any better ideas? */
61 #endif
62 #endif /* HAS_GETNETBYNAME_R */
63 #ifdef HAS_GETPROTOBYNAME_R
64 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
65         PL_reentrant_buffer->_getprotoent_size = 2048; /* Any better ideas? */
66 #endif
67 #endif /* HAS_GETPROTOBYNAME_R */
68 #ifdef HAS_GETPWNAM_R
69 #   if defined(HAS_SYSCONF) && defined(_SC_GETPW_R_SIZE_MAX) && !defined(__GLIBC__)
70         PL_reentrant_buffer->_getpwent_size = sysconf(_SC_GETPW_R_SIZE_MAX);
71 #   else
72 #       if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
73         PL_reentrant_buffer->_getpwent_size = SIABUFSIZ;
74 #       else
75 #           ifdef __sgi
76         PL_reentrant_buffer->_getpwent_size = BUFSIZ;
77 #           else
78         PL_reentrant_buffer->_getpwent_size = 256;
79 #           endif
80 #       endif
81 #   endif 
82 #endif /* HAS_GETPWNAM_R */
83 #ifdef HAS_GETSERVBYNAME_R
84 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
85         PL_reentrant_buffer->_getservent_size = 2048; /* Any better ideas? */
86 #endif
87 #endif /* HAS_GETSERVBYNAME_R */
88 #ifdef HAS_GETSPNAM_R
89         PL_reentrant_buffer->_getspent_size = 1024;
90 #endif /* HAS_GETSPNAM_R */
91 #ifdef HAS_GMTIME_R
92 #endif /* HAS_GMTIME_R */
93 #ifdef HAS_LOCALTIME_R
94 #endif /* HAS_LOCALTIME_R */
95 #ifdef HAS_RANDOM_R
96 #endif /* HAS_RANDOM_R */
97 #ifdef HAS_READDIR_R
98         /* This is the size Solaris recommends.
99          * (though we go static, should use pathconf() instead) */
100         PL_reentrant_buffer->_readdir_size = sizeof(struct dirent) + MAXPATHLEN + 1;
101 #endif /* HAS_READDIR_R */
102 #ifdef HAS_READDIR64_R
103         /* This is the size Solaris recommends.
104          * (though we go static, should use pathconf() instead) */
105         PL_reentrant_buffer->_readdir64_size = sizeof(struct dirent64) + MAXPATHLEN + 1;
106 #endif /* HAS_READDIR64_R */
107 #ifdef HAS_SETLOCALE_R
108         PL_reentrant_buffer->_setlocale_size = 256; /* Make something up. */
109 #endif /* HAS_SETLOCALE_R */
110 #ifdef HAS_STRERROR_R
111         PL_reentrant_buffer->_strerror_size = 256; /* Make something up. */
112 #endif /* HAS_STRERROR_R */
113 #ifdef HAS_TTYNAME_R
114         PL_reentrant_buffer->_ttyname_size = 256; /* Make something up. */
115 #endif /* HAS_TTYNAME_R */
116
117 #endif /* USE_REENTRANT_API */
118 }
119
120 void
121 Perl_reentrant_init(pTHX) {
122 #ifdef USE_REENTRANT_API
123         New(31337, PL_reentrant_buffer, 1, REENTR);
124         Perl_reentrant_size(aTHX);
125 #ifdef HAS_ASCTIME_R
126         New(31338, PL_reentrant_buffer->_asctime_buffer, PL_reentrant_buffer->_asctime_size, char);
127 #endif /* HAS_ASCTIME_R */
128 #ifdef HAS_CRYPT_R
129 #ifdef __GLIBC__
130         PL_reentrant_buffer->_crypt_struct.initialized = 0;
131 #endif
132 #endif /* HAS_CRYPT_R */
133 #ifdef HAS_CTIME_R
134         New(31338, PL_reentrant_buffer->_ctime_buffer, PL_reentrant_buffer->_ctime_size, char);
135 #endif /* HAS_CTIME_R */
136 #ifdef HAS_DRAND48_R
137 #endif /* HAS_DRAND48_R */
138 #ifdef HAS_GETGRNAM_R
139 #   ifdef USE_GETGRENT_FPTR
140         PL_reentrant_buffer->_getgrent_fptr = NULL;
141 #   endif
142         New(31338, PL_reentrant_buffer->_getgrent_buffer, PL_reentrant_buffer->_getgrent_size, char);
143 #endif /* HAS_GETGRNAM_R */
144 #ifdef HAS_GETHOSTBYNAME_R
145 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
146         New(31338, PL_reentrant_buffer->_gethostent_buffer, PL_reentrant_buffer->_gethostent_size, char);
147 #endif
148 #endif /* HAS_GETHOSTBYNAME_R */
149 #ifdef HAS_GETLOGIN_R
150         New(31338, PL_reentrant_buffer->_getlogin_buffer, PL_reentrant_buffer->_getlogin_size, char);
151 #endif /* HAS_GETLOGIN_R */
152 #ifdef HAS_GETNETBYNAME_R
153 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
154         New(31338, PL_reentrant_buffer->_getnetent_buffer, PL_reentrant_buffer->_getnetent_size, char);
155 #endif
156 #endif /* HAS_GETNETBYNAME_R */
157 #ifdef HAS_GETPROTOBYNAME_R
158 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
159         New(31338, PL_reentrant_buffer->_getprotoent_buffer, PL_reentrant_buffer->_getprotoent_size, char);
160 #endif
161 #endif /* HAS_GETPROTOBYNAME_R */
162 #ifdef HAS_GETPWNAM_R
163 #   ifdef USE_GETPWENT_FPTR
164         PL_reentrant_buffer->_getpwent_fptr = NULL;
165 #   endif
166         New(31338, PL_reentrant_buffer->_getpwent_buffer, PL_reentrant_buffer->_getpwent_size, char);
167 #endif /* HAS_GETPWNAM_R */
168 #ifdef HAS_GETSERVBYNAME_R
169 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
170         New(31338, PL_reentrant_buffer->_getservent_buffer, PL_reentrant_buffer->_getservent_size, char);
171 #endif
172 #endif /* HAS_GETSERVBYNAME_R */
173 #ifdef HAS_GETSPNAM_R
174         New(31338, PL_reentrant_buffer->_getspent_buffer, PL_reentrant_buffer->_getspent_size, char);
175 #endif /* HAS_GETSPNAM_R */
176 #ifdef HAS_GMTIME_R
177 #endif /* HAS_GMTIME_R */
178 #ifdef HAS_LOCALTIME_R
179 #endif /* HAS_LOCALTIME_R */
180 #ifdef HAS_RANDOM_R
181 #endif /* HAS_RANDOM_R */
182 #ifdef HAS_READDIR_R
183         PL_reentrant_buffer->_readdir_struct = (struct dirent*)safemalloc(PL_reentrant_buffer->_readdir_size);
184 #endif /* HAS_READDIR_R */
185 #ifdef HAS_READDIR64_R
186         PL_reentrant_buffer->_readdir64_struct = (struct dirent64*)safemalloc(PL_reentrant_buffer->_readdir64_size);
187 #endif /* HAS_READDIR64_R */
188 #ifdef HAS_SETLOCALE_R
189         New(31338, PL_reentrant_buffer->_setlocale_buffer, PL_reentrant_buffer->_setlocale_size, char);
190 #endif /* HAS_SETLOCALE_R */
191 #ifdef HAS_STRERROR_R
192         New(31338, PL_reentrant_buffer->_strerror_buffer, PL_reentrant_buffer->_strerror_size, char);
193 #endif /* HAS_STRERROR_R */
194 #ifdef HAS_TTYNAME_R
195         New(31338, PL_reentrant_buffer->_ttyname_buffer, PL_reentrant_buffer->_ttyname_size, char);
196 #endif /* HAS_TTYNAME_R */
197
198 #endif /* USE_REENTRANT_API */
199 }
200
201 void
202 Perl_reentrant_free(pTHX) {
203 #ifdef USE_REENTRANT_API
204 #ifdef HAS_ASCTIME_R
205         Safefree(PL_reentrant_buffer->_asctime_buffer);
206 #endif /* HAS_ASCTIME_R */
207 #ifdef HAS_CRYPT_R
208 #endif /* HAS_CRYPT_R */
209 #ifdef HAS_CTIME_R
210         Safefree(PL_reentrant_buffer->_ctime_buffer);
211 #endif /* HAS_CTIME_R */
212 #ifdef HAS_DRAND48_R
213 #endif /* HAS_DRAND48_R */
214 #ifdef HAS_GETGRNAM_R
215         Safefree(PL_reentrant_buffer->_getgrent_buffer);
216 #endif /* HAS_GETGRNAM_R */
217 #ifdef HAS_GETHOSTBYNAME_R
218 #if   !(GETHOSTBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
219         Safefree(PL_reentrant_buffer->_gethostent_buffer);
220 #endif
221 #endif /* HAS_GETHOSTBYNAME_R */
222 #ifdef HAS_GETLOGIN_R
223         Safefree(PL_reentrant_buffer->_getlogin_buffer);
224 #endif /* HAS_GETLOGIN_R */
225 #ifdef HAS_GETNETBYNAME_R
226 #if   !(GETNETBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
227         Safefree(PL_reentrant_buffer->_getnetent_buffer);
228 #endif
229 #endif /* HAS_GETNETBYNAME_R */
230 #ifdef HAS_GETPROTOBYNAME_R
231 #if   !(GETPROTOBYNAME_R_PROTO == REENTRANT_PROTO_I_CSD)
232         Safefree(PL_reentrant_buffer->_getprotoent_buffer);
233 #endif
234 #endif /* HAS_GETPROTOBYNAME_R */
235 #ifdef HAS_GETPWNAM_R
236         Safefree(PL_reentrant_buffer->_getpwent_buffer);
237 #endif /* HAS_GETPWNAM_R */
238 #ifdef HAS_GETSERVBYNAME_R
239 #if   !(GETSERVBYNAME_R_PROTO == REENTRANT_PROTO_I_CCSD)
240         Safefree(PL_reentrant_buffer->_getservent_buffer);
241 #endif
242 #endif /* HAS_GETSERVBYNAME_R */
243 #ifdef HAS_GETSPNAM_R
244         Safefree(PL_reentrant_buffer->_getspent_buffer);
245 #endif /* HAS_GETSPNAM_R */
246 #ifdef HAS_GMTIME_R
247 #endif /* HAS_GMTIME_R */
248 #ifdef HAS_LOCALTIME_R
249 #endif /* HAS_LOCALTIME_R */
250 #ifdef HAS_RANDOM_R
251 #endif /* HAS_RANDOM_R */
252 #ifdef HAS_READDIR_R
253         Safefree(PL_reentrant_buffer->_readdir_struct);
254 #endif /* HAS_READDIR_R */
255 #ifdef HAS_READDIR64_R
256         Safefree(PL_reentrant_buffer->_readdir64_struct);
257 #endif /* HAS_READDIR64_R */
258 #ifdef HAS_SETLOCALE_R
259         Safefree(PL_reentrant_buffer->_setlocale_buffer);
260 #endif /* HAS_SETLOCALE_R */
261 #ifdef HAS_STRERROR_R
262         Safefree(PL_reentrant_buffer->_strerror_buffer);
263 #endif /* HAS_STRERROR_R */
264 #ifdef HAS_TTYNAME_R
265         Safefree(PL_reentrant_buffer->_ttyname_buffer);
266 #endif /* HAS_TTYNAME_R */
267
268         Safefree(PL_reentrant_buffer);
269 #endif /* USE_REENTRANT_API */
270 }
271
272 void*
273 Perl_reentrant_retry(const char *f, ...)
274 {
275     dTHX;
276     void *retptr = NULL;
277 #ifdef USE_REENTRANT_API
278     void *p0, *p1;
279     size_t asize;
280     int anint;
281     va_list ap;
282
283     va_start(ap, f);
284
285 #define REENTRANTHALFMAXSIZE 32768 /* The maximum may end up twice this. */
286
287     switch (PL_op->op_type) {
288 #ifdef USE_GETHOSTENT_BUFFER
289     case OP_GHBYADDR:
290     case OP_GHBYNAME:
291     case OP_GHOSTENT:
292         {
293             if (PL_reentrant_buffer->_gethostent_size <= REENTRANTHALFMAXSIZE) {
294                 PL_reentrant_buffer->_gethostent_size *= 2;
295                 Renew(PL_reentrant_buffer->_gethostent_buffer,
296                       PL_reentrant_buffer->_gethostent_size, char);
297                 switch (PL_op->op_type) {
298                 case OP_GHBYADDR:
299                     p0    = va_arg(ap, void *);
300                     asize = va_arg(ap, size_t);
301                     anint  = va_arg(ap, int);
302                     retptr = gethostbyaddr(p0, asize, anint); break;
303                 case OP_GHBYNAME:
304                     p0 = va_arg(ap, void *);
305                     retptr = gethostbyname(p0); break;
306                 case OP_GHOSTENT:
307                     retptr = gethostent(); break;
308                 default:
309                     break;
310                 }
311             }
312         }
313         break;
314 #endif
315 #ifdef USE_GETGRENT_BUFFER
316     case OP_GGRNAM:
317     case OP_GGRGID:
318     case OP_GGRENT:
319         {
320             if (PL_reentrant_buffer->_getgrent_size <= REENTRANTHALFMAXSIZE) {
321                 Gid_t gid;
322                 PL_reentrant_buffer->_getgrent_size *= 2;
323                 Renew(PL_reentrant_buffer->_getgrent_buffer,
324                       PL_reentrant_buffer->_getgrent_size, char);
325                 switch (PL_op->op_type) {
326                 case OP_GGRNAM:
327                     p0 = va_arg(ap, void *);
328                     retptr = getgrnam(p0); break;
329                 case OP_GGRGID:
330                     gid = va_arg(ap, Gid_t);
331                     retptr = getgrgid(gid); break;
332                 case OP_GGRENT:
333                     retptr = getgrent(); break;
334                 default:
335                     break;
336                 }
337             }
338         }
339         break;
340 #endif
341 #ifdef USE_GETNETENT_BUFFER
342     case OP_GNBYADDR:
343     case OP_GNBYNAME:
344     case OP_GNETENT:
345         {
346             if (PL_reentrant_buffer->_getnetent_size <= REENTRANTHALFMAXSIZE) {
347                 Netdb_net_t net;
348                 PL_reentrant_buffer->_getnetent_size *= 2;
349                 Renew(PL_reentrant_buffer->_getnetent_buffer,
350                       PL_reentrant_buffer->_getnetent_size, char);
351                 switch (PL_op->op_type) {
352                 case OP_GNBYADDR:
353                     net = va_arg(ap, Netdb_net_t);
354                     anint = va_arg(ap, int);
355                     retptr = getnetbyaddr(net, anint); break;
356                 case OP_GNBYNAME:
357                     p0 = va_arg(ap, void *);
358                     retptr = getnetbyname(p0); break;
359                 case OP_GNETENT:
360                     retptr = getnetent(); break;
361                 default:
362                     break;
363                 }
364             }
365         }
366         break;
367 #endif
368 #ifdef USE_GETPWENT_BUFFER
369     case OP_GPWNAM:
370     case OP_GPWUID:
371     case OP_GPWENT:
372         {
373             if (PL_reentrant_buffer->_getpwent_size <= REENTRANTHALFMAXSIZE) {
374                 Uid_t uid;
375                 PL_reentrant_buffer->_getpwent_size *= 2;
376                 Renew(PL_reentrant_buffer->_getpwent_buffer,
377                       PL_reentrant_buffer->_getpwent_size, char);
378                 switch (PL_op->op_type) {
379                 case OP_GPWNAM:
380                     p0 = va_arg(ap, void *);
381                     retptr = getpwnam(p0); break;
382                 case OP_GPWUID:
383                     uid = va_arg(ap, Uid_t);
384                     retptr = getpwuid(uid); break;
385                 case OP_GPWENT:
386                     retptr = getpwent(); break;
387                 default:
388                     break;
389                 }
390             }
391         }
392         break;
393 #endif
394 #ifdef USE_GETPROTOENT_BUFFER
395     case OP_GPBYNAME:
396     case OP_GPBYNUMBER:
397     case OP_GPROTOENT:
398         {
399             if (PL_reentrant_buffer->_getprotoent_size <= REENTRANTHALFMAXSIZE) {
400                 PL_reentrant_buffer->_getprotoent_size *= 2;
401                 Renew(PL_reentrant_buffer->_getprotoent_buffer,
402                       PL_reentrant_buffer->_getprotoent_size, char);
403                 switch (PL_op->op_type) {
404                 case OP_GPBYNAME:
405                     p0 = va_arg(ap, void *);
406                     retptr = getprotobyname(p0); break;
407                 case OP_GPBYNUMBER:
408                     anint = va_arg(ap, int);
409                     retptr = getprotobynumber(anint); break;
410                 case OP_GPROTOENT:
411                     retptr = getprotoent(); break;
412                 default:
413                     break;
414                 }
415             }
416         }
417         break;
418 #endif
419 #ifdef USE_GETSERVENT_BUFFER
420     case OP_GSBYNAME:
421     case OP_GSBYPORT:
422     case OP_GSERVENT:
423         {
424             if (PL_reentrant_buffer->_getservent_size <= REENTRANTHALFMAXSIZE) {
425                 PL_reentrant_buffer->_getservent_size *= 2;
426                 Renew(PL_reentrant_buffer->_getservent_buffer,
427                       PL_reentrant_buffer->_getservent_size, char);
428                 switch (PL_op->op_type) {
429                 case OP_GSBYNAME:
430                     p0 = va_arg(ap, void *);
431                     p1 = va_arg(ap, void *);
432                     retptr = getservbyname(p0, p1); break;
433                 case OP_GSBYPORT:
434                     anint = va_arg(ap, int);
435                     p0 = va_arg(ap, void *);
436                     retptr = getservbyport(anint, p0); break;
437                 case OP_GSERVENT:
438                     retptr = getservent(); break;
439                 default:
440                     break;
441                 }
442             }
443         }
444         break;
445 #endif
446     default:
447         /* Not known how to retry, so just fail. */
448         break;
449     }
450
451     va_end(ap);
452 #endif
453     return retptr;
454 }
455