xref: /openbsd-src/gnu/usr.bin/perl/ext/POSIX/lib/POSIX.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1898184e3Ssthenpackage POSIX;
2898184e3Ssthenuse strict;
3898184e3Ssthenuse warnings;
4898184e3Ssthen
5898184e3Ssthenour ($AUTOLOAD, %SIGRT);
6898184e3Ssthen
7*3d61058aSafresh1our $VERSION = '2.20';
8898184e3Ssthen
9898184e3Ssthenrequire XSLoader;
10898184e3Ssthen
11898184e3Ssthenuse Fcntl qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK F_SETFD
12898184e3Ssthen	     F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK O_ACCMODE O_APPEND
13898184e3Ssthen	     O_CREAT O_EXCL O_NOCTTY O_NONBLOCK O_RDONLY O_RDWR O_TRUNC
14898184e3Ssthen	     O_WRONLY SEEK_CUR SEEK_END SEEK_SET
15e0680481Safresh1	     S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISLNK S_ISREG S_ISSOCK
16898184e3Ssthen	     S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU S_ISGID S_ISUID
17898184e3Ssthen	     S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR);
18898184e3Ssthen
19898184e3Ssthenmy $loaded;
20898184e3Ssthen
21898184e3Ssthensub croak { require Carp;  goto &Carp::croak }
22898184e3Ssthensub usage { croak "Usage: POSIX::$_[0]" }
23898184e3Ssthen
24898184e3SsthenXSLoader::load();
25898184e3Ssthen
26898184e3Ssthenmy %replacement = (
279f11ffb7Safresh1    L_tmpnam    => undef,
28898184e3Ssthen    atexit      => 'END {}',
29898184e3Ssthen    atof        => undef,
30898184e3Ssthen    atoi        => undef,
31898184e3Ssthen    atol        => undef,
32898184e3Ssthen    bsearch     => \'not supplied',
33898184e3Ssthen    calloc      => undef,
34898184e3Ssthen    clearerr    => 'IO::Handle::clearerr',
35898184e3Ssthen    div         => '/, % and int',
36898184e3Ssthen    execl       => undef,
37898184e3Ssthen    execle      => undef,
38898184e3Ssthen    execlp      => undef,
39898184e3Ssthen    execv       => undef,
40898184e3Ssthen    execve      => undef,
41898184e3Ssthen    execvp      => undef,
42898184e3Ssthen    fclose      => 'IO::Handle::close',
43898184e3Ssthen    fdopen      => 'IO::Handle::new_from_fd',
44898184e3Ssthen    feof        => 'IO::Handle::eof',
45898184e3Ssthen    ferror      => 'IO::Handle::error',
46898184e3Ssthen    fflush      => 'IO::Handle::flush',
47898184e3Ssthen    fgetc       => 'IO::Handle::getc',
48898184e3Ssthen    fgetpos     => 'IO::Seekable::getpos',
49898184e3Ssthen    fgets       => 'IO::Handle::gets',
50898184e3Ssthen    fileno      => 'IO::Handle::fileno',
51898184e3Ssthen    fopen       => 'IO::File::open',
52898184e3Ssthen    fprintf     => 'printf',
53898184e3Ssthen    fputc       => 'print',
54898184e3Ssthen    fputs       => 'print',
55898184e3Ssthen    fread       => 'read',
56898184e3Ssthen    free        => undef,
57898184e3Ssthen    freopen     => 'open',
58898184e3Ssthen    fscanf      => '<> and regular expressions',
59898184e3Ssthen    fseek       => 'IO::Seekable::seek',
60898184e3Ssthen    fsetpos     => 'IO::Seekable::setpos',
61898184e3Ssthen    fsync       => 'IO::Handle::sync',
62898184e3Ssthen    ftell       => 'IO::Seekable::tell',
63898184e3Ssthen    fwrite      => 'print',
64898184e3Ssthen    labs        => 'abs',
65898184e3Ssthen    ldiv        => '/, % and int',
66898184e3Ssthen    longjmp     => 'die',
67898184e3Ssthen    malloc      => undef,
68898184e3Ssthen    memchr      => 'index()',
69898184e3Ssthen    memcmp      => 'eq',
70898184e3Ssthen    memcpy      => '=',
71898184e3Ssthen    memmove     => '=',
72898184e3Ssthen    memset      => 'x',
73898184e3Ssthen    offsetof    => undef,
74898184e3Ssthen    putc        => 'print',
75898184e3Ssthen    putchar     => 'print',
76898184e3Ssthen    puts        => 'print',
77898184e3Ssthen    qsort       => 'sort',
78898184e3Ssthen    rand        => \'non-portable, use Perl\'s rand instead',
79898184e3Ssthen    realloc     => undef,
80898184e3Ssthen    scanf       => '<> and regular expressions',
81898184e3Ssthen    setbuf      => 'IO::Handle::setbuf',
82898184e3Ssthen    setjmp      => 'eval {}',
83898184e3Ssthen    setvbuf     => 'IO::Handle::setvbuf',
84898184e3Ssthen    siglongjmp  => 'die',
85898184e3Ssthen    sigsetjmp   => 'eval {}',
86898184e3Ssthen    srand       => \'not supplied; refer to Perl\'s srand documentation',
87898184e3Ssthen    sscanf      => 'regular expressions',
88898184e3Ssthen    strcat      => '.=',
89898184e3Ssthen    strchr      => 'index()',
90898184e3Ssthen    strcmp      => 'eq',
91898184e3Ssthen    strcpy      => '=',
92898184e3Ssthen    strcspn     => 'regular expressions',
93898184e3Ssthen    strlen      => 'length',
94898184e3Ssthen    strncat     => '.=',
95898184e3Ssthen    strncmp     => 'eq',
96898184e3Ssthen    strncpy     => '=',
97898184e3Ssthen    strpbrk     => undef,
98898184e3Ssthen    strrchr     => 'rindex()',
99898184e3Ssthen    strspn      => undef,
100898184e3Ssthen    strtok      => undef,
101898184e3Ssthen    tmpfile     => 'IO::File::new_tmpfile',
1029f11ffb7Safresh1    tmpnam      => 'use File::Temp',
103898184e3Ssthen    ungetc      => 'IO::Handle::ungetc',
104898184e3Ssthen    vfprintf    => undef,
105898184e3Ssthen    vprintf     => undef,
106898184e3Ssthen    vsprintf    => undef,
107898184e3Ssthen);
108898184e3Ssthen
109898184e3Ssthenmy %reimpl = (
1109f11ffb7Safresh1    abs       => 'x => CORE::abs($_[0])',
1119f11ffb7Safresh1    alarm     => 'seconds => CORE::alarm($_[0])',
112898184e3Ssthen    assert    => 'expr => croak "Assertion failed" if !$_[0]',
113898184e3Ssthen    atan2     => 'x, y => CORE::atan2($_[0], $_[1])',
1149f11ffb7Safresh1    chdir     => 'directory => CORE::chdir($_[0])',
1159f11ffb7Safresh1    chmod     => 'mode, filename => CORE::chmod($_[0], $_[1])',
1169f11ffb7Safresh1    chown     => 'uid, gid, filename => CORE::chown($_[0], $_[1], $_[2])',
1179f11ffb7Safresh1    closedir  => 'dirhandle => CORE::closedir($_[0])',
118898184e3Ssthen    cos       => 'x => CORE::cos($_[0])',
1199f11ffb7Safresh1    creat     => 'filename, mode => &open($_[0], &O_WRONLY | &O_CREAT | &O_TRUNC, $_[1])',
1209f11ffb7Safresh1    errno     => '$! + 0',
1219f11ffb7Safresh1    exit      => 'status => CORE::exit($_[0])',
122898184e3Ssthen    exp       => 'x => CORE::exp($_[0])',
123898184e3Ssthen    fabs      => 'x => CORE::abs($_[0])',
1249f11ffb7Safresh1    fcntl     => 'filehandle, cmd, arg => CORE::fcntl($_[0], $_[1], $_[2])',
1259f11ffb7Safresh1    fork      => 'CORE::fork',
1269f11ffb7Safresh1    fstat     => 'fd => CORE::open my $dup, "<&", $_[0]; CORE::stat($dup)', # Gross.
127898184e3Ssthen    getc      => 'handle => CORE::getc($_[0])',
128898184e3Ssthen    getchar   => 'CORE::getc(STDIN)',
129898184e3Ssthen    getegid   => '$) + 0',
1309f11ffb7Safresh1    getenv    => 'name => $ENV{$_[0]}',
131898184e3Ssthen    geteuid   => '$> + 0',
132898184e3Ssthen    getgid    => '$( + 0',
1339f11ffb7Safresh1    getgrgid  => 'gid => CORE::getgrgid($_[0])',
1349f11ffb7Safresh1    getgrnam  => 'name => CORE::getgrnam($_[0])',
135898184e3Ssthen    getgroups => 'my %seen; grep !$seen{$_}++, split " ", $)',
136898184e3Ssthen    getlogin  => 'CORE::getlogin()',
137898184e3Ssthen    getpgrp   => 'CORE::getpgrp',
138898184e3Ssthen    getpid    => '$$',
139898184e3Ssthen    getppid   => 'CORE::getppid',
1409f11ffb7Safresh1    getpwnam  => 'name => CORE::getpwnam($_[0])',
1419f11ffb7Safresh1    getpwuid  => 'uid => CORE::getpwuid($_[0])',
1429f11ffb7Safresh1    gets      => 'scalar <STDIN>',
143898184e3Ssthen    getuid    => '$<',
1449f11ffb7Safresh1    gmtime    => 'time => CORE::gmtime($_[0])',
145898184e3Ssthen    isatty    => 'filehandle => -t $_[0]',
1469f11ffb7Safresh1    kill      => 'pid, sig => CORE::kill $_[1], $_[0]',
147898184e3Ssthen    link      => 'oldfilename, newfilename => CORE::link($_[0], $_[1])',
1489f11ffb7Safresh1    localtime => 'time => CORE::localtime($_[0])',
1499f11ffb7Safresh1    log       => 'x => CORE::log($_[0])',
1509f11ffb7Safresh1    mkdir     => 'directoryname, mode => CORE::mkdir($_[0], $_[1])',
1519f11ffb7Safresh1    opendir   => 'directory => my $dh; CORE::opendir($dh, $_[0]) ? $dh : undef',
1529f11ffb7Safresh1    pow       => 'x, exponent => $_[0] ** $_[1]',
1539f11ffb7Safresh1    raise     => 'sig => CORE::kill $_[0], $$;	# Is this good enough',
1549f11ffb7Safresh1    readdir   => 'dirhandle => CORE::readdir($_[0])',
1559f11ffb7Safresh1    remove    => 'filename => (-d $_[0]) ? CORE::rmdir($_[0]) : CORE::unlink($_[0])',
1569f11ffb7Safresh1    rename    => 'oldfilename, newfilename => CORE::rename($_[0], $_[1])',
1579f11ffb7Safresh1    rewind    => 'filehandle => CORE::seek($_[0],0,0)',
1589f11ffb7Safresh1    rewinddir => 'dirhandle => CORE::rewinddir($_[0])',
159898184e3Ssthen    rmdir     => 'directoryname => CORE::rmdir($_[0])',
1609f11ffb7Safresh1    sin       => 'x => CORE::sin($_[0])',
1619f11ffb7Safresh1    sqrt      => 'x => CORE::sqrt($_[0])',
1629f11ffb7Safresh1    stat      => 'filename => CORE::stat($_[0])',
1639f11ffb7Safresh1    strerror  => 'errno => BEGIN { local $!; require locale; locale->import} my $e = $_[0] + 0; local $!; $! = $e; "$!"',
1649f11ffb7Safresh1    strstr    => 'big, little => CORE::index($_[0], $_[1])',
1659f11ffb7Safresh1    system    => 'command => CORE::system($_[0])',
1669f11ffb7Safresh1    time      => 'CORE::time',
1679f11ffb7Safresh1    umask     => 'mask => CORE::umask($_[0])',
168898184e3Ssthen    unlink    => 'filename => CORE::unlink($_[0])',
169898184e3Ssthen    utime     => 'filename, atime, mtime => CORE::utime($_[1], $_[2], $_[0])',
1709f11ffb7Safresh1    wait      => 'CORE::wait()',
1719f11ffb7Safresh1    waitpid   => 'pid, options => CORE::waitpid($_[0], $_[1])',
172898184e3Ssthen);
173898184e3Ssthen
1749f11ffb7Safresh1sub import {
1759f11ffb7Safresh1    my $pkg = shift;
1769f11ffb7Safresh1
1779f11ffb7Safresh1    load_imports() unless $loaded++;
1789f11ffb7Safresh1
179eac174f2Safresh1    # Rewrite legacy foo_h form to new :foo_h form
1809f11ffb7Safresh1    s/^(?=\w+_h$)/:/ for my @list = @_;
1819f11ffb7Safresh1
1829f11ffb7Safresh1    my @unimpl = sort grep { exists $replacement{$_} } @list;
1839f11ffb7Safresh1    if (@unimpl) {
1849f11ffb7Safresh1      for my $u (@unimpl) {
1859f11ffb7Safresh1        warn "Unimplemented: POSIX::$u(): ", unimplemented_message($u);
1869f11ffb7Safresh1      }
1879f11ffb7Safresh1      croak(sprintf("Unimplemented: %s",
1889f11ffb7Safresh1                    join(" ", map { "POSIX::$_()" } @unimpl)));
1899f11ffb7Safresh1    }
1909f11ffb7Safresh1
1919f11ffb7Safresh1    local $Exporter::ExportLevel = 1;
1929f11ffb7Safresh1    Exporter::import($pkg,@list);
1939f11ffb7Safresh1}
1949f11ffb7Safresh1
195898184e3Sstheneval join ';', map "sub $_", keys %replacement, keys %reimpl;
196898184e3Ssthen
1979f11ffb7Safresh1sub unimplemented_message {
1989f11ffb7Safresh1  my $func = shift;
1999f11ffb7Safresh1  my $how = $replacement{$func};
2009f11ffb7Safresh1  return "C-specific, stopped" unless defined $how;
2019f11ffb7Safresh1  return "$$how" if ref $how;
2029f11ffb7Safresh1  return "$how instead" if $how =~ /^use /;
2039f11ffb7Safresh1  return "Use method $how() instead" if $how =~ /::/;
2049f11ffb7Safresh1  return "C-specific: use $how instead";
2059f11ffb7Safresh1}
2069f11ffb7Safresh1
207898184e3Ssthensub AUTOLOAD {
208898184e3Ssthen    my ($func) = ($AUTOLOAD =~ /.*::(.*)/);
209898184e3Ssthen
2106fb12b70Safresh1    die "POSIX.xs has failed to load\n" if $func eq 'constant';
2116fb12b70Safresh1
212898184e3Ssthen    if (my $code = $reimpl{$func}) {
213898184e3Ssthen	my ($num, $arg) = (0, '');
214898184e3Ssthen	if ($code =~ s/^(.*?) *=> *//) {
215898184e3Ssthen	    $arg = $1;
216898184e3Ssthen	    $num = 1 + $arg =~ tr/,//;
217898184e3Ssthen	}
218898184e3Ssthen	# no warnings to be consistent with the old implementation, where each
219898184e3Ssthen	# function was in its own little AutoSplit world:
220898184e3Ssthen	eval qq{ sub $func {
221898184e3Ssthen		no warnings;
222898184e3Ssthen		usage "$func($arg)" if \@_ != $num;
223898184e3Ssthen		$code
224898184e3Ssthen	    } };
225898184e3Ssthen	no strict;
226898184e3Ssthen	goto &$AUTOLOAD;
227898184e3Ssthen    }
228898184e3Ssthen    if (exists $replacement{$func}) {
2299f11ffb7Safresh1      croak "Unimplemented: POSIX::$func(): ", unimplemented_message($func);
230898184e3Ssthen    }
231898184e3Ssthen
232898184e3Ssthen    constant($func);
233898184e3Ssthen}
234898184e3Ssthen
235898184e3Ssthensub perror {
236898184e3Ssthen    print STDERR "@_: " if @_;
237898184e3Ssthen    print STDERR $!,"\n";
238898184e3Ssthen}
239898184e3Ssthen
240898184e3Ssthensub printf {
241898184e3Ssthen    usage "printf(pattern, args...)" if @_ < 1;
242898184e3Ssthen    CORE::printf STDOUT @_;
243898184e3Ssthen}
244898184e3Ssthen
245898184e3Ssthensub sprintf {
246898184e3Ssthen    usage "sprintf(pattern, args...)" if @_ == 0;
247898184e3Ssthen    CORE::sprintf(shift,@_);
248898184e3Ssthen}
249898184e3Ssthen
250898184e3Ssthensub load_imports {
251b8851fccSafresh1my %default_export_tags = ( # cf. exports policy below
252898184e3Ssthen
253898184e3Ssthen    assert_h =>	[qw(assert NDEBUG)],
254898184e3Ssthen
2559f11ffb7Safresh1    ctype_h =>	        [],
256898184e3Ssthen
257898184e3Ssthen    dirent_h =>	[],
258898184e3Ssthen
2596fb12b70Safresh1    errno_h =>	[qw(E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EAFNOSUPPORT EAGAIN
2606fb12b70Safresh1		EALREADY EBADF EBADMSG EBUSY ECANCELED ECHILD ECONNABORTED
2616fb12b70Safresh1		ECONNREFUSED ECONNRESET EDEADLK EDESTADDRREQ EDOM EDQUOT EEXIST
2626fb12b70Safresh1		EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EIDRM EILSEQ EINPROGRESS
2636fb12b70Safresh1		EINTR EINVAL EIO EISCONN EISDIR ELOOP EMFILE EMLINK EMSGSIZE
2646fb12b70Safresh1		ENAMETOOLONG ENETDOWN ENETRESET ENETUNREACH ENFILE ENOBUFS
2656fb12b70Safresh1		ENODATA ENODEV ENOENT ENOEXEC ENOLCK ENOLINK ENOMEM ENOMSG
2666fb12b70Safresh1		ENOPROTOOPT ENOSPC ENOSR ENOSTR ENOSYS ENOTBLK ENOTCONN ENOTDIR
2676fb12b70Safresh1		ENOTEMPTY ENOTRECOVERABLE ENOTSOCK ENOTSUP ENOTTY ENXIO
2686fb12b70Safresh1		EOPNOTSUPP EOTHER EOVERFLOW EOWNERDEAD EPERM EPFNOSUPPORT EPIPE
2696fb12b70Safresh1		EPROCLIM EPROTO EPROTONOSUPPORT EPROTOTYPE ERANGE EREMOTE
2706fb12b70Safresh1		ERESTART EROFS ESHUTDOWN ESOCKTNOSUPPORT ESPIPE ESRCH ESTALE
2716fb12b70Safresh1		ETIME ETIMEDOUT ETOOMANYREFS ETXTBSY EUSERS EWOULDBLOCK EXDEV
2726fb12b70Safresh1		errno)],
273898184e3Ssthen
274898184e3Ssthen    fcntl_h =>	[qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK
275898184e3Ssthen		F_SETFD F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK
276898184e3Ssthen		O_ACCMODE O_APPEND O_CREAT O_EXCL O_NOCTTY O_NONBLOCK
277898184e3Ssthen		O_RDONLY O_RDWR O_TRUNC O_WRONLY
278898184e3Ssthen		creat
279898184e3Ssthen		SEEK_CUR SEEK_END SEEK_SET
280898184e3Ssthen		S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
281e0680481Safresh1		S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISLNK S_ISREG S_ISSOCK S_ISUID
282898184e3Ssthen		S_IWGRP S_IWOTH S_IWUSR)],
283898184e3Ssthen
284898184e3Ssthen    float_h =>	[qw(DBL_DIG DBL_EPSILON DBL_MANT_DIG
285898184e3Ssthen		DBL_MAX DBL_MAX_10_EXP DBL_MAX_EXP
286898184e3Ssthen		DBL_MIN DBL_MIN_10_EXP DBL_MIN_EXP
287898184e3Ssthen		FLT_DIG FLT_EPSILON FLT_MANT_DIG
288898184e3Ssthen		FLT_MAX FLT_MAX_10_EXP FLT_MAX_EXP
289898184e3Ssthen		FLT_MIN FLT_MIN_10_EXP FLT_MIN_EXP
290898184e3Ssthen		FLT_RADIX FLT_ROUNDS
291898184e3Ssthen		LDBL_DIG LDBL_EPSILON LDBL_MANT_DIG
292898184e3Ssthen		LDBL_MAX LDBL_MAX_10_EXP LDBL_MAX_EXP
293898184e3Ssthen		LDBL_MIN LDBL_MIN_10_EXP LDBL_MIN_EXP)],
294898184e3Ssthen
295898184e3Ssthen    grp_h =>	[],
296898184e3Ssthen
297898184e3Ssthen    limits_h =>	[qw( ARG_MAX CHAR_BIT CHAR_MAX CHAR_MIN CHILD_MAX
298898184e3Ssthen		INT_MAX INT_MIN LINK_MAX LONG_MAX LONG_MIN MAX_CANON
299898184e3Ssthen		MAX_INPUT MB_LEN_MAX NAME_MAX NGROUPS_MAX OPEN_MAX
300898184e3Ssthen		PATH_MAX PIPE_BUF SCHAR_MAX SCHAR_MIN SHRT_MAX SHRT_MIN
301898184e3Ssthen		SSIZE_MAX STREAM_MAX TZNAME_MAX UCHAR_MAX UINT_MAX
302898184e3Ssthen		ULONG_MAX USHRT_MAX _POSIX_ARG_MAX _POSIX_CHILD_MAX
303898184e3Ssthen		_POSIX_LINK_MAX _POSIX_MAX_CANON _POSIX_MAX_INPUT
304898184e3Ssthen		_POSIX_NAME_MAX _POSIX_NGROUPS_MAX _POSIX_OPEN_MAX
305898184e3Ssthen		_POSIX_PATH_MAX _POSIX_PIPE_BUF _POSIX_SSIZE_MAX
306898184e3Ssthen		_POSIX_STREAM_MAX _POSIX_TZNAME_MAX)],
307898184e3Ssthen
308898184e3Ssthen    locale_h =>	[qw(LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES
3099f11ffb7Safresh1		    LC_MONETARY LC_NUMERIC LC_TIME LC_IDENTIFICATION
310e0680481Safresh1                    LC_MEASUREMENT LC_PAPER LC_TELEPHONE LC_ADDRESS LC_NAME
311eac174f2Safresh1                    LC_SYNTAX LC_TOD NULL
312898184e3Ssthen		    localeconv setlocale)],
313898184e3Ssthen
314b8851fccSafresh1    math_h =>   [qw(FP_ILOGB0 FP_ILOGBNAN FP_INFINITE FP_NAN FP_NORMAL
315b8851fccSafresh1                    FP_SUBNORMAL FP_ZERO
316b8851fccSafresh1                    M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2 M_LOG10E M_LOG2E
317b8851fccSafresh1                    M_PI M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2
318b8851fccSafresh1                    HUGE_VAL INFINITY NAN
319b8851fccSafresh1                    acos asin atan ceil cosh fabs floor fmod
320898184e3Ssthen		    frexp ldexp log10 modf pow sinh tan tanh)],
321898184e3Ssthen
322898184e3Ssthen    pwd_h =>	[],
323898184e3Ssthen
324898184e3Ssthen    setjmp_h =>	[qw(longjmp setjmp siglongjmp sigsetjmp)],
325898184e3Ssthen
326898184e3Ssthen    signal_h =>	[qw(SA_NOCLDSTOP SA_NOCLDWAIT SA_NODEFER SA_ONSTACK
327898184e3Ssthen		SA_RESETHAND SA_RESTART SA_SIGINFO SIGABRT SIGALRM
328898184e3Ssthen		SIGCHLD SIGCONT SIGFPE SIGHUP SIGILL SIGINT SIGKILL
329898184e3Ssthen		SIGPIPE %SIGRT SIGRTMIN SIGRTMAX SIGQUIT SIGSEGV SIGSTOP
330898184e3Ssthen		SIGTERM SIGTSTP SIGTTIN SIGTTOU SIGUSR1 SIGUSR2 SIGBUS
331898184e3Ssthen		SIGPOLL SIGPROF SIGSYS SIGTRAP SIGURG SIGVTALRM SIGXCPU SIGXFSZ
332898184e3Ssthen		SIG_BLOCK SIG_DFL SIG_ERR SIG_IGN SIG_SETMASK SIG_UNBLOCK
333898184e3Ssthen		raise sigaction signal sigpending sigprocmask sigsuspend)],
334898184e3Ssthen
335898184e3Ssthen    stdarg_h =>	[],
336898184e3Ssthen
337898184e3Ssthen    stddef_h =>	[qw(NULL offsetof)],
338898184e3Ssthen
339898184e3Ssthen    stdio_h =>	[qw(BUFSIZ EOF FILENAME_MAX L_ctermid L_cuserid
3409f11ffb7Safresh1		NULL SEEK_CUR SEEK_END SEEK_SET
341898184e3Ssthen		STREAM_MAX TMP_MAX stderr stdin stdout
342898184e3Ssthen		clearerr fclose fdopen feof ferror fflush fgetc fgetpos
343898184e3Ssthen		fgets fopen fprintf fputc fputs fread freopen
344898184e3Ssthen		fscanf fseek fsetpos ftell fwrite getchar gets
345898184e3Ssthen		perror putc putchar puts remove rewind
346898184e3Ssthen		scanf setbuf setvbuf sscanf tmpfile tmpnam
347898184e3Ssthen		ungetc vfprintf vprintf vsprintf)],
348898184e3Ssthen
349898184e3Ssthen    stdlib_h =>	[qw(EXIT_FAILURE EXIT_SUCCESS MB_CUR_MAX NULL RAND_MAX
350898184e3Ssthen		abort atexit atof atoi atol bsearch calloc div
351898184e3Ssthen		free getenv labs ldiv malloc mblen mbstowcs mbtowc
352898184e3Ssthen		qsort realloc strtod strtol strtoul wcstombs wctomb)],
353898184e3Ssthen
354898184e3Ssthen    string_h =>	[qw(NULL memchr memcmp memcpy memmove memset strcat
355898184e3Ssthen		strchr strcmp strcoll strcpy strcspn strerror strlen
356898184e3Ssthen		strncat strncmp strncpy strpbrk strrchr strspn strstr
357898184e3Ssthen		strtok strxfrm)],
358898184e3Ssthen
359898184e3Ssthen    sys_stat_h => [qw(S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
360e0680481Safresh1		S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISLNK S_ISREG S_ISSOCK
361898184e3Ssthen		S_ISUID S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR
362898184e3Ssthen		fstat mkfifo)],
363898184e3Ssthen
364898184e3Ssthen    sys_times_h => [],
365898184e3Ssthen
366898184e3Ssthen    sys_types_h => [],
367898184e3Ssthen
368898184e3Ssthen    sys_utsname_h => [qw(uname)],
369898184e3Ssthen
370898184e3Ssthen    sys_wait_h => [qw(WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED
371898184e3Ssthen		WNOHANG WSTOPSIG WTERMSIG WUNTRACED)],
372898184e3Ssthen
373898184e3Ssthen    termios_h => [qw( B0 B110 B1200 B134 B150 B1800 B19200 B200 B2400
374898184e3Ssthen		B300 B38400 B4800 B50 B600 B75 B9600 BRKINT CLOCAL
375898184e3Ssthen		CREAD CS5 CS6 CS7 CS8 CSIZE CSTOPB ECHO ECHOE ECHOK
376898184e3Ssthen		ECHONL HUPCL ICANON ICRNL IEXTEN IGNBRK IGNCR IGNPAR
377898184e3Ssthen		INLCR INPCK ISIG ISTRIP IXOFF IXON NCCS NOFLSH OPOST
378898184e3Ssthen		PARENB PARMRK PARODD TCIFLUSH TCIOFF TCIOFLUSH TCION
379898184e3Ssthen		TCOFLUSH TCOOFF TCOON TCSADRAIN TCSAFLUSH TCSANOW
380898184e3Ssthen		TOSTOP VEOF VEOL VERASE VINTR VKILL VMIN VQUIT VSTART
381898184e3Ssthen		VSTOP VSUSP VTIME
382898184e3Ssthen		cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain
383898184e3Ssthen		tcflow tcflush tcgetattr tcsendbreak tcsetattr )],
384898184e3Ssthen
385898184e3Ssthen    time_h =>	[qw(CLK_TCK CLOCKS_PER_SEC NULL asctime clock ctime
386898184e3Ssthen		difftime mktime strftime tzset tzname)],
387898184e3Ssthen
388898184e3Ssthen    unistd_h =>	[qw(F_OK NULL R_OK SEEK_CUR SEEK_END SEEK_SET
389898184e3Ssthen		STDERR_FILENO STDIN_FILENO STDOUT_FILENO W_OK X_OK
390898184e3Ssthen		_PC_CHOWN_RESTRICTED _PC_LINK_MAX _PC_MAX_CANON
391898184e3Ssthen		_PC_MAX_INPUT _PC_NAME_MAX _PC_NO_TRUNC _PC_PATH_MAX
392898184e3Ssthen		_PC_PIPE_BUF _PC_VDISABLE _POSIX_CHOWN_RESTRICTED
393898184e3Ssthen		_POSIX_JOB_CONTROL _POSIX_NO_TRUNC _POSIX_SAVED_IDS
394898184e3Ssthen		_POSIX_VDISABLE _POSIX_VERSION _SC_ARG_MAX
395898184e3Ssthen		_SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL
396898184e3Ssthen		_SC_NGROUPS_MAX _SC_OPEN_MAX _SC_PAGESIZE _SC_SAVED_IDS
397898184e3Ssthen		_SC_STREAM_MAX _SC_TZNAME_MAX _SC_VERSION
398898184e3Ssthen		_exit access ctermid cuserid
399898184e3Ssthen		dup2 dup execl execle execlp execv execve execvp
400898184e3Ssthen		fpathconf fsync getcwd getegid geteuid getgid getgroups
401898184e3Ssthen		getpid getuid isatty lseek pathconf pause setgid setpgid
402898184e3Ssthen		setsid setuid sysconf tcgetpgrp tcsetpgrp ttyname)],
403898184e3Ssthen
404898184e3Ssthen    utime_h =>	[],
405898184e3Ssthen);
406898184e3Ssthen
407b8851fccSafresh1if ($^O eq 'MSWin32') {
408b8851fccSafresh1    $default_export_tags{winsock_h} = [qw(
409b8851fccSafresh1	WSAEINTR WSAEBADF WSAEACCES WSAEFAULT WSAEINVAL WSAEMFILE WSAEWOULDBLOCK
410b8851fccSafresh1	WSAEINPROGRESS WSAEALREADY WSAENOTSOCK WSAEDESTADDRREQ WSAEMSGSIZE
411b8851fccSafresh1	WSAEPROTOTYPE WSAENOPROTOOPT WSAEPROTONOSUPPORT WSAESOCKTNOSUPPORT
412b8851fccSafresh1	WSAEOPNOTSUPP WSAEPFNOSUPPORT WSAEAFNOSUPPORT WSAEADDRINUSE
413b8851fccSafresh1	WSAEADDRNOTAVAIL WSAENETDOWN WSAENETUNREACH WSAENETRESET WSAECONNABORTED
414b8851fccSafresh1	WSAECONNRESET WSAENOBUFS WSAEISCONN WSAENOTCONN WSAESHUTDOWN
415b8851fccSafresh1	WSAETOOMANYREFS WSAETIMEDOUT WSAECONNREFUSED WSAELOOP WSAENAMETOOLONG
416b8851fccSafresh1	WSAEHOSTDOWN WSAEHOSTUNREACH WSAENOTEMPTY WSAEPROCLIM WSAEUSERS
417b8851fccSafresh1	WSAEDQUOT WSAESTALE WSAEREMOTE WSAEDISCON WSAENOMORE WSAECANCELLED
418b8851fccSafresh1	WSAEINVALIDPROCTABLE WSAEINVALIDPROVIDER WSAEPROVIDERFAILEDINIT
419b8851fccSafresh1	WSAEREFUSED)];
420b8851fccSafresh1}
421b8851fccSafresh1
422b8851fccSafresh1my %other_export_tags = ( # cf. exports policy below
423b8851fccSafresh1    fenv_h => [qw(
424b8851fccSafresh1        FE_DOWNWARD FE_TONEAREST FE_TOWARDZERO FE_UPWARD fegetround fesetround
425b8851fccSafresh1    )],
426b8851fccSafresh1
427b8851fccSafresh1    math_h_c99 => [ @{$default_export_tags{math_h}}, qw(
428b8851fccSafresh1        Inf NaN acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma
429b8851fccSafresh1        fmax fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal
430b8851fccSafresh1        isinf isless islessequal islessgreater isnan isnormal isunordered j0 j1
4319f11ffb7Safresh1        jn lgamma log1p log2 logb lrint lround nan nearbyint nextafter nexttoward
432b8851fccSafresh1        remainder remquo rint round scalbn signbit tgamma trunc y0 y1 yn
433b8851fccSafresh1    )],
434b8851fccSafresh1
4359f11ffb7Safresh1    netdb_h => [qw(EAI_AGAIN    EAI_BADFLAGS EAI_FAIL
4369f11ffb7Safresh1                   EAI_FAMILY   EAI_MEMORY   EAI_NONAME
4379f11ffb7Safresh1                   EAI_OVERFLOW EAI_SERVICE  EAI_SOCKTYPE
4389f11ffb7Safresh1                   EAI_SYSTEM)],
4399f11ffb7Safresh1
440b8851fccSafresh1    stdlib_h_c99 => [ @{$default_export_tags{stdlib_h}}, 'strtold' ],
441b8851fccSafresh1
4429f11ffb7Safresh1    sys_resource_h => [qw(PRIO_PROCESS PRIO_PGRP PRIO_USER)],
4439f11ffb7Safresh1
4449f11ffb7Safresh1    sys_socket_h => [qw(
4459f11ffb7Safresh1        MSG_CTRUNC MSG_DONTROUTE MSG_EOR MSG_OOB MSG_PEEK MSG_TRUNC MSG_WAITALL
4469f11ffb7Safresh1    )],
4479f11ffb7Safresh1
448b8851fccSafresh1    nan_payload => [ qw(getpayload setpayload setpayloadsig issignaling) ],
449b8851fccSafresh1
450b8851fccSafresh1    signal_h_si_code => [qw(
451b8851fccSafresh1        ILL_ILLOPC ILL_ILLOPN ILL_ILLADR ILL_ILLTRP ILL_PRVOPC ILL_PRVREG
452b8851fccSafresh1        ILL_COPROC ILL_BADSTK
453b8851fccSafresh1        FPE_INTDIV FPE_INTOVF FPE_FLTDIV FPE_FLTOVF FPE_FLTUND
454b8851fccSafresh1        FPE_FLTRES FPE_FLTINV FPE_FLTSUB
455b8851fccSafresh1        SEGV_MAPERR SEGV_ACCERR
456b8851fccSafresh1        BUS_ADRALN BUS_ADRERR BUS_OBJERR
457b8851fccSafresh1        TRAP_BRKPT TRAP_TRACE
458b8851fccSafresh1        CLD_EXITED CLD_KILLED CLD_DUMPED CLD_TRAPPED CLD_STOPPED CLD_CONTINUED
459b8851fccSafresh1        POLL_IN POLL_OUT POLL_MSG POLL_ERR POLL_PRI POLL_HUP
460b8851fccSafresh1        SI_USER SI_QUEUE SI_TIMER SI_ASYNCIO SI_MESGQ
461b8851fccSafresh1  )],
462b8851fccSafresh1);
463b8851fccSafresh1
464b8851fccSafresh1# exports policy:
465b8851fccSafresh1# - new functions may not be added to @EXPORT, only to @EXPORT_OK
466b8851fccSafresh1# - new SHOUTYCONSTANTS are OK to add to @EXPORT
467b8851fccSafresh1
468898184e3Ssthen{
469898184e3Ssthen  # De-duplicate the export list:
470b8851fccSafresh1  my ( %export, %export_ok );
471b8851fccSafresh1  @export   {map {@$_} values %default_export_tags} = ();
472b8851fccSafresh1  @export_ok{map {@$_} values   %other_export_tags} = ();
473898184e3Ssthen  # Doing the de-dup with a temporary hash has the advantage that the SVs in
474898184e3Ssthen  # @EXPORT are actually shared hash key scalars, which will save some memory.
475898184e3Ssthen  our @EXPORT = keys %export;
476898184e3Ssthen
477b8851fccSafresh1  # you do not want to add symbols to the following list. add a new tag instead
478898184e3Ssthen  our @EXPORT_OK = (qw(close lchown nice open pipe read sleep times write
4799f11ffb7Safresh1		       printf sprintf),
480b8851fccSafresh1		    grep {!exists $export{$_}} keys %reimpl, keys %replacement, keys %export_ok);
481b8851fccSafresh1
482b8851fccSafresh1  our %EXPORT_TAGS = ( %default_export_tags, %other_export_tags );
483898184e3Ssthen}
484898184e3Ssthen
485898184e3Ssthenrequire Exporter;
486898184e3Ssthen}
487898184e3Ssthen
488898184e3Ssthenpackage POSIX::SigAction;
489898184e3Ssthen
490898184e3Ssthensub new { bless {HANDLER => $_[1], MASK => $_[2], FLAGS => $_[3] || 0, SAFE => 0}, $_[0] }
491898184e3Ssthensub handler { $_[0]->{HANDLER} = $_[1] if @_ > 1; $_[0]->{HANDLER} };
492898184e3Ssthensub mask    { $_[0]->{MASK}    = $_[1] if @_ > 1; $_[0]->{MASK} };
493898184e3Ssthensub flags   { $_[0]->{FLAGS}   = $_[1] if @_ > 1; $_[0]->{FLAGS} };
494898184e3Ssthensub safe    { $_[0]->{SAFE}    = $_[1] if @_ > 1; $_[0]->{SAFE} };
495898184e3Ssthen
496898184e3Ssthen{
497898184e3Ssthenpackage POSIX::SigSet;
498898184e3Ssthen# This package is here entirely to make sure that POSIX::SigSet is seen by the
499898184e3Ssthen# PAUSE indexer, so that it will always be clearly indexed in core.  This is to
500898184e3Ssthen# prevent the accidental case where a third-party distribution can accidentally
501898184e3Ssthen# claim the POSIX::SigSet package, as occurred in 2011-12. -- rjbs, 2011-12-30
502898184e3Ssthen}
503898184e3Ssthen
504898184e3Ssthenpackage POSIX::SigRt;
505898184e3Ssthen
506898184e3Ssthenrequire Tie::Hash;
507898184e3Ssthen
508898184e3Ssthenour @ISA = 'Tie::StdHash';
509898184e3Ssthen
510898184e3Ssthenour ($_SIGRTMIN, $_SIGRTMAX, $_sigrtn);
511898184e3Ssthen
512898184e3Ssthenour $SIGACTION_FLAGS = 0;
513898184e3Ssthen
514898184e3Ssthensub _init {
515898184e3Ssthen    $_SIGRTMIN = &POSIX::SIGRTMIN;
516898184e3Ssthen    $_SIGRTMAX = &POSIX::SIGRTMAX;
517898184e3Ssthen    $_sigrtn   = $_SIGRTMAX - $_SIGRTMIN;
518898184e3Ssthen}
519898184e3Ssthen
520898184e3Ssthensub _croak {
521898184e3Ssthen    &_init unless defined $_sigrtn;
522898184e3Ssthen    die "POSIX::SigRt not available" unless defined $_sigrtn && $_sigrtn > 0;
523898184e3Ssthen}
524898184e3Ssthen
525898184e3Ssthensub _getsig {
526898184e3Ssthen    &_croak;
527898184e3Ssthen    my $rtsig = $_[0];
528898184e3Ssthen    # Allow (SIGRT)?MIN( + n)?, a common idiom when doing these things in C.
529898184e3Ssthen    $rtsig = $_SIGRTMIN + ($1 || 0)
530898184e3Ssthen	if $rtsig =~ /^(?:(?:SIG)?RT)?MIN(\s*\+\s*(\d+))?$/;
531898184e3Ssthen    return $rtsig;
532898184e3Ssthen}
533898184e3Ssthen
534898184e3Ssthensub _exist {
535898184e3Ssthen    my $rtsig = _getsig($_[1]);
536898184e3Ssthen    my $ok    = $rtsig >= $_SIGRTMIN && $rtsig <= $_SIGRTMAX;
537898184e3Ssthen    ($rtsig, $ok);
538898184e3Ssthen}
539898184e3Ssthen
540898184e3Ssthensub _check {
541898184e3Ssthen    my ($rtsig, $ok) = &_exist;
542898184e3Ssthen    die "No POSIX::SigRt signal $_[1] (valid range SIGRTMIN..SIGRTMAX, or $_SIGRTMIN..$_SIGRTMAX)"
543898184e3Ssthen	unless $ok;
544898184e3Ssthen    return $rtsig;
545898184e3Ssthen}
546898184e3Ssthen
547898184e3Ssthensub new {
548898184e3Ssthen    my ($rtsig, $handler, $flags) = @_;
549898184e3Ssthen    my $sigset = POSIX::SigSet->new($rtsig);
550898184e3Ssthen    my $sigact = POSIX::SigAction->new($handler, $sigset, $flags);
551898184e3Ssthen    POSIX::sigaction($rtsig, $sigact);
552898184e3Ssthen}
553898184e3Ssthen
554898184e3Ssthensub EXISTS { &_exist }
555898184e3Ssthensub FETCH  { my $rtsig = &_check;
556898184e3Ssthen	     my $oa = POSIX::SigAction->new();
557898184e3Ssthen	     POSIX::sigaction($rtsig, undef, $oa);
558898184e3Ssthen	     return $oa->{HANDLER} }
559898184e3Ssthensub STORE  { my $rtsig = &_check; new($rtsig, $_[2], $SIGACTION_FLAGS) }
560898184e3Ssthensub DELETE { delete $SIG{ &_check } }
561898184e3Ssthensub CLEAR  { &_exist; delete @SIG{ &POSIX::SIGRTMIN .. &POSIX::SIGRTMAX } }
562898184e3Ssthensub SCALAR { &_croak; $_sigrtn + 1 }
563898184e3Ssthen
564898184e3Ssthentie %POSIX::SIGRT, 'POSIX::SigRt';
565898184e3Ssthen# and the expression on the line above is true, so we return true.
566