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