5 our(@ISA, %EXPORT_TAGS, @EXPORT_OK, @EXPORT, $AUTOLOAD, %SIGRT) = ();
13 use Fcntl qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK F_SETFD
14 F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK O_ACCMODE O_APPEND
15 O_CREAT O_EXCL O_NOCTTY O_NONBLOCK O_RDONLY O_RDWR O_TRUNC
16 O_WRONLY SEEK_CUR SEEK_END SEEK_SET
17 S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG
18 S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU S_ISGID S_ISUID
19 S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR);
26 load_imports() unless $loaded++;
28 # Grandfather old foo_h form to new :foo_h form
29 s/^(?=\w+_h$)/:/ for my @list = @_;
31 local $Exporter::ExportLevel = 1;
32 Exporter::import($pkg,@list);
35 sub croak { require Carp; goto &Carp::croak }
36 # declare usage to assist AutoLoad
46 bsearch => \'not supplied',
48 clearerr => 'IO::Handle::clearerr',
49 div => '/, % and int',
56 fclose => 'IO::Handle::close',
57 fdopen => 'IO::Handle::new_from_fd',
58 feof => 'IO::Handle::eof',
59 ferror => 'IO::Handle::error',
60 fflush => 'IO::Handle::flush',
61 fgetc => 'IO::Handle::getc',
62 fgetpos => 'IO::Seekable::getpos',
63 fgets => 'IO::Handle::gets',
64 fileno => 'IO::Handle::fileno',
65 fopen => 'IO::File::open',
72 fscanf => '<> and regular expressions',
73 fseek => 'IO::Seekable::seek',
74 fsetpos => 'IO::Seekable::setpos',
75 fsync => 'IO::Handle::sync',
76 ftell => 'IO::Seekable::tell',
79 ldiv => '/, % and int',
92 rand => \'non-portable, use Perl\'s rand instead',
94 scanf => '<> and regular expressions',
95 setbuf => 'IO::Handle::setbuf',
97 setvbuf => 'IO::Handle::setvbuf',
99 sigsetjmp => 'eval {}',
100 srand => \'not supplied, refer to Perl\'s srand documentation',
101 sscanf => 'regular expressions',
106 strcspn => 'regular expressions',
112 strrchr => 'rindex()',
115 tmpfile => 'IO::File::new_tmpfile',
116 ungetc => 'IO::Handle::ungetc',
122 eval "sub $_;" for keys %replacement;
125 no warnings 'uninitialized';
127 my ($func) = ($AUTOLOAD =~ /.*::(.*)/);
129 if (exists $replacement{$func}) {
130 my $how = $replacement{$func};
131 croak "Unimplemented: POSIX::$func() is C-specific, stopped"
133 croak "Unimplemented: POSIX::$func() is $$how" if ref $how;
134 croak "Use method $how() instead" if $how =~ /::/;
135 croak "Unimplemented: POSIX::$func() is C-specific, use $how instead";
138 if ($func =~ /^_?[a-z]/) {
139 $AutoLoader::AUTOLOAD = $AUTOLOAD;
140 goto &AutoLoader::AUTOLOAD
146 package POSIX::SigAction;
148 use AutoLoader 'AUTOLOAD';
150 package POSIX::SigRt;
152 use AutoLoader 'AUTOLOAD';
156 our @ISA = qw(Tie::StdHash);
158 our ($_SIGRTMIN, $_SIGRTMAX, $_sigrtn);
160 our $SIGACTION_FLAGS = 0;
162 tie %POSIX::SIGRT, 'POSIX::SigRt';
173 croak "Usage: POSIX::$mess";
177 usage "assert(expr)" if @_ != 1;
179 croak "Assertion failed";
184 usage "tolower(string)" if @_ != 1;
189 usage "toupper(string)" if @_ != 1;
194 usage "closedir(dirhandle)" if @_ != 1;
195 CORE::closedir($_[0]);
199 usage "opendir(directory)" if @_ != 1;
201 CORE::opendir($dirhandle, $_[0])
207 usage "readdir(dirhandle)" if @_ != 1;
208 CORE::readdir($_[0]);
212 usage "rewinddir(dirhandle)" if @_ != 1;
213 CORE::rewinddir($_[0]);
217 usage "errno()" if @_ != 0;
222 usage "creat(filename, mode)" if @_ != 2;
223 &open($_[0], &O_WRONLY | &O_CREAT | &O_TRUNC, $_[1]);
227 usage "fcntl(filehandle, cmd, arg)" if @_ != 3;
228 CORE::fcntl($_[0], $_[1], $_[2]);
232 usage "getgrgid(gid)" if @_ != 1;
233 CORE::getgrgid($_[0]);
237 usage "getgrnam(name)" if @_ != 1;
238 CORE::getgrnam($_[0]);
242 usage "atan2(x, y)" if @_ != 2;
243 CORE::atan2($_[0], $_[1]);
247 usage "cos(x)" if @_ != 1;
252 usage "exp(x)" if @_ != 1;
257 usage "fabs(x)" if @_ != 1;
262 usage "log(x)" if @_ != 1;
267 usage "pow(x, exponent)" if @_ != 2;
272 usage "sin(x)" if @_ != 1;
277 usage "sqrt(x)" if @_ != 1;
282 usage "getpwnam(name)" if @_ != 1;
283 CORE::getpwnam($_[0]);
287 usage "getpwuid(uid)" if @_ != 1;
288 CORE::getpwuid($_[0]);
292 usage "kill(pid, sig)" if @_ != 2;
293 CORE::kill $_[1], $_[0];
297 usage "raise(sig)" if @_ != 1;
298 CORE::kill $_[0], $$; # Is this good enough?
302 usage "getc(handle)" if @_ != 1;
307 usage "getchar()" if @_ != 0;
312 usage "gets()" if @_ != 0;
317 print STDERR "@_: " if @_;
318 print STDERR $!,"\n";
322 usage "printf(pattern, args...)" if @_ < 1;
323 CORE::printf STDOUT @_;
327 usage "remove(filename)" if @_ != 1;
328 (-d $_[0]) ? CORE::rmdir($_[0]) : CORE::unlink($_[0]);
332 usage "rename(oldfilename, newfilename)" if @_ != 2;
333 CORE::rename($_[0], $_[1]);
337 usage "rewind(filehandle)" if @_ != 1;
338 CORE::seek($_[0],0,0);
342 usage "sprintf(pattern, args...)" if @_ == 0;
343 CORE::sprintf(shift,@_);
347 usage "abs(x)" if @_ != 1;
352 usage "exit(status)" if @_ != 1;
357 usage "getenv(name)" if @_ != 1;
362 usage "system(command)" if @_ != 1;
367 usage "strerror(errno)" if @_ != 1;
373 usage "strstr(big, little)" if @_ != 2;
374 CORE::index($_[0], $_[1]);
378 usage "chmod(mode, filename)" if @_ != 2;
379 CORE::chmod($_[0], $_[1]);
383 usage "fstat(fd)" if @_ != 1;
385 CORE::open(TMP, "<&$_[0]"); # Gross.
386 my @l = CORE::stat(TMP);
392 usage "mkdir(directoryname, mode)" if @_ != 2;
393 CORE::mkdir($_[0], $_[1]);
397 usage "stat(filename)" if @_ != 1;
402 usage "umask(mask)" if @_ != 1;
407 usage "wait()" if @_ != 0;
412 usage "waitpid(pid, options)" if @_ != 2;
413 CORE::waitpid($_[0], $_[1]);
417 usage "gmtime(time)" if @_ != 1;
422 usage "localtime(time)" if @_ != 1;
423 CORE::localtime($_[0]);
427 usage "time()" if @_ != 0;
432 usage "alarm(seconds)" if @_ != 1;
437 usage "chdir(directory)" if @_ != 1;
442 usage "chown(uid, gid, filename)" if @_ != 3;
443 CORE::chown($_[0], $_[1], $_[2]);
447 usage "fork()" if @_ != 0;
452 usage "getegid()" if @_ != 0;
457 usage "geteuid()" if @_ != 0;
462 usage "getgid()" if @_ != 0;
467 usage "getgroups()" if @_ != 0;
469 grep(!$seen{$_}++, split(' ', $) ));
473 usage "getlogin()" if @_ != 0;
478 usage "getpgrp()" if @_ != 0;
483 usage "getpid()" if @_ != 0;
488 usage "getppid()" if @_ != 0;
493 usage "getuid()" if @_ != 0;
498 usage "isatty(filehandle)" if @_ != 1;
503 usage "link(oldfilename, newfilename)" if @_ != 2;
504 CORE::link($_[0], $_[1]);
508 usage "rmdir(directoryname)" if @_ != 1;
513 usage "sleep(seconds)" if @_ != 1;
514 $_[0] - CORE::sleep($_[0]);
518 usage "unlink(filename)" if @_ != 1;
523 usage "utime(filename, atime, mtime)" if @_ != 3;
524 CORE::utime($_[1], $_[2], $_[0]);
530 assert_h => [qw(assert NDEBUG)],
532 ctype_h => [qw(isalnum isalpha iscntrl isdigit isgraph islower
533 isprint ispunct isspace isupper isxdigit tolower toupper)],
537 errno_h => [qw(E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EAFNOSUPPORT
538 EAGAIN EALREADY EBADF EBUSY ECHILD ECONNABORTED
539 ECONNREFUSED ECONNRESET EDEADLK EDESTADDRREQ EDOM EDQUOT
540 EEXIST EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EINPROGRESS
541 EINTR EINVAL EIO EISCONN EISDIR ELOOP EMFILE EMLINK
542 EMSGSIZE ENAMETOOLONG ENETDOWN ENETRESET ENETUNREACH
543 ENFILE ENOBUFS ENODEV ENOENT ENOEXEC ENOLCK ENOMEM
544 ENOPROTOOPT ENOSPC ENOSYS ENOTBLK ENOTCONN ENOTDIR
545 ENOTEMPTY ENOTSOCK ENOTTY ENXIO EOPNOTSUPP EPERM
546 EPFNOSUPPORT EPIPE EPROCLIM EPROTONOSUPPORT EPROTOTYPE
547 ERANGE EREMOTE ERESTART EROFS ESHUTDOWN ESOCKTNOSUPPORT
548 ESPIPE ESRCH ESTALE ETIMEDOUT ETOOMANYREFS ETXTBSY
549 EUSERS EWOULDBLOCK EXDEV errno)],
551 fcntl_h => [qw(FD_CLOEXEC F_DUPFD F_GETFD F_GETFL F_GETLK F_RDLCK
552 F_SETFD F_SETFL F_SETLK F_SETLKW F_UNLCK F_WRLCK
553 O_ACCMODE O_APPEND O_CREAT O_EXCL O_NOCTTY O_NONBLOCK
554 O_RDONLY O_RDWR O_TRUNC O_WRONLY
556 SEEK_CUR SEEK_END SEEK_SET
557 S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
558 S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISREG S_ISUID
559 S_IWGRP S_IWOTH S_IWUSR)],
561 float_h => [qw(DBL_DIG DBL_EPSILON DBL_MANT_DIG
562 DBL_MAX DBL_MAX_10_EXP DBL_MAX_EXP
563 DBL_MIN DBL_MIN_10_EXP DBL_MIN_EXP
564 FLT_DIG FLT_EPSILON FLT_MANT_DIG
565 FLT_MAX FLT_MAX_10_EXP FLT_MAX_EXP
566 FLT_MIN FLT_MIN_10_EXP FLT_MIN_EXP
568 LDBL_DIG LDBL_EPSILON LDBL_MANT_DIG
569 LDBL_MAX LDBL_MAX_10_EXP LDBL_MAX_EXP
570 LDBL_MIN LDBL_MIN_10_EXP LDBL_MIN_EXP)],
574 limits_h => [qw( ARG_MAX CHAR_BIT CHAR_MAX CHAR_MIN CHILD_MAX
575 INT_MAX INT_MIN LINK_MAX LONG_MAX LONG_MIN MAX_CANON
576 MAX_INPUT MB_LEN_MAX NAME_MAX NGROUPS_MAX OPEN_MAX
577 PATH_MAX PIPE_BUF SCHAR_MAX SCHAR_MIN SHRT_MAX SHRT_MIN
578 SSIZE_MAX STREAM_MAX TZNAME_MAX UCHAR_MAX UINT_MAX
579 ULONG_MAX USHRT_MAX _POSIX_ARG_MAX _POSIX_CHILD_MAX
580 _POSIX_LINK_MAX _POSIX_MAX_CANON _POSIX_MAX_INPUT
581 _POSIX_NAME_MAX _POSIX_NGROUPS_MAX _POSIX_OPEN_MAX
582 _POSIX_PATH_MAX _POSIX_PIPE_BUF _POSIX_SSIZE_MAX
583 _POSIX_STREAM_MAX _POSIX_TZNAME_MAX)],
585 locale_h => [qw(LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES
586 LC_MONETARY LC_NUMERIC LC_TIME NULL
587 localeconv setlocale)],
589 math_h => [qw(HUGE_VAL acos asin atan ceil cosh fabs floor fmod
590 frexp ldexp log10 modf pow sinh tan tanh)],
594 setjmp_h => [qw(longjmp setjmp siglongjmp sigsetjmp)],
596 signal_h => [qw(SA_NOCLDSTOP SA_NOCLDWAIT SA_NODEFER SA_ONSTACK
597 SA_RESETHAND SA_RESTART SA_SIGINFO SIGABRT SIGALRM
598 SIGCHLD SIGCONT SIGFPE SIGHUP SIGILL SIGINT SIGKILL
599 SIGPIPE %SIGRT SIGRTMIN SIGRTMAX SIGQUIT SIGSEGV SIGSTOP
600 SIGTERM SIGTSTP SIGTTIN SIGTTOU SIGUSR1 SIGUSR2 SIGBUS
601 SIGPOLL SIGPROF SIGSYS SIGTRAP SIGURG SIGVTALRM SIGXCPU SIGXFSZ
602 SIG_BLOCK SIG_DFL SIG_ERR SIG_IGN SIG_SETMASK SIG_UNBLOCK
603 raise sigaction signal sigpending sigprocmask sigsuspend)],
607 stddef_h => [qw(NULL offsetof)],
609 stdio_h => [qw(BUFSIZ EOF FILENAME_MAX L_ctermid L_cuserid
610 L_tmpname NULL SEEK_CUR SEEK_END SEEK_SET
611 STREAM_MAX TMP_MAX stderr stdin stdout
612 clearerr fclose fdopen feof ferror fflush fgetc fgetpos
613 fgets fopen fprintf fputc fputs fread freopen
614 fscanf fseek fsetpos ftell fwrite getchar gets
615 perror putc putchar puts remove rewind
616 scanf setbuf setvbuf sscanf tmpfile tmpnam
617 ungetc vfprintf vprintf vsprintf)],
619 stdlib_h => [qw(EXIT_FAILURE EXIT_SUCCESS MB_CUR_MAX NULL RAND_MAX
620 abort atexit atof atoi atol bsearch calloc div
621 free getenv labs ldiv malloc mblen mbstowcs mbtowc
622 qsort realloc strtod strtol strtoul wcstombs wctomb)],
624 string_h => [qw(NULL memchr memcmp memcpy memmove memset strcat
625 strchr strcmp strcoll strcpy strcspn strerror strlen
626 strncat strncmp strncpy strpbrk strrchr strspn strstr
629 sys_stat_h => [qw(S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU
630 S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISGID S_ISREG
631 S_ISUID S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR
638 sys_utsname_h => [qw(uname)],
640 sys_wait_h => [qw(WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED
641 WNOHANG WSTOPSIG WTERMSIG WUNTRACED)],
643 termios_h => [qw( B0 B110 B1200 B134 B150 B1800 B19200 B200 B2400
644 B300 B38400 B4800 B50 B600 B75 B9600 BRKINT CLOCAL
645 CREAD CS5 CS6 CS7 CS8 CSIZE CSTOPB ECHO ECHOE ECHOK
646 ECHONL HUPCL ICANON ICRNL IEXTEN IGNBRK IGNCR IGNPAR
647 INLCR INPCK ISIG ISTRIP IXOFF IXON NCCS NOFLSH OPOST
648 PARENB PARMRK PARODD TCIFLUSH TCIOFF TCIOFLUSH TCION
649 TCOFLUSH TCOOFF TCOON TCSADRAIN TCSAFLUSH TCSANOW
650 TOSTOP VEOF VEOL VERASE VINTR VKILL VMIN VQUIT VSTART
652 cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain
653 tcflow tcflush tcgetattr tcsendbreak tcsetattr )],
655 time_h => [qw(CLK_TCK CLOCKS_PER_SEC NULL asctime clock ctime
656 difftime mktime strftime tzset tzname)],
658 unistd_h => [qw(F_OK NULL R_OK SEEK_CUR SEEK_END SEEK_SET
659 STDERR_FILENO STDIN_FILENO STDOUT_FILENO W_OK X_OK
660 _PC_CHOWN_RESTRICTED _PC_LINK_MAX _PC_MAX_CANON
661 _PC_MAX_INPUT _PC_NAME_MAX _PC_NO_TRUNC _PC_PATH_MAX
662 _PC_PIPE_BUF _PC_VDISABLE _POSIX_CHOWN_RESTRICTED
663 _POSIX_JOB_CONTROL _POSIX_NO_TRUNC _POSIX_SAVED_IDS
664 _POSIX_VDISABLE _POSIX_VERSION _SC_ARG_MAX
665 _SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL
666 _SC_NGROUPS_MAX _SC_OPEN_MAX _SC_PAGESIZE _SC_SAVED_IDS
667 _SC_STREAM_MAX _SC_TZNAME_MAX _SC_VERSION
668 _exit access ctermid cuserid
669 dup2 dup execl execle execlp execv execve execvp
670 fpathconf fsync getcwd getegid geteuid getgid getgroups
671 getpid getuid isatty lseek pathconf pause setgid setpgid
672 setsid setuid sysconf tcgetpgrp tcsetpgrp ttyname)],
677 # Exporter::export_tags();
679 # De-duplicate the export list:
681 @export{map {@$_} values %EXPORT_TAGS} = ();
682 # Doing the de-dup with a temporary hash has the advantage that the SVs in
683 # @EXPORT are actually shared hash key scalars, which will save some memory.
684 our @EXPORT = keys %export;
749 package POSIX::SigAction;
751 sub new { bless {HANDLER => $_[1], MASK => $_[2], FLAGS => $_[3] || 0, SAFE => 0}, $_[0] }
752 sub handler { $_[0]->{HANDLER} = $_[1] if @_ > 1; $_[0]->{HANDLER} };
753 sub mask { $_[0]->{MASK} = $_[1] if @_ > 1; $_[0]->{MASK} };
754 sub flags { $_[0]->{FLAGS} = $_[1] if @_ > 1; $_[0]->{FLAGS} };
755 sub safe { $_[0]->{SAFE} = $_[1] if @_ > 1; $_[0]->{SAFE} };
757 package POSIX::SigRt;
760 $_SIGRTMIN = &POSIX::SIGRTMIN;
761 $_SIGRTMAX = &POSIX::SIGRTMAX;
762 $_sigrtn = $_SIGRTMAX - $_SIGRTMIN;
766 &_init unless defined $_sigrtn;
767 die "POSIX::SigRt not available" unless defined $_sigrtn && $_sigrtn > 0;
773 # Allow (SIGRT)?MIN( + n)?, a common idiom when doing these things in C.
774 $rtsig = $_SIGRTMIN + ($1 || 0)
775 if $rtsig =~ /^(?:(?:SIG)?RT)?MIN(\s*\+\s*(\d+))?$/;
780 my $rtsig = _getsig($_[1]);
781 my $ok = $rtsig >= $_SIGRTMIN && $rtsig <= $_SIGRTMAX;
786 my ($rtsig, $ok) = &_exist;
787 die "No POSIX::SigRt signal $_[1] (valid range SIGRTMIN..SIGRTMAX, or $_SIGRTMIN..$_SIGRTMAX)"
793 my ($rtsig, $handler, $flags) = @_;
794 my $sigset = POSIX::SigSet->new($rtsig);
795 my $sigact = POSIX::SigAction->new($handler, $sigset, $flags);
796 POSIX::sigaction($rtsig, $sigact);
799 sub EXISTS { &_exist }
800 sub FETCH { my $rtsig = &_check;
801 my $oa = POSIX::SigAction->new();
802 POSIX::sigaction($rtsig, undef, $oa);
803 return $oa->{HANDLER} }
804 sub STORE { my $rtsig = &_check; new($rtsig, $_[2], $SIGACTION_FLAGS) }
805 sub DELETE { delete $SIG{ &_check } }
806 sub CLEAR { &_exist; delete @SIG{ &POSIX::SIGRTMIN .. &POSIX::SIGRTMAX } }
807 sub SCALAR { &_croak; $_sigrtn + 1 }