Monster _r patch: try to scan for all known _r variants,
[p5sagit/p5-mst-13.2.git] / reentr.pl
CommitLineData
10bc17b6 1#!/usr/bin/perl -w
2
3#
4# Generate the reentr.c and reentr.h,
5# and optionally also the relevant metaconfig units (-U option).
6#
7
8use strict;
9use Getopt::Std;
10my %opts;
11getopts('U', \%opts);
12
13my %map = (
14 V => "void",
15 A => "char*", # as an input argument
16 B => "char*", # as an output argument
17 C => "const char*", # as a read-only input argument
18 I => "int",
19 L => "long",
20 W => "size_t",
21 H => "FILE**",
22 E => "int*",
23 );
24
25# (See the definitions after __DATA__.)
26# In func|inc|type|... a "S" means "type*", and a "R" means "type**".
27# (The "types" are often structs, such as "struct passwd".)
28#
29# After the prototypes one can have |X=...|Y=... to define more types.
30# A commonly used extra type is to define D to be equal to "type_data",
31# for example "struct_hostent_data to" go with "struct hostent".
32#
33# Example #1: I_XSBWR means int func_r(X, type, char*, size_t, type**)
34# Example #2: S_SBIE means type func_r(type, char*, int, int*)
35# Example #3: S_CBI means type func_r(const char*, char*, int)
36
37
38die "reentr.h: $!" unless open(H, ">reentr.h");
39select H;
40print <<EOF;
41/*
42 * reentr.h
43 *
44 * Copyright (c) 1997-2002, Larry Wall
45 *
46 * You may distribute under the terms of either the GNU General Public
47 * License or the Artistic License, as specified in the README file.
48 *
49 * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
50 * This file is built by reentrl.pl from data in reentr.pl.
51 */
52
53#ifndef REENTR_H
54#define REENTR_H
55
56#ifdef USE_REENTRANT_API
57
58/* Deprecations: some platforms have the said reentrant interfaces
59 * but they are declared obsolete and are not to be used. Often this
60 * means that the platform has threadsafed the interfaces (hopefully).
61 * All this is OS version dependent, so we are of course fooling ourselves.
62 * If you know of more deprecations on some platforms, please add your own. */
63
64#ifdef __hpux
65# undef HAS_CRYPT_R
66# undef HAS_DRAND48_R
67# undef HAS_GETGRENT_R
68# undef HAS_GETPWENT_R
69# undef HAS_SETLOCALE_R
70# undef HAS_SRAND48_R
71# undef HAS_STRERROR_R
72# define NETDB_R_OBSOLETE
73#endif
74
75#if defined(__osf__) && defined(__alpha) /* Tru64 aka Digital UNIX */
76# undef HAS_CRYPT_R
77# undef HAS_STRERROR_R
78# define NETDB_R_OBSOLETE
79#endif
80
81#ifdef NETDB_R_OBSOLETE
82# undef HAS_ENDHOSTENT_R
83# undef HAS_ENDNETENT_R
84# undef HAS_ENDPROTOENT_R
85# undef HAS_ENDSERVENT_R
86# undef HAS_GETHOSTBYADDR_R
87# undef HAS_GETHOSTBYNAME_R
88# undef HAS_GETHOSTENT_R
89# undef HAS_GETNETBYADDR_R
90# undef HAS_GETNETBYNAME_R
91# undef HAS_GETNETENT_R
92# undef HAS_GETPROTOBYNAME_R
93# undef HAS_GETPROTOBYNUMBER_R
94# undef HAS_GETPROTOENT_R
95# undef HAS_GETSERVBYNAME_R
96# undef HAS_GETSERVBYPORT_R
97# undef HAS_GETSERVENT_R
98# undef HAS_SETHOSTENT_R
99# undef HAS_SETNETENT_R
100# undef HAS_SETPROTOENT_R
101# undef HAS_SETSERVENT_R
102#endif
103
104#ifdef I_PWD
105# include <pwd.h>
106#endif
107#ifdef I_GRP
108# include <grp.h>
109#endif
110#ifdef I_NETDB
111# include <netdb.h>
112#endif
113#ifdef I_STDLIB
114# include <stdlib.h> /* drand48_data */
115#endif
116#ifdef I_CRYPT
117# ifdef I_CRYPT
118# include <crypt.h>
119# endif
120#endif
121#ifdef HAS_GETSPNAM_R
122# ifdef I_SHADOW
123# include <shadow.h>
124# endif
125#endif
126
127EOF
128
129my %seenh;
130my %seena;
131my @seenf;
132my %seenp;
133my %seent;
134my %seens;
135my %seend;
136my %seenu;
137
138while (<DATA>) {
139 next if /^\s+$/;
140 chomp;
141 my ($f, $h, $t, @p) = split(/\s*\|\s*/, $_, -1);
142 my $u;
143 ($f, $u) = split(' ', $f);
144 $seenu{$f} = defined $u ? length $u : 0;
145 my $F = uc $f;
146 push @seenf, $f;
147 my %m = %map;
148 if ($t) {
149 $m{S} = "$t*";
150 $m{R} = "$t**";
151 }
152 if (@p) {
153 while ($p[-1] =~ /=/) {
154 my ($k, $v) = ($p[-1] =~ /^([A-Za-z])\s*=\s*(.*)/);
155 $m{$k} = $v;
156 pop @p;
157 }
158 }
159 if ($opts{U} && open(U, ">d_${f}_r.U")) {
160 select U;
161 }
162 my $prereqh = $h eq 'stdio' ? '' : "i_$h"; # There's no i_stdio.
163 print <<EOF if $opts{U};
164?RCS: \$Id: d_${f}_r.U,v $
165?RCS:
166?RCS: Copyright (c) 2002 Jarkko Hietaniemi
167?RCS:
168?RCS: You may distribute under the terms of either the GNU General Public
169?RCS: License or the Artistic License, as specified in the README file.
170?RCS:
171?RCS: Generated by the reentr.pl from the Perl 5.8 distribution.
172?RCS:
173?MAKE:d_${f}_r ${f}_r_proto: Inlibc Protochk i_systypes $prereqh
174?MAKE: -pick add \$@ %<
175?S:d_${f}_r:
176?S: This variable conditionally defines the HAS_${F}_R symbol,
177?S: which indicates to the C program that the ${f}_r()
178?S: routine is available.
179?S:.
180?S:${f}_r_proto:
181?S: This variable encodes the prototype of ${f}_r.
182?S:.
183?C:HAS_${F}_R:
184?C: This symbol, if defined, indicates that the ${f}_r routine
185?C: is available to ${f} re-entrantly.
186?C:.
187?C:${F}_R_PROTO:
188?C: This symbol encodes the prototype of ${f}_r.
189?C:.
190?H:#\$d_${f}_r HAS_${F}_R /**/
191?H:#define ${F}_R_PROTO \$${f}_r_proto /**/
192?H:.
193?T:try hdrs
194?LINT:set d_${f}_r
195?LINT:set ${f}_r_proto
196: see if ${f}_r exists
197set ${f}_r d_${f}_r
198eval \$inlibc
199case "\$d_${f}_r" in
200"\$define")
201 hdrs="\$i_systypes sys/types.h define stdio.h \$i_${h} $h.h"
202EOF
203 for my $p (@p) {
204 my ($r, $a) = ($p =~ /^(.)_(.+)/);
205 my $v = join(", ", map { $m{$_} } split '', $a);
206 if ($opts{U}) {
207 print <<EOF ;
208 case "\$${f}_r_proto" in
209 ''|0) try='$m{$r} ${f}_r($v);'
210 ./protochk "extern \$try" \$hdrs && ${f}_r_proto=$p ;;
211 esac
212EOF
213 }
214 $seenh{$f}->{$p}++;
215 push @{$seena{$f}}, $p;
216 $seenp{$p}++;
217 $seent{$f} = $t;
218 $seens{$f} = $m{S};
219 $seend{$f} = $m{D};
220 }
221 if ($opts{U}) {
222 print <<EOF;
223 case "\$${f}_r_proto" in
224 '') d_${f}_r=undef
225 ${f}_r_proto=0
226 echo "Disabling ${f}_r, cannot determine prototype." ;;
227 * ) case "\$${f}_r_proto" in
228 REENTRANT_PROTO*) ;;
229 *) ${f}_r_proto="REENTRANT_PROTO_\$${f}_r_proto" ;;
230 esac
231 echo "Prototype: \$try" ;;
232 esac
233 ;;
234*) ${f}_r_proto=0
235 ;;
236esac
237
238EOF
239 close(U);
240 }
241}
242
243close DATA;
244
245select H;
246
247{
248 my $i = 1;
249 for my $p (sort keys %seenp) {
250 print "#define REENTRANT_PROTO_${p} ${i}\n";
251 $i++;
252 }
253}
254
255sub ifprotomatch {
256 my $F = shift;
257 join " || ", map { "${F}_R_PROTO == REENTRANT_PROTO_$_" } @_;
258}
259
260my @struct;
261my @size;
262my @init;
263my @free;
264my @wrap;
265my @define;
266
267sub pushssif {
268 push @struct, @_;
269 push @size, @_;
270 push @init, @_;
271 push @free, @_;
272}
273
274sub pushinitfree {
275 my $f = shift;
276 push @init, <<EOF;
277 New(31338, PL_reentrant_buffer->_${f}_buffer, PL_reentrant_buffer->_${f}_size, char);
278EOF
279 push @free, <<EOF;
280 Safefree(PL_reentrant_buffer->_${f}_buffer);
281EOF
282}
283
284sub define {
285 my ($n, $p, @F) = @_;
286 my @H;
287 my $H = uc $F[0];
288 push @define, <<EOF;
289/* The @F using \L$n? */
290
291EOF
292 for my $f (@F) {
293 my $F = uc $f;
294 my $h = "${F}_R_HAS_$n";
295 push @H, $h;
296 my @h = grep { /$p/ } @{$seena{$f}};
297 if (@h) {
298 push @define, "#if (" . join(" || ", map { "${F}_R_PROTO == REENTRANT_PROTO_$_" } @h) . ")\n";
299
300 push @define, <<EOF;
301# define $h
302#else
303# undef $h
304#endif
305EOF
306 }
307 }
308 push @define, <<EOF;
309
310/* Any of the @F using \L$n? */
311
312EOF
313 push @define, "#if (" . join(" || ", map { "defined($_)" } @H) . ")\n";
314 push @define, <<EOF;
315# define USE_${H}_$n
316#else
317# undef USE_${H}_$n
318#endif
319
320EOF
321}
322
323define('PTR', 'R',
324 qw(getgrent getgrgid getgrnam));
325define('PTR', 'R',
326 qw(getpwent getpwnam getpwuid));
327define('PTR', 'R',
328 qw(getspent getspnam));
329
330define('FPTR', 'H',
331 qw(getgrent getgrgid getgrnam));
332define('FPTR', 'H',
333 qw(getpwent getpwnam getpwuid));
334
335define('PTR', 'R',
336 qw(gethostent gethostbyaddr gethostbyname));
337define('PTR', 'R',
338 qw(getnetent getnetbyaddr getnetbyname));
339define('PTR', 'R',
340 qw(getprotoent getprotobyname getprotobynumber));
341define('PTR', 'R',
342 qw(getservent getservbyname getservbyport));
343
344define('ERRNO', 'E',
345 qw(gethostent gethostbyaddr gethostbyname));
346define('ERRNO', 'E',
347 qw(getnetent getnetbyaddr getnetbyname));
348
349for my $f (@seenf) {
350 my $F = uc $f;
351 my $ifdef = "#ifdef HAS_${F}_R\n";
352 my $endif = "#endif /* HAS_${F}_R */\n";
353 if (exists $seena{$f}) {
354 my @p = @{$seena{$f}};
355 if ($f =~ /^(asctime|ctime|getlogin|setlocale|strerror|ttyname)$/) {
356 pushssif $ifdef;
357 push @struct, <<EOF;
358 char* _${f}_buffer;
359 size_t _${f}_size;
360EOF
361 push @size, <<EOF;
362 PL_reentrant_buffer->_${f}_size = 256; /* Make something up. */
363EOF
364 pushinitfree $f;
365 pushssif $endif;
366 }
367 elsif ($f =~ /^(crypt|drand48|gmtime|localtime|random)$/) {
368 pushssif $ifdef;
369 push @struct, <<EOF;
370 $seent{$f} _${f}_struct;
371EOF
372 if ($f eq 'crypt') {
373 push @init, <<EOF;
374#ifdef __GLIBC__
375 PL_reentrant_buffer->_${f}_struct.initialized = 0;
376#endif
377EOF
378 }
379 if ($1 eq 'drand48') {
380 push @struct, <<EOF;
381 double _${f}_double;
382EOF
383 }
384 pushssif $endif;
385 }
386 elsif ($f =~ /^(getgrnam|getpwnam|getspnam)$/) {
387 pushssif $ifdef;
388 my $g = $f;
389 $g =~ s/nam/ent/g;
390 my $G = uc $g;
391 push @struct, <<EOF;
392 $seent{$f} _${g}_struct;
393 char* _${g}_buffer;
394 size_t _${g}_size;
395EOF
396 push @struct, <<EOF;
397# ifdef USE_${G}_PTR
398 $seent{$f}* _${g}_ptr;
399# endif
400EOF
401 if ($g eq 'getspent') {
402 push @size, <<EOF;
403 PL_reentrant_buffer->_${g}_size = 1024;
404EOF
405 } else {
406 push @struct, <<EOF;
407# ifdef USE_${G}_FPTR
408 FILE* _${g}_fptr;
409# endif
410EOF
411 push @init, <<EOF;
412# ifdef USE_${G}_FPTR
413 PL_reentrant_buffer->_${g}_fptr = NULL;
414# endif
415EOF
416 my $sc = $g eq 'getgrent' ?
417 '_SC_GETGR_R_SIZE_MAX' : '_SC_GETPW_R_SIZE_MAX';
418 push @size, <<EOF;
419# if defined(HAS_SYSCONF) && defined($sc) && !defined(__GLIBC__)
420 PL_reentrant_buffer->_${g}_size = sysconf($sc);
421# else
422# if defined(__osf__) && defined(__alpha) && defined(SIABUFSIZ)
423 PL_reentrant_buffer->_${g}_size = SIABUFSIZ;
424# else
425# ifdef __sgi
426 PL_reentrant_buffer->_${g}_size = BUFSIZ;
427# else
428 PL_reentrant_buffer->_${g}_size = 2048;
429# endif
430# endif
431# endif
432EOF
433 }
434 pushinitfree $g;
435 pushssif $endif;
436 }
437 elsif ($f =~ /^(gethostbyname|getnetbyname|getservbyname|getprotobyname)$/) {
438 pushssif $ifdef;
439 my $g = $f;
440 $g =~ s/byname/ent/;
441 my $G = uc $g;
442 my $D = ifprotomatch($F, grep {/D/} @p);
443 my $d = $seend{$f};
444 push @struct, <<EOF;
445 $seent{$f} _${g}_struct;
446# if $D
447 $d _${g}_data;
448# else
449 char* _${g}_buffer;
450 size_t _${g}_size;
451# endif
452# ifdef USE_${G}_PTR
453 $seent{$f}* _${g}_ptr;
454# endif
455EOF
456 push @struct, <<EOF;
457# ifdef USE_${G}_ERRNO
458 int _${g}_errno;
459# endif
460EOF
461 push @size, <<EOF;
462#if !($D)
463 PL_reentrant_buffer->_${g}_size = 2048; /* Any better ideas? */
464#endif
465EOF
466 push @init, <<EOF;
467#if !($D)
468 New(31338, PL_reentrant_buffer->_${g}_buffer, PL_reentrant_buffer->_${g}_size, char);
469#endif
470EOF
471 push @free, <<EOF;
472#if !($D)
473 Safefree(PL_reentrant_buffer->_${g}_buffer);
474#endif
475EOF
476 pushssif $endif;
477 }
478 elsif ($f =~ /^(readdir|readdir64)$/) {
479 pushssif $ifdef;
480 my $R = ifprotomatch($F, grep {/R/} @p);
481 push @struct, <<EOF;
482 $seent{$f}* _${f}_struct;
483 size_t _${f}_size;
484# if $R
485 $seent{$f}* _${f}_ptr;
486# endif
487EOF
488 push @size, <<EOF;
489 /* This is the size Solaris recommends.
490 * (though we go static, should use pathconf() instead) */
491 PL_reentrant_buffer->_${f}_size = sizeof($seent{$f}) + MAXPATHLEN + 1;
492EOF
493 push @init, <<EOF;
494 PL_reentrant_buffer->_${f}_struct = ($seent{$f}*)safemalloc(PL_reentrant_buffer->_${f}_size);
495EOF
496 push @free, <<EOF;
497 Safefree(PL_reentrant_buffer->_${f}_struct);
498EOF
499 pushssif $endif;
500 }
501
502 push @wrap, $ifdef;
503
504# Doesn't implement the buffer growth loop for glibc gethostby*().
505 push @wrap, <<EOF;
506# undef $f
507EOF
508 my @v = 'a'..'z';
509 my $v = join(", ", @v[0..$seenu{$f}-1]);
510 for my $p (@p) {
511 my ($r, $a) = split '_', $p;
512 my $test = $r eq 'I' ? ' == 0' : '';
513 my $true = 1;
514 my $false = 0;
515 my $g = $f;
516 if ($g =~ /^(?:get|set|end)(pw|gr|host|net|proto|serv|sp)/) {
517 $g = "get$1ent";
518 } elsif ($g eq 'srand48') {
519 $g = "drand48";
520 }
521 my $b = $a;
522 my $w = '';
523 substr($b, 0, $seenu{$f}) = '';
524 if ($b =~ /R/) {
525 $true = "PL_reentrant_buffer->_${g}_ptr";
526 } elsif ($b =~ /T/ && $f eq 'drand48') {
527 $true = "PL_reentrant_buffer->_${g}_double";
528 } elsif ($b =~ /S/) {
529 if ($f =~ /^readdir/) {
530 $true = "PL_reentrant_buffer->_${g}_struct";
531 } else {
532 $true = "&PL_reentrant_buffer->_${g}_struct";
533 }
534 } elsif ($b =~ /B/) {
535 $true = "PL_reentrant_buffer->_${g}_buffer";
536 }
537 if (length $b) {
538 $w = join ", ",
539 map {
540 $_ eq 'R' ?
541 "&PL_reentrant_buffer->_${g}_ptr" :
542 $_ eq 'E' ?
543 "&PL_reentrant_buffer->_${g}_errno" :
544 $_ eq 'B' ?
545 "PL_reentrant_buffer->_${g}_buffer" :
546 $_ =~ /^[WI]$/ ?
547 "PL_reentrant_buffer->_${g}_size" :
548 $_ eq 'H' ?
549 "&PL_reentrant_buffer->_${g}_fptr" :
550 $_ eq 'D' ?
551 "&PL_reentrant_buffer->_${g}_data" :
552 $_ eq 'S' ?
553 ($f =~ /^readdir/ ?
554 "PL_reentrant_buffer->_${g}_struct" :
555 "&PL_reentrant_buffer->_${g}_struct" ) :
556 $_ eq 'T' && $f eq 'drand48' ?
557 "&PL_reentrant_buffer->_${g}_double" :
558 $_
559 } split '', $b;
560 $w = ", $w" if length $v;
561 }
562 my $call = "${f}_r($v$w)";
563 $call = "((errno = $call))" if $r eq 'I';
564 push @wrap, <<EOF;
565# if !defined($f) && ${F}_R_PROTO == REENTRANT_PROTO_$p
566EOF
567 if ($r eq 'V' || $r eq 'B') {
568 push @wrap, <<EOF;
569# define $f($v) $call
570EOF
571 } else {
572 push @wrap, <<EOF;
573# define $f($v) ($call$test ? $true : $false)
574EOF
575 }
576 push @wrap, <<EOF;
577# endif
578EOF
579 }
580
581 push @wrap, $endif, "\n";
582 }
583}
584
585local $" = '';
586
587print <<EOF;
588
589/* Defines for indicating which special features are supported. */
590
591@define
592typedef struct {
593@struct
594} REENTR;
595
596/* The wrappers. */
597
598@wrap
599#endif /* USE_REENTRANT_API */
600
601#endif
602
603EOF
604
605close(H);
606
607die "reentr.c: $!" unless open(C, ">reentr.c");
608select C;
609print <<EOF;
610/*
611 * reentr.c
612 *
613 * Copyright (c) 1997-2002, Larry Wall
614 *
615 * You may distribute under the terms of either the GNU General Public
616 * License or the Artistic License, as specified in the README file.
617 *
618 * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
619 * This file is built by reentrl.pl from data in reentr.pl.
620 *
621 * "Saruman," I said, standing away from him, "only one hand at a time can
622 * wield the One, and you know that well, so do not trouble to say we!"
623 *
624 */
625
626#include "EXTERN.h"
627#define PERL_IN_REENTR_C
628#include "perl.h"
629#include "reentr.h"
630
631void
632Perl_reentrant_size(pTHX) {
633#ifdef USE_REENTRANT_API
634@size
635#endif /* USE_REENTRANT_API */
636}
637
638void
639Perl_reentrant_init(pTHX) {
640#ifdef USE_REENTRANT_API
641 New(31337, PL_reentrant_buffer, 1, REENTR);
642 Perl_reentrant_size(aTHX);
643@init
644#endif /* USE_REENTRANT_API */
645}
646
647void
648Perl_reentrant_free(pTHX) {
649#ifdef USE_REENTRANT_API
650@free
651 Safefree(PL_reentrant_buffer);
652#endif /* USE_REENTRANT_API */
653}
654
655EOF
656
657__DATA__
658asctime S |time |const struct tm|B_SB|B_SBI|I_SB|I_SBI
659crypt CC |crypt |struct crypt_data|B_CCS
660ctermid B |stdio | |B_B
661ctime S |time |const time_t |B_SB|B_SBI|I_SB|I_SBI
662drand48 |stdlib |struct drand48_data |I_ST|T=double*
663endgrent |grp | |I_H|V_H
664endhostent |netdb |struct hostent_data |I_S|V_S
665endnetent |netdb |struct netent_data |I_S|V_S
666endprotoent |netdb |struct protoent_data |I_S|V_S
667endpwent |pwd | |I_H|V_H
668endservent |netdb |struct servent_data |I_S|V_S
669getgrent |grp |struct group |I_SBWR|I_SBIR|S_SBW|S_SBI|I_SBI|I_SBIH
670getgrgid T |grp |struct group |I_TSBWR|I_TSBIR|I_TSBI|S_TSBI|T=gid_t
671getgrnam C |grp |struct group |I_CSBWR|I_CSBIR|S_CBI|I_CSBI|S_CSBI
672gethostbyaddr CWI |netdb |struct hostent |I_CWISBWRE|S_CWISBWIE|S_CWISBIE|S_TWISBIE|S_CIISBIE|S_CSBIE|S_TSBIE|I_CWISD|I_CIISD|I_CII|D=struct hostent_data*|T=const void*
673gethostbyname C |netdb |struct hostent |I_CSBWRE|S_CSBIE|I_CSD|D=struct hostent_data*
674gethostent |netdb |struct hostent |I_SBWRE|I_SBIE|S_SBIE|S_SBI|I_SBI|I_SD|D=struct hostent_data*
675getlogin |unistd | |I_BW|I_BI|B_BW|B_BI
676getnetbyaddr LI |netdb |struct netent |I_UISBWRE|I_LISBI|S_TISBI|S_LISBI|I_TISD|I_LISD|I_IISD|D=struct netent_data*|T=in_addr_t|U=unsigned long
677getnetbyname C |netdb |struct netent |I_CSBWRE|I_CSBI|S_CSBI|I_CSD|D=struct netent_data*
678getnetent |netdb |struct netent |I_SBWRE|I_SBIE|S_SBIE|S_SBI|I_SBI|I_SD|D=struct netent_data*
679getprotobyname C|netdb |struct protoent|I_CSBWR|S_CSBI|I_CSD|D=struct protoent_data*
680getprotobynumber I |netdb |struct protoent|I_ISBWR|S_ISBI|I_ISD|D=struct protoent_data*
681getprotoent |netdb |struct protoent|I_SBWR|I_SBI|S_SBI|I_SD|D=struct protoent_data*
682getpwent |pwd |struct passwd |I_SBWR|I_SBIR|S_SBW|S_SBI|I_SBI|I_SBIH
683getpwnam C |pwd |struct passwd |I_CSBWR|I_CSBIR|S_CSBI|I_CSBI
684getpwuid T |pwd |struct passwd |I_TSBWR|I_TSBIR|I_TSBI|S_TSBI|T=uid_t
685getservbyname CC|netdb |struct servent |I_CCSBWR|S_CCSBI|I_CCSD|D=struct servent_data*
686getservbyport IC|netdb |struct servent |I_ICSBWR|S_ICSBI|I_ICSD|D=struct servent_data*
687getservent |netdb |struct servent |I_SBWR|I_SBI|S_SBI|I_SD|D=struct servent_data*
688getspnam C |shadow |struct spwd |I_CSBWR|S_CSBI
689gmtime T |time |struct tm |S_TS|I_TS|T=const time_t*
690localtime T |time |struct tm |S_TS|I_TS|T=const time_t*
691random |stdlib |struct random_data|I_TS|T=int*
692readdir T |dirent |struct dirent |I_TSR|I_TS|T=DIR*
693readdir64 T |dirent |struct dirent64|I_TSR|I_TS|T=DIR*
694setgrent |grp | |I_H|V_H
695sethostent I |netdb | |I_ID|V_ID|D=struct hostent_data*
696setlocale IC |locale | |I_ICBI
697setnetent I |netdb | |I_ID|V_ID|D=struct netent_data*
698setprotoent I |netdb | |I_ID|V_ID|D=struct protoent_data*
699setpwent |pwd | |I_H|V_H
700setservent I |netdb | |I_ID|V_ID|D=struct servent_data*
701srand48 L |stdlib |struct drand48_data |I_LS
702srandom T |stdlib |struct random_data|I_TS|T=unsigned int
703strerror I |string | |I_IBW|I_IBI|B_IBW
704tmpnam B |stdio | |B_B
705ttyname I |unistd | |I_IBW|I_IBI|B_IBI