a63ff15acc85bb0b5baff75097064cb6b475d347
[p5sagit/p5-mst-13.2.git] / ext / POSIX / POSIX.pm
1 package POSIX;
2
3 our(@ISA, %EXPORT_TAGS, @EXPORT_OK, $AUTOLOAD, %SIGRT) = ();
4
5 our $VERSION = "1.11";
6
7 use AutoLoader;
8
9 use XSLoader ();
10
11 use Fcntl qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK F_SETFD
12              F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK O_ACCMODE O_APPEND
13              O_CREAT O_EXCL O_NOCTTY O_NONBLOCK O_RDONLY O_RDWR O_TRUNC
14              O_WRONLY);
15
16 # Grandfather old foo_h form to new :foo_h form
17 my $loaded;
18
19 sub import {
20     load_imports() unless $loaded++;
21     my $this = shift;
22     my @list = map { m/^\w+_h$/ ? ":$_" : $_ } @_;
23     local $Exporter::ExportLevel = 1;
24     Exporter::import($this,@list);
25 }
26
27 sub croak { require Carp;  goto &Carp::croak }
28 # declare usage to assist AutoLoad
29 sub usage;
30
31 XSLoader::load 'POSIX', $VERSION;
32
33 my %NON_CONSTS = (map {($_,1)}
34                   qw(S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG WEXITSTATUS
35                      WIFEXITED WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG));
36
37 sub AUTOLOAD {
38     if ($AUTOLOAD =~ /::(_?[a-z])/) {
39         # require AutoLoader;
40         $AutoLoader::AUTOLOAD = $AUTOLOAD;
41         goto &AutoLoader::AUTOLOAD
42     }
43     local $! = 0;
44     my $constname = $AUTOLOAD;
45     $constname =~ s/.*:://;
46     if ($NON_CONSTS{$constname}) {
47         my ($val, $error) = &int_macro_int($constname, $_[0]);
48         croak $error if $error;
49         *$AUTOLOAD = sub { &int_macro_int($constname, $_[0]) };
50     } else {
51         my ($error, $val) = constant($constname);
52         croak $error if $error;
53         *$AUTOLOAD = sub { $val };
54     }
55
56     goto &$AUTOLOAD;
57 }
58
59 package POSIX::SigAction;
60
61 use AutoLoader 'AUTOLOAD';
62
63 package POSIX::SigRt;
64
65 use strict;
66
67 use Tie::Hash;
68 use base qw(Tie::StdHash);
69
70 use vars qw($SIGACTION_FLAGS);
71
72 $SIGACTION_FLAGS = 0;
73
74 my ($SIGRTMIN, $SIGRTMAX, $sigrtn);
75
76 sub _init {
77     $SIGRTMIN = &POSIX::SIGRTMIN;
78     $SIGRTMAX = &POSIX::SIGRTMAX;
79     $sigrtn   = $SIGRTMAX - $SIGRTMIN;
80 }
81
82 sub _croak {
83     &_init unless defined $sigrtn;
84     die "POSIX::SigRt not available" unless defined $sigrtn && $sigrtn > 0;
85 }
86
87 sub _getsig {
88     &_croak;
89     my $rtsig = $_[0];
90     # Allow (SIGRT)?MIN( + n)?, a common idiom when doing these things in C.
91     $rtsig = $SIGRTMIN + ($1 || 0)
92         if $rtsig =~ /^(?:(?:SIG)?RT)?MIN(\s*\+\s*(\d+))?$/;
93     return $rtsig;
94 }
95
96 sub _exist {
97     my $rtsig = _getsig($_[1]);
98     my $ok    = $rtsig >= $SIGRTMIN && $rtsig <= $SIGRTMAX;
99     ($rtsig, $ok);
100 }
101
102 sub _check {
103     my ($rtsig, $ok) = &_exist;
104     die "No POSIX::SigRt signal $_[1] (valid range SIGRTMIN..SIGRTMAX, or $SIGRTMIN..$SIGRTMAX)"
105         unless $ok;
106     return $rtsig;
107 }
108
109 sub new {
110     my ($rtsig, $handler, $flags) = @_;
111     my $sigset = POSIX::SigSet->new($rtsig);
112     my $sigact = POSIX::SigAction->new($handler,
113                                        $sigset,
114                                        $flags);
115     POSIX::sigaction($rtsig, $sigact);
116 }
117
118 sub EXISTS { &_exist }
119 sub FETCH  { my $rtsig = &_check;
120              my $oa = POSIX::SigAction->new();
121              POSIX::sigaction($rtsig, undef, $oa);
122              return $oa->{HANDLER} }
123 sub STORE  { my $rtsig = &_check; new($rtsig, $_[2], $SIGACTION_FLAGS) }
124 sub DELETE { delete $SIG{ &_check } }
125 sub CLEAR  { &_exist; delete @SIG{ &POSIX::SIGRTMIN .. &POSIX::SIGRTMAX } }
126 sub SCALAR { &_croak; $sigrtn + 1 }
127
128 tie %POSIX::SIGRT, 'POSIX::SigRt';
129
130 package POSIX;
131
132 1;
133 __END__
134
135 sub usage {
136     my ($mess) = @_;
137     croak "Usage: POSIX::$mess";
138 }
139
140 sub redef {
141     my ($mess) = @_;
142     croak "Use method $mess instead";
143 }
144
145 sub unimpl {
146     my ($mess) = @_;
147     $mess =~ s/xxx//;
148     croak "Unimplemented: POSIX::$mess";
149 }
150
151 sub assert {
152     usage "assert(expr)" if @_ != 1;
153     if (!$_[0]) {
154         croak "Assertion failed";
155     }
156 }
157
158 sub tolower {
159     usage "tolower(string)" if @_ != 1;
160     lc($_[0]);
161 }
162
163 sub toupper {
164     usage "toupper(string)" if @_ != 1;
165     uc($_[0]);
166 }
167
168 sub closedir {
169     usage "closedir(dirhandle)" if @_ != 1;
170     CORE::closedir($_[0]);
171 }
172
173 sub opendir {
174     usage "opendir(directory)" if @_ != 1;
175     my $dirhandle;
176     CORE::opendir($dirhandle, $_[0])
177         ? $dirhandle
178         : undef;
179 }
180
181 sub readdir {
182     usage "readdir(dirhandle)" if @_ != 1;
183     CORE::readdir($_[0]);
184 }
185
186 sub rewinddir {
187     usage "rewinddir(dirhandle)" if @_ != 1;
188     CORE::rewinddir($_[0]);
189 }
190
191 sub errno {
192     usage "errno()" if @_ != 0;
193     $! + 0;
194 }
195
196 sub creat {
197     usage "creat(filename, mode)" if @_ != 2;
198     &open($_[0], &O_WRONLY | &O_CREAT | &O_TRUNC, $_[1]);
199 }
200
201 sub fcntl {
202     usage "fcntl(filehandle, cmd, arg)" if @_ != 3;
203     CORE::fcntl($_[0], $_[1], $_[2]);
204 }
205
206 sub getgrgid {
207     usage "getgrgid(gid)" if @_ != 1;
208     CORE::getgrgid($_[0]);
209 }
210
211 sub getgrnam {
212     usage "getgrnam(name)" if @_ != 1;
213     CORE::getgrnam($_[0]);
214 }
215
216 sub atan2 {
217     usage "atan2(x,y)" if @_ != 2;
218     CORE::atan2($_[0], $_[1]);
219 }
220
221 sub cos {
222     usage "cos(x)" if @_ != 1;
223     CORE::cos($_[0]);
224 }
225
226 sub exp {
227     usage "exp(x)" if @_ != 1;
228     CORE::exp($_[0]);
229 }
230
231 sub fabs {
232     usage "fabs(x)" if @_ != 1;
233     CORE::abs($_[0]);
234 }
235
236 sub log {
237     usage "log(x)" if @_ != 1;
238     CORE::log($_[0]);
239 }
240
241 sub pow {
242     usage "pow(x,exponent)" if @_ != 2;
243     $_[0] ** $_[1];
244 }
245
246 sub sin {
247     usage "sin(x)" if @_ != 1;
248     CORE::sin($_[0]);
249 }
250
251 sub sqrt {
252     usage "sqrt(x)" if @_ != 1;
253     CORE::sqrt($_[0]);
254 }
255
256 sub getpwnam {
257     usage "getpwnam(name)" if @_ != 1;
258     CORE::getpwnam($_[0]);
259 }
260
261 sub getpwuid {
262     usage "getpwuid(uid)" if @_ != 1;
263     CORE::getpwuid($_[0]);
264 }
265
266 sub longjmp {
267     unimpl "longjmp() is C-specific: use die instead";
268 }
269
270 sub setjmp {
271     unimpl "setjmp() is C-specific: use eval {} instead";
272 }
273
274 sub siglongjmp {
275     unimpl "siglongjmp() is C-specific: use die instead";
276 }
277
278 sub sigsetjmp {
279     unimpl "sigsetjmp() is C-specific: use eval {} instead";
280 }
281
282 sub kill {
283     usage "kill(pid, sig)" if @_ != 2;
284     CORE::kill $_[1], $_[0];
285 }
286
287 sub raise {
288     usage "raise(sig)" if @_ != 1;
289     CORE::kill $_[0], $$;       # Is this good enough?
290 }
291
292 sub offsetof {
293     unimpl "offsetof() is C-specific, stopped";
294 }
295
296 sub clearerr {
297     redef "IO::Handle::clearerr()";
298 }
299
300 sub fclose {
301     redef "IO::Handle::close()";
302 }
303
304 sub fdopen {
305     redef "IO::Handle::new_from_fd()";
306 }
307
308 sub feof {
309     redef "IO::Handle::eof()";
310 }
311
312 sub fgetc {
313     redef "IO::Handle::getc()";
314 }
315
316 sub fgets {
317     redef "IO::Handle::gets()";
318 }
319
320 sub fileno {
321     redef "IO::Handle::fileno()";
322 }
323
324 sub fopen {
325     redef "IO::File::open()";
326 }
327
328 sub fprintf {
329     unimpl "fprintf() is C-specific--use printf instead";
330 }
331
332 sub fputc {
333     unimpl "fputc() is C-specific--use print instead";
334 }
335
336 sub fputs {
337     unimpl "fputs() is C-specific--use print instead";
338 }
339
340 sub fread {
341     unimpl "fread() is C-specific--use read instead";
342 }
343
344 sub freopen {
345     unimpl "freopen() is C-specific--use open instead";
346 }
347
348 sub fscanf {
349     unimpl "fscanf() is C-specific--use <> and regular expressions instead";
350 }
351
352 sub fseek {
353     redef "IO::Seekable::seek()";
354 }
355
356 sub fsync {
357     redef "IO::Handle::sync()";
358 }
359
360 sub ferror {
361     redef "IO::Handle::error()";
362 }
363
364 sub fflush {
365     redef "IO::Handle::flush()";
366 }
367
368 sub fgetpos {
369     redef "IO::Seekable::getpos()";
370 }
371
372 sub fsetpos {
373     redef "IO::Seekable::setpos()";
374 }
375
376 sub ftell {
377     redef "IO::Seekable::tell()";
378 }
379
380 sub fwrite {
381     unimpl "fwrite() is C-specific--use print instead";
382 }
383
384 sub getc {
385     usage "getc(handle)" if @_ != 1;
386     CORE::getc($_[0]);
387 }
388
389 sub getchar {
390     usage "getchar()" if @_ != 0;
391     CORE::getc(STDIN);
392 }
393
394 sub gets {
395     usage "gets()" if @_ != 0;
396     scalar <STDIN>;
397 }
398
399 sub perror {
400     print STDERR "@_: " if @_;
401     print STDERR $!,"\n";
402 }
403
404 sub printf {
405     usage "printf(pattern, args...)" if @_ < 1;
406     CORE::printf STDOUT @_;
407 }
408
409 sub putc {
410     unimpl "putc() is C-specific--use print instead";
411 }
412
413 sub putchar {
414     unimpl "putchar() is C-specific--use print instead";
415 }
416
417 sub puts {
418     unimpl "puts() is C-specific--use print instead";
419 }
420
421 sub remove {
422     usage "remove(filename)" if @_ != 1;
423     (-d $_[0]) ? CORE::rmdir($_[0]) : CORE::unlink($_[0]);
424 }
425
426 sub rename {
427     usage "rename(oldfilename, newfilename)" if @_ != 2;
428     CORE::rename($_[0], $_[1]);
429 }
430
431 sub rewind {
432     usage "rewind(filehandle)" if @_ != 1;
433     CORE::seek($_[0],0,0);
434 }
435
436 sub scanf {
437     unimpl "scanf() is C-specific--use <> and regular expressions instead";
438 }
439
440 sub sprintf {
441     usage "sprintf(pattern,args)" if @_ == 0;
442     CORE::sprintf(shift,@_);
443 }
444
445 sub sscanf {
446     unimpl "sscanf() is C-specific--use regular expressions instead";
447 }
448
449 sub tmpfile {
450     redef "IO::File::new_tmpfile()";
451 }
452
453 sub ungetc {
454     redef "IO::Handle::ungetc()";
455 }
456
457 sub vfprintf {
458     unimpl "vfprintf() is C-specific";
459 }
460
461 sub vprintf {
462     unimpl "vprintf() is C-specific";
463 }
464
465 sub vsprintf {
466     unimpl "vsprintf() is C-specific";
467 }
468
469 sub abs {
470     usage "abs(x)" if @_ != 1;
471     CORE::abs($_[0]);
472 }
473
474 sub atexit {
475     unimpl "atexit() is C-specific: use END {} instead";
476 }
477
478 sub atof {
479     unimpl "atof() is C-specific, stopped";
480 }
481
482 sub atoi {
483     unimpl "atoi() is C-specific, stopped";
484 }
485
486 sub atol {
487     unimpl "atol() is C-specific, stopped";
488 }
489
490 sub bsearch {
491     unimpl "bsearch() not supplied";
492 }
493
494 sub calloc {
495     unimpl "calloc() is C-specific, stopped";
496 }
497
498 sub div {
499     unimpl "div() is C-specific, use /, % and int instead";
500 }
501
502 sub exit {
503     usage "exit(status)" if @_ != 1;
504     CORE::exit($_[0]);
505 }
506
507 sub free {
508     unimpl "free() is C-specific, stopped";
509 }
510
511 sub getenv {
512     usage "getenv(name)" if @_ != 1;
513     $ENV{$_[0]};
514 }
515
516 sub labs {
517     unimpl "labs() is C-specific, use abs instead";
518 }
519
520 sub ldiv {
521     unimpl "ldiv() is C-specific, use /, % and int instead";
522 }
523
524 sub malloc {
525     unimpl "malloc() is C-specific, stopped";
526 }
527
528 sub qsort {
529     unimpl "qsort() is C-specific, use sort instead";
530 }
531
532 sub rand {
533     unimpl "rand() is non-portable, use Perl's rand instead";
534 }
535
536 sub realloc {
537     unimpl "realloc() is C-specific, stopped";
538 }
539
540 sub srand {
541     unimpl "srand()";
542 }
543
544 sub system {
545     usage "system(command)" if @_ != 1;
546     CORE::system($_[0]);
547 }
548
549 sub memchr {
550     unimpl "memchr() is C-specific, use index() instead";
551 }
552
553 sub memcmp {
554     unimpl "memcmp() is C-specific, use eq instead";
555 }
556
557 sub memcpy {
558     unimpl "memcpy() is C-specific, use = instead";
559 }
560
561 sub memmove {
562     unimpl "memmove() is C-specific, use = instead";
563 }
564
565 sub memset {
566     unimpl "memset() is C-specific, use x instead";
567 }
568
569 sub strcat {
570     unimpl "strcat() is C-specific, use .= instead";
571 }
572
573 sub strchr {
574     unimpl "strchr() is C-specific, use index() instead";
575 }
576
577 sub strcmp {
578     unimpl "strcmp() is C-specific, use eq instead";
579 }
580
581 sub strcpy {
582     unimpl "strcpy() is C-specific, use = instead";
583 }
584
585 sub strcspn {
586     unimpl "strcspn() is C-specific, use regular expressions instead";
587 }
588
589 sub strerror {
590     usage "strerror(errno)" if @_ != 1;
591     local $! = $_[0];
592     $! . "";
593 }
594
595 sub strlen {
596     unimpl "strlen() is C-specific, use length instead";
597 }
598
599 sub strncat {
600     unimpl "strncat() is C-specific, use .= instead";
601 }
602
603 sub strncmp {
604     unimpl "strncmp() is C-specific, use eq instead";
605 }
606
607 sub strncpy {
608     unimpl "strncpy() is C-specific, use = instead";
609 }
610
611 sub strpbrk {
612     unimpl "strpbrk() is C-specific, stopped";
613 }
614
615 sub strrchr {
616     unimpl "strrchr() is C-specific, use rindex() instead";
617 }
618
619 sub strspn {
620     unimpl "strspn() is C-specific, stopped";
621 }
622
623 sub strstr {
624     usage "strstr(big, little)" if @_ != 2;
625     CORE::index($_[0], $_[1]);
626 }
627
628 sub strtok {
629     unimpl "strtok() is C-specific, stopped";
630 }
631
632 sub chmod {
633     usage "chmod(mode, filename)" if @_ != 2;
634     CORE::chmod($_[0], $_[1]);
635 }
636
637 sub fstat {
638     usage "fstat(fd)" if @_ != 1;
639     local *TMP;
640     CORE::open(TMP, "<&$_[0]");         # Gross.
641     my @l = CORE::stat(TMP);
642     CORE::close(TMP);
643     @l;
644 }
645
646 sub mkdir {
647     usage "mkdir(directoryname, mode)" if @_ != 2;
648     CORE::mkdir($_[0], $_[1]);
649 }
650
651 sub stat {
652     usage "stat(filename)" if @_ != 1;
653     CORE::stat($_[0]);
654 }
655
656 sub umask {
657     usage "umask(mask)" if @_ != 1;
658     CORE::umask($_[0]);
659 }
660
661 sub wait {
662     usage "wait()" if @_ != 0;
663     CORE::wait();
664 }
665
666 sub waitpid {
667     usage "waitpid(pid, options)" if @_ != 2;
668     CORE::waitpid($_[0], $_[1]);
669 }
670
671 sub gmtime {
672     usage "gmtime(time)" if @_ != 1;
673     CORE::gmtime($_[0]);
674 }
675
676 sub localtime {
677     usage "localtime(time)" if @_ != 1;
678     CORE::localtime($_[0]);
679 }
680
681 sub time {
682     usage "time()" if @_ != 0;
683     CORE::time;
684 }
685
686 sub alarm {
687     usage "alarm(seconds)" if @_ != 1;
688     CORE::alarm($_[0]);
689 }
690
691 sub chdir {
692     usage "chdir(directory)" if @_ != 1;
693     CORE::chdir($_[0]);
694 }
695
696 sub chown {
697     usage "chown(uid, gid, filename)" if @_ != 3;
698     CORE::chown($_[0], $_[1], $_[2]);
699 }
700
701 sub execl {
702     unimpl "execl() is C-specific, stopped";
703 }
704
705 sub execle {
706     unimpl "execle() is C-specific, stopped";
707 }
708
709 sub execlp {
710     unimpl "execlp() is C-specific, stopped";
711 }
712
713 sub execv {
714     unimpl "execv() is C-specific, stopped";
715 }
716
717 sub execve {
718     unimpl "execve() is C-specific, stopped";
719 }
720
721 sub execvp {
722     unimpl "execvp() is C-specific, stopped";
723 }
724
725 sub fork {
726     usage "fork()" if @_ != 0;
727     CORE::fork;
728 }
729
730 sub getegid {
731     usage "getegid()" if @_ != 0;
732     $) + 0;
733 }
734
735 sub geteuid {
736     usage "geteuid()" if @_ != 0;
737     $> + 0;
738 }
739
740 sub getgid {
741     usage "getgid()" if @_ != 0;
742     $( + 0;
743 }
744
745 sub getgroups {
746     usage "getgroups()" if @_ != 0;
747     my %seen;
748     grep(!$seen{$_}++, split(' ', $) ));
749 }
750
751 sub getlogin {
752     usage "getlogin()" if @_ != 0;
753     CORE::getlogin();
754 }
755
756 sub getpgrp {
757     usage "getpgrp()" if @_ != 0;
758     CORE::getpgrp;
759 }
760
761 sub getpid {
762     usage "getpid()" if @_ != 0;
763     $$;
764 }
765
766 sub getppid {
767     usage "getppid()" if @_ != 0;
768     CORE::getppid;
769 }
770
771 sub getuid {
772     usage "getuid()" if @_ != 0;
773     $<;
774 }
775
776 sub isatty {
777     usage "isatty(filehandle)" if @_ != 1;
778     -t $_[0];
779 }
780
781 sub link {
782     usage "link(oldfilename, newfilename)" if @_ != 2;
783     CORE::link($_[0], $_[1]);
784 }
785
786 sub rmdir {
787     usage "rmdir(directoryname)" if @_ != 1;
788     CORE::rmdir($_[0]);
789 }
790
791 sub setbuf {
792     redef "IO::Handle::setbuf()";
793 }
794
795 sub setvbuf {
796     redef "IO::Handle::setvbuf()";
797 }
798
799 sub sleep {
800     usage "sleep(seconds)" if @_ != 1;
801     $_[0] - CORE::sleep($_[0]);
802 }
803
804 sub unlink {
805     usage "unlink(filename)" if @_ != 1;
806     CORE::unlink($_[0]);
807 }
808
809 sub utime {
810     usage "utime(filename, atime, mtime)" if @_ != 3;
811     CORE::utime($_[1], $_[2], $_[0]);
812 }
813
814 sub load_imports {
815 %EXPORT_TAGS = (
816
817     assert_h => [qw(assert NDEBUG)],
818
819     ctype_h =>  [qw(isalnum isalpha iscntrl isdigit isgraph islower
820                 isprint ispunct isspace isupper isxdigit tolower toupper)],
821
822     dirent_h => [],
823
824     errno_h =>  [qw(E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EAFNOSUPPORT
825                 EAGAIN EALREADY EBADF EBUSY ECHILD ECONNABORTED
826                 ECONNREFUSED ECONNRESET EDEADLK EDESTADDRREQ EDOM EDQUOT
827                 EEXIST EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EINPROGRESS
828                 EINTR EINVAL EIO EISCONN EISDIR ELOOP EMFILE EMLINK
829                 EMSGSIZE ENAMETOOLONG ENETDOWN ENETRESET ENETUNREACH
830                 ENFILE ENOBUFS ENODEV ENOENT ENOEXEC ENOLCK ENOMEM
831                 ENOPROTOOPT ENOSPC ENOSYS ENOTBLK ENOTCONN ENOTDIR
832                 ENOTEMPTY ENOTSOCK ENOTTY ENXIO EOPNOTSUPP EPERM
833                 EPFNOSUPPORT EPIPE EPROCLIM EPROTONOSUPPORT EPROTOTYPE
834                 ERANGE EREMOTE ERESTART EROFS ESHUTDOWN ESOCKTNOSUPPORT
835                 ESPIPE ESRCH ESTALE ETIMEDOUT ETOOMANYREFS ETXTBSY
836                 EUSERS EWOULDBLOCK EXDEV errno)],
837
838     fcntl_h =>  [qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK
839                 F_SETFD F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK
840                 O_ACCMODE O_APPEND O_CREAT O_EXCL O_NOCTTY O_NONBLOCK
841                 O_RDONLY O_RDWR O_TRUNC O_WRONLY
842                 creat
843                 SEEK_CUR SEEK_END SEEK_SET
844                 S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
845                 S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISREG S_ISUID
846                 S_IWGRP S_IWOTH S_IWUSR)],
847
848     float_h =>  [qw(DBL_DIG DBL_EPSILON DBL_MANT_DIG
849                 DBL_MAX DBL_MAX_10_EXP DBL_MAX_EXP
850                 DBL_MIN DBL_MIN_10_EXP DBL_MIN_EXP
851                 FLT_DIG FLT_EPSILON FLT_MANT_DIG
852                 FLT_MAX FLT_MAX_10_EXP FLT_MAX_EXP
853                 FLT_MIN FLT_MIN_10_EXP FLT_MIN_EXP
854                 FLT_RADIX FLT_ROUNDS
855                 LDBL_DIG LDBL_EPSILON LDBL_MANT_DIG
856                 LDBL_MAX LDBL_MAX_10_EXP LDBL_MAX_EXP
857                 LDBL_MIN LDBL_MIN_10_EXP LDBL_MIN_EXP)],
858
859     grp_h =>    [],
860
861     limits_h => [qw( ARG_MAX CHAR_BIT CHAR_MAX CHAR_MIN CHILD_MAX
862                 INT_MAX INT_MIN LINK_MAX LONG_MAX LONG_MIN MAX_CANON
863                 MAX_INPUT MB_LEN_MAX NAME_MAX NGROUPS_MAX OPEN_MAX
864                 PATH_MAX PIPE_BUF SCHAR_MAX SCHAR_MIN SHRT_MAX SHRT_MIN
865                 SSIZE_MAX STREAM_MAX TZNAME_MAX UCHAR_MAX UINT_MAX
866                 ULONG_MAX USHRT_MAX _POSIX_ARG_MAX _POSIX_CHILD_MAX
867                 _POSIX_LINK_MAX _POSIX_MAX_CANON _POSIX_MAX_INPUT
868                 _POSIX_NAME_MAX _POSIX_NGROUPS_MAX _POSIX_OPEN_MAX
869                 _POSIX_PATH_MAX _POSIX_PIPE_BUF _POSIX_SSIZE_MAX
870                 _POSIX_STREAM_MAX _POSIX_TZNAME_MAX)],
871
872     locale_h => [qw(LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES
873                     LC_MONETARY LC_NUMERIC LC_TIME NULL
874                     localeconv setlocale)],
875
876     math_h =>   [qw(HUGE_VAL acos asin atan ceil cosh fabs floor fmod
877                 frexp ldexp log10 modf pow sinh tan tanh)],
878
879     pwd_h =>    [],
880
881     setjmp_h => [qw(longjmp setjmp siglongjmp sigsetjmp)],
882
883     signal_h => [qw(SA_NOCLDSTOP SA_NOCLDWAIT SA_NODEFER SA_ONSTACK
884                 SA_RESETHAND SA_RESTART SA_SIGINFO SIGABRT SIGALRM
885                 SIGCHLD SIGCONT SIGFPE SIGHUP SIGILL SIGINT SIGKILL
886                 SIGPIPE %SIGRT SIGRTMIN SIGRTMAX SIGQUIT SIGSEGV SIGSTOP
887                 SIGTERM SIGTSTP SIGTTIN SIGTTOU SIGUSR1 SIGUSR2
888                 SIG_BLOCK SIG_DFL SIG_ERR SIG_IGN SIG_SETMASK SIG_UNBLOCK
889                 raise sigaction signal sigpending sigprocmask sigsuspend)],
890
891     stdarg_h => [],
892
893     stddef_h => [qw(NULL offsetof)],
894
895     stdio_h =>  [qw(BUFSIZ EOF FILENAME_MAX L_ctermid L_cuserid
896                 L_tmpname NULL SEEK_CUR SEEK_END SEEK_SET
897                 STREAM_MAX TMP_MAX stderr stdin stdout
898                 clearerr fclose fdopen feof ferror fflush fgetc fgetpos
899                 fgets fopen fprintf fputc fputs fread freopen
900                 fscanf fseek fsetpos ftell fwrite getchar gets
901                 perror putc putchar puts remove rewind
902                 scanf setbuf setvbuf sscanf tmpfile tmpnam
903                 ungetc vfprintf vprintf vsprintf)],
904
905     stdlib_h => [qw(EXIT_FAILURE EXIT_SUCCESS MB_CUR_MAX NULL RAND_MAX
906                 abort atexit atof atoi atol bsearch calloc div
907                 free getenv labs ldiv malloc mblen mbstowcs mbtowc
908                 qsort realloc strtod strtol strtoul wcstombs wctomb)],
909
910     string_h => [qw(NULL memchr memcmp memcpy memmove memset strcat
911                 strchr strcmp strcoll strcpy strcspn strerror strlen
912                 strncat strncmp strncpy strpbrk strrchr strspn strstr
913                 strtok strxfrm)],
914
915     sys_stat_h => [qw(S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
916                 S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISREG
917                 S_ISUID S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR
918                 fstat mkfifo)],
919
920     sys_times_h => [],
921
922     sys_types_h => [],
923
924     sys_utsname_h => [qw(uname)],
925
926     sys_wait_h => [qw(WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED
927                 WNOHANG WSTOPSIG WTERMSIG WUNTRACED)],
928
929     termios_h => [qw( B0 B110 B1200 B134 B150 B1800 B19200 B200 B2400
930                 B300 B38400 B4800 B50 B600 B75 B9600 BRKINT CLOCAL
931                 CREAD CS5 CS6 CS7 CS8 CSIZE CSTOPB ECHO ECHOE ECHOK
932                 ECHONL HUPCL ICANON ICRNL IEXTEN IGNBRK IGNCR IGNPAR
933                 INLCR INPCK ISIG ISTRIP IXOFF IXON NCCS NOFLSH OPOST
934                 PARENB PARMRK PARODD TCIFLUSH TCIOFF TCIOFLUSH TCION
935                 TCOFLUSH TCOOFF TCOON TCSADRAIN TCSAFLUSH TCSANOW
936                 TOSTOP VEOF VEOL VERASE VINTR VKILL VMIN VQUIT VSTART
937                 VSTOP VSUSP VTIME
938                 cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain
939                 tcflow tcflush tcgetattr tcsendbreak tcsetattr )],
940
941     time_h =>   [qw(CLK_TCK CLOCKS_PER_SEC NULL asctime clock ctime
942                 difftime mktime strftime tzset tzname)],
943
944     unistd_h => [qw(F_OK NULL R_OK SEEK_CUR SEEK_END SEEK_SET
945                 STDERR_FILENO STDIN_FILENO STDOUT_FILENO W_OK X_OK
946                 _PC_CHOWN_RESTRICTED _PC_LINK_MAX _PC_MAX_CANON
947                 _PC_MAX_INPUT _PC_NAME_MAX _PC_NO_TRUNC _PC_PATH_MAX
948                 _PC_PIPE_BUF _PC_VDISABLE _POSIX_CHOWN_RESTRICTED
949                 _POSIX_JOB_CONTROL _POSIX_NO_TRUNC _POSIX_SAVED_IDS
950                 _POSIX_VDISABLE _POSIX_VERSION _SC_ARG_MAX
951                 _SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL
952                 _SC_NGROUPS_MAX _SC_OPEN_MAX _SC_PAGESIZE _SC_SAVED_IDS
953                 _SC_STREAM_MAX _SC_TZNAME_MAX _SC_VERSION
954                 _exit access ctermid cuserid
955                 dup2 dup execl execle execlp execv execve execvp
956                 fpathconf fsync getcwd getegid geteuid getgid getgroups
957                 getpid getuid isatty lseek pathconf pause setgid setpgid
958                 setsid setuid sysconf tcgetpgrp tcsetpgrp ttyname)],
959
960     utime_h =>  [],
961
962 );
963
964 # Exporter::export_tags();
965 {
966   # De-duplicate the export list: 
967   my %export;
968   @export{map {@$_} values %EXPORT_TAGS} = ();
969   # Doing the de-dup with a temporary hash has the advantage that the SVs in
970   # @EXPORT are actually shared hash key sacalars, which will save some memory.
971   push @EXPORT, keys %export;
972 }
973
974 @EXPORT_OK = qw(
975                 abs
976                 alarm
977                 atan2
978                 chdir
979                 chmod
980                 chown
981                 close
982                 closedir
983                 cos
984                 exit
985                 exp
986                 fcntl
987                 fileno
988                 fork
989                 getc
990                 getgrgid
991                 getgrnam
992                 getlogin
993                 getpgrp
994                 getppid
995                 getpwnam
996                 getpwuid
997                 gmtime
998                 isatty
999                 kill
1000                 lchown
1001                 link
1002                 localtime
1003                 log
1004                 mkdir
1005                 nice
1006                 open
1007                 opendir
1008                 pipe
1009                 printf
1010                 rand
1011                 read
1012                 readdir
1013                 rename
1014                 rewinddir
1015                 rmdir
1016                 sin
1017                 sleep
1018                 sprintf
1019                 sqrt
1020                 srand
1021                 stat
1022                 system
1023                 time
1024                 times
1025                 umask
1026                 unlink
1027                 utime
1028                 wait
1029                 waitpid
1030                 write
1031 );
1032
1033 require Exporter;
1034 }
1035
1036 package POSIX::SigAction;
1037
1038 sub new { bless {HANDLER => $_[1], MASK => $_[2], FLAGS => $_[3] || 0, SAFE => 0}, $_[0] }
1039 sub handler { $_[0]->{HANDLER} = $_[1] if @_ > 1; $_[0]->{HANDLER} };
1040 sub mask    { $_[0]->{MASK}    = $_[1] if @_ > 1; $_[0]->{MASK} };
1041 sub flags   { $_[0]->{FLAGS}   = $_[1] if @_ > 1; $_[0]->{FLAGS} };
1042 sub safe    { $_[0]->{SAFE}    = $_[1] if @_ > 1; $_[0]->{SAFE} };
1043