fix File::Spec->abs2rel() to return absolute $path more often for VMS
[p5sagit/p5-mst-13.2.git] / ext / POSIX / POSIX.xs
1 #define PERL_EXT_POSIX
2
3 #ifdef NETWARE
4         #define _POSIX_
5         /*
6          * Ideally this should be somewhere down in the includes
7          * but putting it in other places is giving compiler errors.
8          * Also here I am unable to check for HAS_UNAME since it wouldn't have
9          * yet come into the file at this stage - sgp 18th Oct 2000
10          */
11         #include <sys/utsname.h>
12 #endif  /* NETWARE */
13
14 #define PERL_NO_GET_CONTEXT
15
16 #include "EXTERN.h"
17 #define PERLIO_NOT_STDIO 1
18 #include "perl.h"
19 #include "XSUB.h"
20 #if defined(PERL_IMPLICIT_SYS)
21 #  undef signal
22 #  undef open
23 #  undef setmode
24 #  define open PerlLIO_open3
25 #endif
26 #include <ctype.h>
27 #ifdef I_DIRENT    /* XXX maybe better to just rely on perl.h? */
28 #include <dirent.h>
29 #endif
30 #include <errno.h>
31 #ifdef I_FLOAT
32 #include <float.h>
33 #endif
34 #ifdef I_LIMITS
35 #include <limits.h>
36 #endif
37 #include <locale.h>
38 #include <math.h>
39 #ifdef I_PWD
40 #include <pwd.h>
41 #endif
42 #include <setjmp.h>
43 #include <signal.h>
44 #include <stdarg.h>
45
46 #ifdef I_STDDEF
47 #include <stddef.h>
48 #endif
49
50 #ifdef I_UNISTD
51 #include <unistd.h>
52 #endif
53
54 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to 
55    metaconfig for future extension writers.  We don't use them in POSIX.
56    (This is really sneaky :-)  --AD
57 */
58 #if defined(I_TERMIOS)
59 #include <termios.h>
60 #endif
61 #ifdef I_STDLIB
62 #include <stdlib.h>
63 #endif
64 #ifndef __ultrix__
65 #include <string.h>
66 #endif
67 #include <sys/stat.h>
68 #include <sys/types.h>
69 #include <time.h>
70 #ifdef I_UNISTD
71 #include <unistd.h>
72 #endif
73 #ifdef MACOS_TRADITIONAL
74 #undef fdopen
75 #endif
76 #include <fcntl.h>
77
78 #ifdef HAS_TZNAME
79 #  if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
80 extern char *tzname[];
81 #  endif
82 #else
83 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
84 char *tzname[] = { "" , "" };
85 #endif
86 #endif
87
88 #if defined(__VMS) && !defined(__POSIX_SOURCE)
89 #  include <libdef.h>       /* LIB$_INVARG constant */
90 #  include <lib$routines.h> /* prototype for lib$ediv() */
91 #  include <starlet.h>      /* prototype for sys$gettim() */
92 #  if DECC_VERSION < 50000000
93 #    define pid_t int       /* old versions of DECC miss this in types.h */
94 #  endif
95
96 #  undef mkfifo
97 #  define mkfifo(a,b) (not_here("mkfifo"),-1)
98 #  define tzset() not_here("tzset")
99
100 #if ((__VMS_VER >= 70000000) && (__DECC_VER >= 50200000)) || (__CRTL_VER >= 70000000)
101 #    define HAS_TZNAME  /* shows up in VMS 7.0 or Dec C 5.6 */
102 #    include <utsname.h>
103 #  endif /* __VMS_VER >= 70000000 or Dec C 5.6 */
104
105    /* The POSIX notion of ttyname() is better served by getname() under VMS */
106    static char ttnambuf[64];
107 #  define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
108
109    /* The non-POSIX CRTL times() has void return type, so we just get the
110       current time directly */
111    clock_t vms_times(struct tms *bufptr) {
112         dTHX;
113         clock_t retval;
114         /* Get wall time and convert to 10 ms intervals to
115          * produce the return value that the POSIX standard expects */
116 #  if defined(__DECC) && defined (__ALPHA)
117 #    include <ints.h>
118         uint64 vmstime;
119         _ckvmssts(sys$gettim(&vmstime));
120         vmstime /= 100000;
121         retval = vmstime & 0x7fffffff;
122 #  else
123         /* (Older hw or ccs don't have an atomic 64-bit type, so we
124          * juggle 32-bit ints (and a float) to produce a time_t result
125          * with minimal loss of information.) */
126         long int vmstime[2],remainder,divisor = 100000;
127         _ckvmssts(sys$gettim((unsigned long int *)vmstime));
128         vmstime[1] &= 0x7fff;  /* prevent overflow in EDIV */
129         _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));
130 #  endif
131         /* Fill in the struct tms using the CRTL routine . . .*/
132         times((tbuffer_t *)bufptr);
133         return (clock_t) retval;
134    }
135 #  define times(t) vms_times(t)
136 #else
137 #if defined (__CYGWIN__)
138 #    define tzname _tzname
139 #endif
140 #if defined (WIN32) || defined (NETWARE)
141 #  undef mkfifo
142 #  define mkfifo(a,b) not_here("mkfifo")
143 #  define ttyname(a) (char*)not_here("ttyname")
144 #  define sigset_t long
145 #  define pid_t long
146 #  ifdef __BORLANDC__
147 #    define tzname _tzname
148 #  endif
149 #  ifdef _MSC_VER
150 #    define mode_t short
151 #  endif
152 #  ifdef __MINGW32__
153 #    define mode_t short
154 #    ifndef tzset
155 #      define tzset()           not_here("tzset")
156 #    endif
157 #    ifndef _POSIX_OPEN_MAX
158 #      define _POSIX_OPEN_MAX   FOPEN_MAX       /* XXX bogus ? */
159 #    endif
160 #  endif
161 #  define sigaction(a,b,c)      not_here("sigaction")
162 #  define sigpending(a)         not_here("sigpending")
163 #  define sigprocmask(a,b,c)    not_here("sigprocmask")
164 #  define sigsuspend(a)         not_here("sigsuspend")
165 #  define sigemptyset(a)        not_here("sigemptyset")
166 #  define sigaddset(a,b)        not_here("sigaddset")
167 #  define sigdelset(a,b)        not_here("sigdelset")
168 #  define sigfillset(a)         not_here("sigfillset")
169 #  define sigismember(a,b)      not_here("sigismember")
170 #ifndef NETWARE
171 #  undef setuid
172 #  undef setgid
173 #  define setuid(a)             not_here("setuid")
174 #  define setgid(a)             not_here("setgid")
175 #endif  /* NETWARE */
176 #else
177
178 #  ifndef HAS_MKFIFO
179 #    if defined(OS2) || defined(MACOS_TRADITIONAL)
180 #      define mkfifo(a,b) not_here("mkfifo")
181 #    else       /* !( defined OS2 ) */ 
182 #      ifndef mkfifo
183 #        define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
184 #      endif
185 #    endif
186 #  endif /* !HAS_MKFIFO */
187
188 #  ifdef MACOS_TRADITIONAL
189 #    define ttyname(a) (char*)not_here("ttyname")
190 #    define tzset() not_here("tzset")
191 #  else
192 #    include <grp.h>
193 #    include <sys/times.h>
194 #    ifdef HAS_UNAME
195 #      include <sys/utsname.h>
196 #    endif
197 #    include <sys/wait.h>
198 #  endif
199 #  ifdef I_UTIME
200 #    include <utime.h>
201 #  endif
202 #endif /* WIN32 || NETWARE */
203 #endif /* __VMS */
204
205 typedef int SysRet;
206 typedef long SysRetLong;
207 typedef sigset_t* POSIX__SigSet;
208 typedef HV* POSIX__SigAction;
209 #ifdef I_TERMIOS
210 typedef struct termios* POSIX__Termios;
211 #else /* Define termios types to int, and call not_here for the functions.*/
212 #define POSIX__Termios int
213 #define speed_t int
214 #define tcflag_t int
215 #define cc_t int
216 #define cfgetispeed(x) not_here("cfgetispeed")
217 #define cfgetospeed(x) not_here("cfgetospeed")
218 #define tcdrain(x) not_here("tcdrain")
219 #define tcflush(x,y) not_here("tcflush")
220 #define tcsendbreak(x,y) not_here("tcsendbreak")
221 #define cfsetispeed(x,y) not_here("cfsetispeed")
222 #define cfsetospeed(x,y) not_here("cfsetospeed")
223 #define ctermid(x) (char *) not_here("ctermid")
224 #define tcflow(x,y) not_here("tcflow")
225 #define tcgetattr(x,y) not_here("tcgetattr")
226 #define tcsetattr(x,y,z) not_here("tcsetattr")
227 #endif
228
229 /* Possibly needed prototypes */
230 char *cuserid (char *);
231 #ifndef WIN32
232 double strtod (const char *, char **);
233 long strtol (const char *, char **, int);
234 unsigned long strtoul (const char *, char **, int);
235 #endif
236
237 #ifndef HAS_CUSERID
238 #define cuserid(a) (char *) not_here("cuserid")
239 #endif
240 #ifndef HAS_DIFFTIME
241 #ifndef difftime
242 #define difftime(a,b) not_here("difftime")
243 #endif
244 #endif
245 #ifndef HAS_FPATHCONF
246 #define fpathconf(f,n)  (SysRetLong) not_here("fpathconf")
247 #endif
248 #ifndef HAS_MKTIME
249 #define mktime(a) not_here("mktime")
250 #endif
251 #ifndef HAS_NICE
252 #define nice(a) not_here("nice")
253 #endif
254 #ifndef HAS_PATHCONF
255 #define pathconf(f,n)   (SysRetLong) not_here("pathconf")
256 #endif
257 #ifndef HAS_SYSCONF
258 #define sysconf(n)      (SysRetLong) not_here("sysconf")
259 #endif
260 #ifndef HAS_READLINK
261 #define readlink(a,b,c) not_here("readlink")
262 #endif
263 #ifndef HAS_SETPGID
264 #define setpgid(a,b) not_here("setpgid")
265 #endif
266 #ifndef HAS_SETSID
267 #define setsid() not_here("setsid")
268 #endif
269 #ifndef HAS_STRCOLL
270 #define strcoll(s1,s2) not_here("strcoll")
271 #endif
272 #ifndef HAS_STRTOD
273 #define strtod(s1,s2) not_here("strtod")
274 #endif
275 #ifndef HAS_STRTOL
276 #define strtol(s1,s2,b) not_here("strtol")
277 #endif
278 #ifndef HAS_STRTOUL
279 #define strtoul(s1,s2,b) not_here("strtoul")
280 #endif
281 #ifndef HAS_STRXFRM
282 #define strxfrm(s1,s2,n) not_here("strxfrm")
283 #endif
284 #ifndef HAS_TCGETPGRP
285 #define tcgetpgrp(a) not_here("tcgetpgrp")
286 #endif
287 #ifndef HAS_TCSETPGRP
288 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
289 #endif
290 #ifndef HAS_TIMES
291 #ifndef NETWARE
292 #define times(a) not_here("times")
293 #endif  /* NETWARE */
294 #endif
295 #ifndef HAS_UNAME
296 #define uname(a) not_here("uname")
297 #endif
298 #ifndef HAS_WAITPID
299 #define waitpid(a,b,c) not_here("waitpid")
300 #endif
301
302 #ifndef HAS_MBLEN
303 #ifndef mblen
304 #define mblen(a,b) not_here("mblen")
305 #endif
306 #endif
307 #ifndef HAS_MBSTOWCS
308 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
309 #endif
310 #ifndef HAS_MBTOWC
311 #define mbtowc(pwc, s, n) not_here("mbtowc")
312 #endif
313 #ifndef HAS_WCSTOMBS
314 #define wcstombs(s, pwcs, n) not_here("wcstombs")
315 #endif
316 #ifndef HAS_WCTOMB
317 #define wctomb(s, wchar) not_here("wcstombs")
318 #endif
319 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
320 /* If we don't have these functions, then we wouldn't have gotten a typedef
321    for wchar_t, the wide character type.  Defining wchar_t allows the
322    functions referencing it to compile.  Its actual type is then meaningless,
323    since without the above functions, all sections using it end up calling
324    not_here() and croak.  --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
325 #ifndef wchar_t
326 #define wchar_t char
327 #endif
328 #endif
329
330 #ifndef HAS_LOCALECONV
331 #define localeconv() not_here("localeconv")
332 #endif
333
334 #ifdef HAS_LONG_DOUBLE
335 #  if LONG_DOUBLESIZE > NVSIZE
336 #    undef HAS_LONG_DOUBLE  /* XXX until we figure out how to use them */
337 #  endif
338 #endif
339
340 #ifndef HAS_LONG_DOUBLE
341 #ifdef LDBL_MAX
342 #undef LDBL_MAX
343 #endif
344 #ifdef LDBL_MIN
345 #undef LDBL_MIN
346 #endif
347 #ifdef LDBL_EPSILON
348 #undef LDBL_EPSILON
349 #endif
350 #endif
351
352 /* Background: in most systems the low byte of the wait status
353  * is the signal (the lowest 7 bits) and the coredump flag is
354  * the eight bit, and the second lowest byte is the exit status.
355  * BeOS bucks the trend and has the bytes in different order.
356  * See beos/beos.c for how the reality is bent even in BeOS
357  * to follow the traditional.  However, to make the POSIX
358  * wait W*() macros to work in BeOS, we need to unbend the
359  * reality back in place. --jhi */
360 #ifdef __BEOS__
361 #    define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
362 #else
363 #    define WMUNGE(x) (x)
364 #endif
365
366 static int
367 not_here(char *s)
368 {
369     croak("POSIX::%s not implemented on this architecture", s);
370     return -1;
371 }
372
373 #include "const-c.inc"
374
375 /* These were implemented in the old "constant" subroutine. They are actually
376    macros that take an integer argument and return an integer result.  */
377 static int
378 int_macro_int (const char *name, STRLEN len, IV *arg_result) {
379   /* Initially switch on the length of the name.  */
380   /* This code has been edited from a "constant" function generated by:
381
382 use ExtUtils::Constant qw (constant_types C_constant XS_constant);
383
384 my $types = {map {($_, 1)} qw(IV)};
385 my @names = (qw(S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG WEXITSTATUS WIFEXITED
386                WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG));
387
388 print constant_types(); # macro defs
389 foreach (C_constant ("POSIX", 'int_macro_int', 'IV', $types, undef, 5, @names) ) {
390     print $_, "\n"; # C constant subs
391 }
392 print "#### XS Section:\n";
393 print XS_constant ("POSIX", $types);
394 __END__
395    */
396
397   switch (len) {
398   case 7:
399     /* Names all of length 7.  */
400     /* S_ISBLK S_ISCHR S_ISDIR S_ISREG */
401     /* Offset 5 gives the best switch position.  */
402     switch (name[5]) {
403     case 'E':
404       if (memEQ(name, "S_ISREG", 7)) {
405       /*                    ^       */
406 #ifdef S_ISREG
407         *arg_result = S_ISREG(*arg_result);
408         return PERL_constant_ISIV;
409 #else
410         return PERL_constant_NOTDEF;
411 #endif
412       }
413       break;
414     case 'H':
415       if (memEQ(name, "S_ISCHR", 7)) {
416       /*                    ^       */
417 #ifdef S_ISCHR
418         *arg_result = S_ISCHR(*arg_result);
419         return PERL_constant_ISIV;
420 #else
421         return PERL_constant_NOTDEF;
422 #endif
423       }
424       break;
425     case 'I':
426       if (memEQ(name, "S_ISDIR", 7)) {
427       /*                    ^       */
428 #ifdef S_ISDIR
429         *arg_result = S_ISDIR(*arg_result);
430         return PERL_constant_ISIV;
431 #else
432         return PERL_constant_NOTDEF;
433 #endif
434       }
435       break;
436     case 'L':
437       if (memEQ(name, "S_ISBLK", 7)) {
438       /*                    ^       */
439 #ifdef S_ISBLK
440         *arg_result = S_ISBLK(*arg_result);
441         return PERL_constant_ISIV;
442 #else
443         return PERL_constant_NOTDEF;
444 #endif
445       }
446       break;
447     }
448     break;
449   case 8:
450     /* Names all of length 8.  */
451     /* S_ISFIFO WSTOPSIG WTERMSIG */
452     /* Offset 3 gives the best switch position.  */
453     switch (name[3]) {
454     case 'O':
455       if (memEQ(name, "WSTOPSIG", 8)) {
456       /*                  ^          */
457 #ifdef WSTOPSIG
458         int i = *arg_result;
459         *arg_result = WSTOPSIG(WMUNGE(i));
460         return PERL_constant_ISIV;
461 #else
462         return PERL_constant_NOTDEF;
463 #endif
464       }
465       break;
466     case 'R':
467       if (memEQ(name, "WTERMSIG", 8)) {
468       /*                  ^          */
469 #ifdef WTERMSIG
470         int i = *arg_result;
471         *arg_result = WTERMSIG(WMUNGE(i));
472         return PERL_constant_ISIV;
473 #else
474         return PERL_constant_NOTDEF;
475 #endif
476       }
477       break;
478     case 'S':
479       if (memEQ(name, "S_ISFIFO", 8)) {
480       /*                  ^          */
481 #ifdef S_ISFIFO
482         *arg_result = S_ISFIFO(*arg_result);
483         return PERL_constant_ISIV;
484 #else
485         return PERL_constant_NOTDEF;
486 #endif
487       }
488       break;
489     }
490     break;
491   case 9:
492     if (memEQ(name, "WIFEXITED", 9)) {
493 #ifdef WIFEXITED
494       int i = *arg_result;
495       *arg_result = WIFEXITED(WMUNGE(i));
496       return PERL_constant_ISIV;
497 #else
498       return PERL_constant_NOTDEF;
499 #endif
500     }
501     break;
502   case 10:
503     if (memEQ(name, "WIFSTOPPED", 10)) {
504 #ifdef WIFSTOPPED
505       int i = *arg_result;
506       *arg_result = WIFSTOPPED(WMUNGE(i));
507       return PERL_constant_ISIV;
508 #else
509       return PERL_constant_NOTDEF;
510 #endif
511     }
512     break;
513   case 11:
514     /* Names all of length 11.  */
515     /* WEXITSTATUS WIFSIGNALED */
516     /* Offset 1 gives the best switch position.  */
517     switch (name[1]) {
518     case 'E':
519       if (memEQ(name, "WEXITSTATUS", 11)) {
520       /*                ^                */
521 #ifdef WEXITSTATUS
522         int i = *arg_result;
523         *arg_result = WEXITSTATUS(WMUNGE(i));
524         return PERL_constant_ISIV;
525 #else
526         return PERL_constant_NOTDEF;
527 #endif
528       }
529       break;
530     case 'I':
531       if (memEQ(name, "WIFSIGNALED", 11)) {
532       /*                ^                */
533 #ifdef WIFSIGNALED
534         int i = *arg_result;
535         *arg_result = WIFSIGNALED(WMUNGE(i));
536         return PERL_constant_ISIV;
537 #else
538         return PERL_constant_NOTDEF;
539 #endif
540       }
541       break;
542     }
543     break;
544   }
545   return PERL_constant_NOTFOUND;
546 }
547
548 static void
549 restore_sigmask(pTHX_ SV *osset_sv)
550 {
551      /* Fortunately, restoring the signal mask can't fail, because
552       * there's nothing we can do about it if it does -- we're not
553       * supposed to return -1 from sigaction unless the disposition
554       * was unaffected.
555       */
556      sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
557      (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
558 }
559
560 MODULE = SigSet         PACKAGE = POSIX::SigSet         PREFIX = sig
561
562 POSIX::SigSet
563 new(packname = "POSIX::SigSet", ...)
564     char *              packname
565     CODE:
566         {
567             int i;
568             New(0, RETVAL, 1, sigset_t);
569             sigemptyset(RETVAL);
570             for (i = 1; i < items; i++)
571                 sigaddset(RETVAL, SvIV(ST(i)));
572         }
573     OUTPUT:
574         RETVAL
575
576 void
577 DESTROY(sigset)
578         POSIX::SigSet   sigset
579     CODE:
580         Safefree(sigset);
581
582 SysRet
583 sigaddset(sigset, sig)
584         POSIX::SigSet   sigset
585         int             sig
586
587 SysRet
588 sigdelset(sigset, sig)
589         POSIX::SigSet   sigset
590         int             sig
591
592 SysRet
593 sigemptyset(sigset)
594         POSIX::SigSet   sigset
595
596 SysRet
597 sigfillset(sigset)
598         POSIX::SigSet   sigset
599
600 int
601 sigismember(sigset, sig)
602         POSIX::SigSet   sigset
603         int             sig
604
605
606 MODULE = Termios        PACKAGE = POSIX::Termios        PREFIX = cf
607
608 POSIX::Termios
609 new(packname = "POSIX::Termios", ...)
610     char *              packname
611     CODE:
612         {
613 #ifdef I_TERMIOS
614             New(0, RETVAL, 1, struct termios);
615 #else
616             not_here("termios");
617         RETVAL = 0;
618 #endif
619         }
620     OUTPUT:
621         RETVAL
622
623 void
624 DESTROY(termios_ref)
625         POSIX::Termios  termios_ref
626     CODE:
627 #ifdef I_TERMIOS
628         Safefree(termios_ref);
629 #else
630             not_here("termios");
631 #endif
632
633 SysRet
634 getattr(termios_ref, fd = 0)
635         POSIX::Termios  termios_ref
636         int             fd
637     CODE:
638         RETVAL = tcgetattr(fd, termios_ref);
639     OUTPUT:
640         RETVAL
641
642 SysRet
643 setattr(termios_ref, fd = 0, optional_actions = 0)
644         POSIX::Termios  termios_ref
645         int             fd
646         int             optional_actions
647     CODE:
648         RETVAL = tcsetattr(fd, optional_actions, termios_ref);
649     OUTPUT:
650         RETVAL
651
652 speed_t
653 cfgetispeed(termios_ref)
654         POSIX::Termios  termios_ref
655
656 speed_t
657 cfgetospeed(termios_ref)
658         POSIX::Termios  termios_ref
659
660 tcflag_t
661 getiflag(termios_ref)
662         POSIX::Termios  termios_ref
663     CODE:
664 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
665         RETVAL = termios_ref->c_iflag;
666 #else
667      not_here("getiflag");
668      RETVAL = 0;
669 #endif
670     OUTPUT:
671         RETVAL
672
673 tcflag_t
674 getoflag(termios_ref)
675         POSIX::Termios  termios_ref
676     CODE:
677 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
678         RETVAL = termios_ref->c_oflag;
679 #else
680      not_here("getoflag");
681      RETVAL = 0;
682 #endif
683     OUTPUT:
684         RETVAL
685
686 tcflag_t
687 getcflag(termios_ref)
688         POSIX::Termios  termios_ref
689     CODE:
690 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
691         RETVAL = termios_ref->c_cflag;
692 #else
693      not_here("getcflag");
694      RETVAL = 0;
695 #endif
696     OUTPUT:
697         RETVAL
698
699 tcflag_t
700 getlflag(termios_ref)
701         POSIX::Termios  termios_ref
702     CODE:
703 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
704         RETVAL = termios_ref->c_lflag;
705 #else
706      not_here("getlflag");
707      RETVAL = 0;
708 #endif
709     OUTPUT:
710         RETVAL
711
712 cc_t
713 getcc(termios_ref, ccix)
714         POSIX::Termios  termios_ref
715         int             ccix
716     CODE:
717 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
718         if (ccix >= NCCS)
719             croak("Bad getcc subscript");
720         RETVAL = termios_ref->c_cc[ccix];
721 #else
722      not_here("getcc");
723      RETVAL = 0;
724 #endif
725     OUTPUT:
726         RETVAL
727
728 SysRet
729 cfsetispeed(termios_ref, speed)
730         POSIX::Termios  termios_ref
731         speed_t         speed
732
733 SysRet
734 cfsetospeed(termios_ref, speed)
735         POSIX::Termios  termios_ref
736         speed_t         speed
737
738 void
739 setiflag(termios_ref, iflag)
740         POSIX::Termios  termios_ref
741         tcflag_t        iflag
742     CODE:
743 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
744         termios_ref->c_iflag = iflag;
745 #else
746             not_here("setiflag");
747 #endif
748
749 void
750 setoflag(termios_ref, oflag)
751         POSIX::Termios  termios_ref
752         tcflag_t        oflag
753     CODE:
754 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
755         termios_ref->c_oflag = oflag;
756 #else
757             not_here("setoflag");
758 #endif
759
760 void
761 setcflag(termios_ref, cflag)
762         POSIX::Termios  termios_ref
763         tcflag_t        cflag
764     CODE:
765 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
766         termios_ref->c_cflag = cflag;
767 #else
768             not_here("setcflag");
769 #endif
770
771 void
772 setlflag(termios_ref, lflag)
773         POSIX::Termios  termios_ref
774         tcflag_t        lflag
775     CODE:
776 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
777         termios_ref->c_lflag = lflag;
778 #else
779             not_here("setlflag");
780 #endif
781
782 void
783 setcc(termios_ref, ccix, cc)
784         POSIX::Termios  termios_ref
785         int             ccix
786         cc_t            cc
787     CODE:
788 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
789         if (ccix >= NCCS)
790             croak("Bad setcc subscript");
791         termios_ref->c_cc[ccix] = cc;
792 #else
793             not_here("setcc");
794 #endif
795
796
797 MODULE = POSIX          PACKAGE = POSIX
798
799 INCLUDE: const-xs.inc
800
801 void
802 int_macro_int(sv, iv)
803     PREINIT:
804         dXSTARG;
805         STRLEN          len;
806         int             type;
807     INPUT:
808         SV *            sv;
809         const char *    s = SvPV(sv, len);
810         IV              iv;
811     PPCODE:
812         /* Change this to int_macro_int(s, len, &iv, &nv);
813            if you need to return both NVs and IVs */
814         type = int_macro_int(s, len, &iv);
815       /* Return 1 or 2 items. First is error message, or undef if no error.
816            Second, if present, is found value */
817         switch (type) {
818         case PERL_constant_NOTFOUND:
819           sv = sv_2mortal(newSVpvf("%s is not a valid POSIX macro", s));
820           EXTEND(SP, 1);
821           PUSHs(&PL_sv_undef);
822           PUSHs(sv);
823           break;
824         case PERL_constant_NOTDEF:
825           sv = sv_2mortal(newSVpvf(
826             "Your vendor has not defined POSIX macro %s, used", s));
827           EXTEND(SP, 1);
828           PUSHs(&PL_sv_undef);
829           PUSHs(sv);
830           break;
831         case PERL_constant_ISIV:
832           PUSHi(iv);
833           break;
834         default:
835           sv = sv_2mortal(newSVpvf(
836             "Unexpected return type %d while processing POSIX macro %s, used",
837                type, s));
838           EXTEND(SP, 1);
839           PUSHs(&PL_sv_undef);
840           PUSHs(sv);
841         }
842
843 int
844 isalnum(charstring)
845         unsigned char * charstring
846     CODE:
847         unsigned char *s = charstring;
848         unsigned char *e = s + SvCUR(ST(0));
849         for (RETVAL = 1; RETVAL && s < e; s++)
850             if (!isalnum(*s))
851                 RETVAL = 0;
852     OUTPUT:
853         RETVAL
854
855 int
856 isalpha(charstring)
857         unsigned char * charstring
858     CODE:
859         unsigned char *s = charstring;
860         unsigned char *e = s + SvCUR(ST(0));
861         for (RETVAL = 1; RETVAL && s < e; s++)
862             if (!isalpha(*s))
863                 RETVAL = 0;
864     OUTPUT:
865         RETVAL
866
867 int
868 iscntrl(charstring)
869         unsigned char * charstring
870     CODE:
871         unsigned char *s = charstring;
872         unsigned char *e = s + SvCUR(ST(0));
873         for (RETVAL = 1; RETVAL && s < e; s++)
874             if (!iscntrl(*s))
875                 RETVAL = 0;
876     OUTPUT:
877         RETVAL
878
879 int
880 isdigit(charstring)
881         unsigned char * charstring
882     CODE:
883         unsigned char *s = charstring;
884         unsigned char *e = s + SvCUR(ST(0));
885         for (RETVAL = 1; RETVAL && s < e; s++)
886             if (!isdigit(*s))
887                 RETVAL = 0;
888     OUTPUT:
889         RETVAL
890
891 int
892 isgraph(charstring)
893         unsigned char * charstring
894     CODE:
895         unsigned char *s = charstring;
896         unsigned char *e = s + SvCUR(ST(0));
897         for (RETVAL = 1; RETVAL && s < e; s++)
898             if (!isgraph(*s))
899                 RETVAL = 0;
900     OUTPUT:
901         RETVAL
902
903 int
904 islower(charstring)
905         unsigned char * charstring
906     CODE:
907         unsigned char *s = charstring;
908         unsigned char *e = s + SvCUR(ST(0));
909         for (RETVAL = 1; RETVAL && s < e; s++)
910             if (!islower(*s))
911                 RETVAL = 0;
912     OUTPUT:
913         RETVAL
914
915 int
916 isprint(charstring)
917         unsigned char * charstring
918     CODE:
919         unsigned char *s = charstring;
920         unsigned char *e = s + SvCUR(ST(0));
921         for (RETVAL = 1; RETVAL && s < e; s++)
922             if (!isprint(*s))
923                 RETVAL = 0;
924     OUTPUT:
925         RETVAL
926
927 int
928 ispunct(charstring)
929         unsigned char * charstring
930     CODE:
931         unsigned char *s = charstring;
932         unsigned char *e = s + SvCUR(ST(0));
933         for (RETVAL = 1; RETVAL && s < e; s++)
934             if (!ispunct(*s))
935                 RETVAL = 0;
936     OUTPUT:
937         RETVAL
938
939 int
940 isspace(charstring)
941         unsigned char * charstring
942     CODE:
943         unsigned char *s = charstring;
944         unsigned char *e = s + SvCUR(ST(0));
945         for (RETVAL = 1; RETVAL && s < e; s++)
946             if (!isspace(*s))
947                 RETVAL = 0;
948     OUTPUT:
949         RETVAL
950
951 int
952 isupper(charstring)
953         unsigned char * charstring
954     CODE:
955         unsigned char *s = charstring;
956         unsigned char *e = s + SvCUR(ST(0));
957         for (RETVAL = 1; RETVAL && s < e; s++)
958             if (!isupper(*s))
959                 RETVAL = 0;
960     OUTPUT:
961         RETVAL
962
963 int
964 isxdigit(charstring)
965         unsigned char * charstring
966     CODE:
967         unsigned char *s = charstring;
968         unsigned char *e = s + SvCUR(ST(0));
969         for (RETVAL = 1; RETVAL && s < e; s++)
970             if (!isxdigit(*s))
971                 RETVAL = 0;
972     OUTPUT:
973         RETVAL
974
975 SysRet
976 open(filename, flags = O_RDONLY, mode = 0666)
977         char *          filename
978         int             flags
979         Mode_t          mode
980     CODE:
981         if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
982             TAINT_PROPER("open");
983         RETVAL = open(filename, flags, mode);
984     OUTPUT:
985         RETVAL
986
987
988 HV *
989 localeconv()
990     CODE:
991 #ifdef HAS_LOCALECONV
992         struct lconv *lcbuf;
993         RETVAL = newHV();
994         if ((lcbuf = localeconv())) {
995             /* the strings */
996             if (lcbuf->decimal_point && *lcbuf->decimal_point)
997                 hv_store(RETVAL, "decimal_point", 13,
998                     newSVpv(lcbuf->decimal_point, 0), 0);
999             if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
1000                 hv_store(RETVAL, "thousands_sep", 13,
1001                     newSVpv(lcbuf->thousands_sep, 0), 0);
1002 #ifndef NO_LOCALECONV_GROUPING
1003             if (lcbuf->grouping && *lcbuf->grouping)
1004                 hv_store(RETVAL, "grouping", 8,
1005                     newSVpv(lcbuf->grouping, 0), 0);
1006 #endif
1007             if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
1008                 hv_store(RETVAL, "int_curr_symbol", 15,
1009                     newSVpv(lcbuf->int_curr_symbol, 0), 0);
1010             if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
1011                 hv_store(RETVAL, "currency_symbol", 15,
1012                     newSVpv(lcbuf->currency_symbol, 0), 0);
1013             if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
1014                 hv_store(RETVAL, "mon_decimal_point", 17,
1015                     newSVpv(lcbuf->mon_decimal_point, 0), 0);
1016 #ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1017             if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
1018                 hv_store(RETVAL, "mon_thousands_sep", 17,
1019                     newSVpv(lcbuf->mon_thousands_sep, 0), 0);
1020 #endif                    
1021 #ifndef NO_LOCALECONV_MON_GROUPING
1022             if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
1023                 hv_store(RETVAL, "mon_grouping", 12,
1024                     newSVpv(lcbuf->mon_grouping, 0), 0);
1025 #endif
1026             if (lcbuf->positive_sign && *lcbuf->positive_sign)
1027                 hv_store(RETVAL, "positive_sign", 13,
1028                     newSVpv(lcbuf->positive_sign, 0), 0);
1029             if (lcbuf->negative_sign && *lcbuf->negative_sign)
1030                 hv_store(RETVAL, "negative_sign", 13,
1031                     newSVpv(lcbuf->negative_sign, 0), 0);
1032             /* the integers */
1033             if (lcbuf->int_frac_digits != CHAR_MAX)
1034                 hv_store(RETVAL, "int_frac_digits", 15,
1035                     newSViv(lcbuf->int_frac_digits), 0);
1036             if (lcbuf->frac_digits != CHAR_MAX)
1037                 hv_store(RETVAL, "frac_digits", 11,
1038                     newSViv(lcbuf->frac_digits), 0);
1039             if (lcbuf->p_cs_precedes != CHAR_MAX)
1040                 hv_store(RETVAL, "p_cs_precedes", 13,
1041                     newSViv(lcbuf->p_cs_precedes), 0);
1042             if (lcbuf->p_sep_by_space != CHAR_MAX)
1043                 hv_store(RETVAL, "p_sep_by_space", 14,
1044                     newSViv(lcbuf->p_sep_by_space), 0);
1045             if (lcbuf->n_cs_precedes != CHAR_MAX)
1046                 hv_store(RETVAL, "n_cs_precedes", 13,
1047                     newSViv(lcbuf->n_cs_precedes), 0);
1048             if (lcbuf->n_sep_by_space != CHAR_MAX)
1049                 hv_store(RETVAL, "n_sep_by_space", 14,
1050                     newSViv(lcbuf->n_sep_by_space), 0);
1051             if (lcbuf->p_sign_posn != CHAR_MAX)
1052                 hv_store(RETVAL, "p_sign_posn", 11,
1053                     newSViv(lcbuf->p_sign_posn), 0);
1054             if (lcbuf->n_sign_posn != CHAR_MAX)
1055                 hv_store(RETVAL, "n_sign_posn", 11,
1056                     newSViv(lcbuf->n_sign_posn), 0);
1057         }
1058 #else
1059         localeconv(); /* A stub to call not_here(). */
1060 #endif
1061     OUTPUT:
1062         RETVAL
1063
1064 char *
1065 setlocale(category, locale = 0)
1066         int             category
1067         char *          locale
1068     CODE:
1069         RETVAL = setlocale(category, locale);
1070         if (RETVAL) {
1071 #ifdef USE_LOCALE_CTYPE
1072             if (category == LC_CTYPE
1073 #ifdef LC_ALL
1074                 || category == LC_ALL
1075 #endif
1076                 )
1077             {
1078                 char *newctype;
1079 #ifdef LC_ALL
1080                 if (category == LC_ALL)
1081                     newctype = setlocale(LC_CTYPE, NULL);
1082                 else
1083 #endif
1084                     newctype = RETVAL;
1085                 new_ctype(newctype);
1086             }
1087 #endif /* USE_LOCALE_CTYPE */
1088 #ifdef USE_LOCALE_COLLATE
1089             if (category == LC_COLLATE
1090 #ifdef LC_ALL
1091                 || category == LC_ALL
1092 #endif
1093                 )
1094             {
1095                 char *newcoll;
1096 #ifdef LC_ALL
1097                 if (category == LC_ALL)
1098                     newcoll = setlocale(LC_COLLATE, NULL);
1099                 else
1100 #endif
1101                     newcoll = RETVAL;
1102                 new_collate(newcoll);
1103             }
1104 #endif /* USE_LOCALE_COLLATE */
1105 #ifdef USE_LOCALE_NUMERIC
1106             if (category == LC_NUMERIC
1107 #ifdef LC_ALL
1108                 || category == LC_ALL
1109 #endif
1110                 )
1111             {
1112                 char *newnum;
1113 #ifdef LC_ALL
1114                 if (category == LC_ALL)
1115                     newnum = setlocale(LC_NUMERIC, NULL);
1116                 else
1117 #endif
1118                     newnum = RETVAL;
1119                 new_numeric(newnum);
1120             }
1121 #endif /* USE_LOCALE_NUMERIC */
1122         }
1123     OUTPUT:
1124         RETVAL
1125
1126
1127 NV
1128 acos(x)
1129         NV              x
1130
1131 NV
1132 asin(x)
1133         NV              x
1134
1135 NV
1136 atan(x)
1137         NV              x
1138
1139 NV
1140 ceil(x)
1141         NV              x
1142
1143 NV
1144 cosh(x)
1145         NV              x
1146
1147 NV
1148 floor(x)
1149         NV              x
1150
1151 NV
1152 fmod(x,y)
1153         NV              x
1154         NV              y
1155
1156 void
1157 frexp(x)
1158         NV              x
1159     PPCODE:
1160         int expvar;
1161         /* (We already know stack is long enough.) */
1162         PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1163         PUSHs(sv_2mortal(newSViv(expvar)));
1164
1165 NV
1166 ldexp(x,exp)
1167         NV              x
1168         int             exp
1169
1170 NV
1171 log10(x)
1172         NV              x
1173
1174 void
1175 modf(x)
1176         NV              x
1177     PPCODE:
1178         NV intvar;
1179         /* (We already know stack is long enough.) */
1180         PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
1181         PUSHs(sv_2mortal(newSVnv(intvar)));
1182
1183 NV
1184 sinh(x)
1185         NV              x
1186
1187 NV
1188 tan(x)
1189         NV              x
1190
1191 NV
1192 tanh(x)
1193         NV              x
1194
1195 SysRet
1196 sigaction(sig, optaction, oldaction = 0)
1197         int                     sig
1198         SV *                    optaction
1199         POSIX::SigAction        oldaction
1200     CODE:
1201 #if defined(WIN32) || defined(NETWARE)
1202         RETVAL = not_here("sigaction");
1203 #else
1204 # This code is really grody because we're trying to make the signal
1205 # interface look beautiful, which is hard.
1206
1207         {
1208             POSIX__SigAction action;
1209             GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
1210             struct sigaction act;
1211             struct sigaction oact;
1212             sigset_t sset;
1213             SV *osset_sv;
1214             sigset_t osset;
1215             POSIX__SigSet sigset;
1216             SV** svp;
1217             SV** sigsvp;
1218             if (sig == 0 && SvPOK(ST(0))) {
1219                 char *s = SvPVX(ST(0));
1220                 int i = whichsig(s);
1221
1222                 if (i < 0 && memEQ(s, "SIG", 3))
1223                     i = whichsig(s + 3);
1224                 if (i < 0) {
1225                     if (ckWARN(WARN_SIGNAL))
1226                         Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1227                                     "No such signal: SIG%s", s);
1228                     XSRETURN_UNDEF;
1229                 }
1230                 else
1231                     sig = i;
1232             }
1233             sigsvp = hv_fetch(GvHVn(siggv),
1234                               PL_sig_name[sig],
1235                               strlen(PL_sig_name[sig]),
1236                               TRUE);
1237
1238             /* Check optaction and set action */
1239             if(SvTRUE(optaction)) {
1240                 if(sv_isa(optaction, "POSIX::SigAction"))
1241                         action = (HV*)SvRV(optaction);
1242                 else
1243                         croak("action is not of type POSIX::SigAction");
1244             }
1245             else {
1246                 action=0;
1247             }
1248
1249             /* sigaction() is supposed to look atomic. In particular, any
1250              * signal handler invoked during a sigaction() call should
1251              * see either the old or the new disposition, and not something
1252              * in between. We use sigprocmask() to make it so.
1253              */
1254             sigfillset(&sset);
1255             RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1256             if(RETVAL == -1)
1257                XSRETURN_UNDEF;
1258             ENTER;
1259             /* Restore signal mask no matter how we exit this block. */
1260             osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1261             SAVEFREESV( osset_sv );
1262             SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1263
1264             RETVAL=-1; /* In case both oldaction and action are 0. */
1265
1266             /* Remember old disposition if desired. */
1267             if (oldaction) {
1268                 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1269                 if(!svp)
1270                     croak("Can't supply an oldaction without a HANDLER");
1271                 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1272                         sv_setsv(*svp, *sigsvp);
1273                 }
1274                 else {
1275                         sv_setpv(*svp, "DEFAULT");
1276                 }
1277                 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1278                 if(RETVAL == -1)
1279                    XSRETURN_UNDEF;
1280                 /* Get back the mask. */
1281                 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1282                 if (sv_isa(*svp, "POSIX::SigSet")) {
1283                     IV tmp = SvIV((SV*)SvRV(*svp));
1284                     sigset = INT2PTR(sigset_t*, tmp);
1285                 }
1286                 else {
1287                     New(0, sigset, 1, sigset_t);
1288                     sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1289                 }
1290                 *sigset = oact.sa_mask;
1291
1292                 /* Get back the flags. */
1293                 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1294                 sv_setiv(*svp, oact.sa_flags);
1295
1296                 /* Get back whether the old handler used safe signals. */
1297                 svp = hv_fetch(oldaction, "SAFE", 4, TRUE);
1298                 sv_setiv(*svp, oact.sa_handler == PL_csighandlerp);
1299             }
1300
1301             if (action) {
1302                 /* Safe signals use "csighandler", which vectors through the
1303                    PL_sighandlerp pointer when it's safe to do so.
1304                    (BTW, "csighandler" is very different from "sighandler".) */
1305                 svp = hv_fetch(action, "SAFE", 4, FALSE);
1306                 act.sa_handler = (*svp && SvTRUE(*svp))
1307                                  ? PL_csighandlerp : PL_sighandlerp;
1308
1309                 /* Vector new Perl handler through %SIG.
1310                    (The core signal handlers read %SIG to dispatch.) */
1311                 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1312                 if (!svp)
1313                     croak("Can't supply an action without a HANDLER");
1314                 sv_setsv(*sigsvp, *svp);
1315
1316                 /* This call actually calls sigaction() with almost the
1317                    right settings, including appropriate interpretation
1318                    of DEFAULT and IGNORE.  However, why are we doing
1319                    this when we're about to do it again just below?  XXX */
1320                 mg_set(*sigsvp);
1321
1322                 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1323                 if(SvPOK(*svp)) {
1324                         char *s=SvPVX(*svp);
1325                         if(strEQ(s,"IGNORE")) {
1326                                 act.sa_handler = SIG_IGN;
1327                         }
1328                         else if(strEQ(s,"DEFAULT")) {
1329                                 act.sa_handler = SIG_DFL;
1330                         }
1331                 }
1332
1333                 /* Set up any desired mask. */
1334                 svp = hv_fetch(action, "MASK", 4, FALSE);
1335                 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
1336                     IV tmp = SvIV((SV*)SvRV(*svp));
1337                     sigset = INT2PTR(sigset_t*, tmp);
1338                     act.sa_mask = *sigset;
1339                 }
1340                 else
1341                     sigemptyset(& act.sa_mask);
1342
1343                 /* Set up any desired flags. */
1344                 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1345                 act.sa_flags = svp ? SvIV(*svp) : 0;
1346
1347                 /* Don't worry about cleaning up *sigsvp if this fails,
1348                  * because that means we tried to disposition a
1349                  * nonblockable signal, in which case *sigsvp is
1350                  * essentially meaningless anyway.
1351                  */
1352                 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
1353                if(RETVAL == -1)
1354                    XSRETURN_UNDEF;
1355             }
1356
1357             LEAVE;
1358         }
1359 #endif
1360     OUTPUT:
1361         RETVAL
1362
1363 SysRet
1364 sigpending(sigset)
1365         POSIX::SigSet           sigset
1366
1367 SysRet
1368 sigprocmask(how, sigset, oldsigset = 0)
1369         int                     how
1370         POSIX::SigSet           sigset
1371         POSIX::SigSet           oldsigset = NO_INIT
1372 INIT:
1373         if ( items < 3 ) {
1374             oldsigset = 0;
1375         }
1376         else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
1377             IV tmp = SvIV((SV*)SvRV(ST(2)));
1378             oldsigset = INT2PTR(POSIX__SigSet,tmp);
1379         }
1380         else {
1381             New(0, oldsigset, 1, sigset_t);
1382             sigemptyset(oldsigset);
1383             sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
1384         }
1385
1386 SysRet
1387 sigsuspend(signal_mask)
1388         POSIX::SigSet           signal_mask
1389
1390 void
1391 _exit(status)
1392         int             status
1393
1394 SysRet
1395 close(fd)
1396         int             fd
1397
1398 SysRet
1399 dup(fd)
1400         int             fd
1401
1402 SysRet
1403 dup2(fd1, fd2)
1404         int             fd1
1405         int             fd2
1406
1407 SV *
1408 lseek(fd, offset, whence)
1409         int             fd
1410         Off_t           offset
1411         int             whence
1412     CODE:
1413         Off_t pos = PerlLIO_lseek(fd, offset, whence);
1414         RETVAL = sizeof(Off_t) > sizeof(IV)
1415                  ? newSVnv((NV)pos) : newSViv((IV)pos);
1416     OUTPUT:
1417         RETVAL
1418
1419 void
1420 nice(incr)
1421         int             incr
1422     PPCODE:
1423         errno = 0;
1424         if ((incr = nice(incr)) != -1 || errno == 0) {
1425             if (incr == 0)
1426                 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1427             else
1428                 XPUSHs(sv_2mortal(newSViv(incr)));
1429         }
1430
1431 void
1432 pipe()
1433     PPCODE:
1434         int fds[2];
1435         if (pipe(fds) != -1) {
1436             EXTEND(SP,2);
1437             PUSHs(sv_2mortal(newSViv(fds[0])));
1438             PUSHs(sv_2mortal(newSViv(fds[1])));
1439         }
1440
1441 SysRet
1442 read(fd, buffer, nbytes)
1443     PREINIT:
1444         SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1445     INPUT:
1446         int             fd
1447         size_t          nbytes
1448         char *          buffer = sv_grow( sv_buffer, nbytes+1 );
1449     CLEANUP:
1450         if (RETVAL >= 0) {
1451             SvCUR(sv_buffer) = RETVAL;
1452             SvPOK_only(sv_buffer);
1453             *SvEND(sv_buffer) = '\0';
1454             SvTAINTED_on(sv_buffer);
1455         }
1456
1457 SysRet
1458 setpgid(pid, pgid)
1459         pid_t           pid
1460         pid_t           pgid
1461
1462 pid_t
1463 setsid()
1464
1465 pid_t
1466 tcgetpgrp(fd)
1467         int             fd
1468
1469 SysRet
1470 tcsetpgrp(fd, pgrp_id)
1471         int             fd
1472         pid_t           pgrp_id
1473
1474 void
1475 uname()
1476     PPCODE:
1477 #ifdef HAS_UNAME
1478         struct utsname buf;
1479         if (uname(&buf) >= 0) {
1480             EXTEND(SP, 5);
1481             PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1482             PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1483             PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1484             PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1485             PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
1486         }
1487 #else
1488         uname((char *) 0); /* A stub to call not_here(). */
1489 #endif
1490
1491 SysRet
1492 write(fd, buffer, nbytes)
1493         int             fd
1494         char *          buffer
1495         size_t          nbytes
1496
1497 SV *
1498 tmpnam()
1499     PREINIT:
1500         STRLEN i;
1501         int len;
1502     CODE:
1503         RETVAL = newSVpvn("", 0);
1504         SvGROW(RETVAL, L_tmpnam);
1505         len = strlen(tmpnam(SvPV(RETVAL, i)));
1506         SvCUR_set(RETVAL, len);
1507     OUTPUT:
1508         RETVAL
1509
1510 void
1511 abort()
1512
1513 int
1514 mblen(s, n)
1515         char *          s
1516         size_t          n
1517
1518 size_t
1519 mbstowcs(s, pwcs, n)
1520         wchar_t *       s
1521         char *          pwcs
1522         size_t          n
1523
1524 int
1525 mbtowc(pwc, s, n)
1526         wchar_t *       pwc
1527         char *          s
1528         size_t          n
1529
1530 int
1531 wcstombs(s, pwcs, n)
1532         char *          s
1533         wchar_t *       pwcs
1534         size_t          n
1535
1536 int
1537 wctomb(s, wchar)
1538         char *          s
1539         wchar_t         wchar
1540
1541 int
1542 strcoll(s1, s2)
1543         char *          s1
1544         char *          s2
1545
1546 void
1547 strtod(str)
1548         char *          str
1549     PREINIT:
1550         double num;
1551         char *unparsed;
1552     PPCODE:
1553         SET_NUMERIC_LOCAL();
1554         num = strtod(str, &unparsed);
1555         PUSHs(sv_2mortal(newSVnv(num)));
1556         if (GIMME == G_ARRAY) {
1557             EXTEND(SP, 1);
1558             if (unparsed)
1559                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1560             else
1561                 PUSHs(&PL_sv_undef);
1562         }
1563
1564 void
1565 strtol(str, base = 0)
1566         char *          str
1567         int             base
1568     PREINIT:
1569         long num;
1570         char *unparsed;
1571     PPCODE:
1572         num = strtol(str, &unparsed, base);
1573 #if IVSIZE <= LONGSIZE
1574         if (num < IV_MIN || num > IV_MAX)
1575             PUSHs(sv_2mortal(newSVnv((double)num)));
1576         else
1577 #endif
1578             PUSHs(sv_2mortal(newSViv((IV)num)));
1579         if (GIMME == G_ARRAY) {
1580             EXTEND(SP, 1);
1581             if (unparsed)
1582                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1583             else
1584                 PUSHs(&PL_sv_undef);
1585         }
1586
1587 void
1588 strtoul(str, base = 0)
1589         char *          str
1590         int             base
1591     PREINIT:
1592         unsigned long num;
1593         char *unparsed;
1594     PPCODE:
1595         num = strtoul(str, &unparsed, base);
1596 #if IVSIZE <= LONGSIZE
1597         if (num > IV_MAX)
1598             PUSHs(sv_2mortal(newSVnv((double)num)));
1599         else
1600 #endif
1601             PUSHs(sv_2mortal(newSViv((IV)num)));
1602         if (GIMME == G_ARRAY) {
1603             EXTEND(SP, 1);
1604             if (unparsed)
1605                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1606             else
1607                 PUSHs(&PL_sv_undef);
1608         }
1609
1610 void
1611 strxfrm(src)
1612         SV *            src
1613     CODE:
1614         {
1615           STRLEN srclen;
1616           STRLEN dstlen;
1617           char *p = SvPV(src,srclen);
1618           srclen++;
1619           ST(0) = sv_2mortal(NEWSV(800,srclen*4+1));
1620           dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1621           if (dstlen > srclen) {
1622               dstlen++;
1623               SvGROW(ST(0), dstlen);
1624               strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1625               dstlen--;
1626           }
1627           SvCUR(ST(0)) = dstlen;
1628             SvPOK_only(ST(0));
1629         }
1630
1631 SysRet
1632 mkfifo(filename, mode)
1633         char *          filename
1634         Mode_t          mode
1635     CODE:
1636         TAINT_PROPER("mkfifo");
1637         RETVAL = mkfifo(filename, mode);
1638     OUTPUT:
1639         RETVAL
1640
1641 SysRet
1642 tcdrain(fd)
1643         int             fd
1644
1645
1646 SysRet
1647 tcflow(fd, action)
1648         int             fd
1649         int             action
1650
1651
1652 SysRet
1653 tcflush(fd, queue_selector)
1654         int             fd
1655         int             queue_selector
1656
1657 SysRet
1658 tcsendbreak(fd, duration)
1659         int             fd
1660         int             duration
1661
1662 char *
1663 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1664         int             sec
1665         int             min
1666         int             hour
1667         int             mday
1668         int             mon
1669         int             year
1670         int             wday
1671         int             yday
1672         int             isdst
1673     CODE:
1674         {
1675             struct tm mytm;
1676             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1677             mytm.tm_sec = sec;
1678             mytm.tm_min = min;
1679             mytm.tm_hour = hour;
1680             mytm.tm_mday = mday;
1681             mytm.tm_mon = mon;
1682             mytm.tm_year = year;
1683             mytm.tm_wday = wday;
1684             mytm.tm_yday = yday;
1685             mytm.tm_isdst = isdst;
1686             RETVAL = asctime(&mytm);
1687         }
1688     OUTPUT:
1689         RETVAL
1690
1691 long
1692 clock()
1693
1694 char *
1695 ctime(time)
1696         Time_t          &time
1697
1698 void
1699 times()
1700         PPCODE:
1701         struct tms tms;
1702         clock_t realtime;
1703         realtime = times( &tms );
1704         EXTEND(SP,5);
1705         PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1706         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1707         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1708         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1709         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
1710
1711 double
1712 difftime(time1, time2)
1713         Time_t          time1
1714         Time_t          time2
1715
1716 SysRetLong
1717 mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1718         int             sec
1719         int             min
1720         int             hour
1721         int             mday
1722         int             mon
1723         int             year
1724         int             wday
1725         int             yday
1726         int             isdst
1727     CODE:
1728         {
1729             struct tm mytm;
1730             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1731             mytm.tm_sec = sec;
1732             mytm.tm_min = min;
1733             mytm.tm_hour = hour;
1734             mytm.tm_mday = mday;
1735             mytm.tm_mon = mon;
1736             mytm.tm_year = year;
1737             mytm.tm_wday = wday;
1738             mytm.tm_yday = yday;
1739             mytm.tm_isdst = isdst;
1740             RETVAL = mktime(&mytm);
1741         }
1742     OUTPUT:
1743         RETVAL
1744
1745 #XXX: if $xsubpp::WantOptimize is always the default
1746 #     sv_setpv(TARG, ...) could be used rather than
1747 #     ST(0) = sv_2mortal(newSVpv(...))
1748 void
1749 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
1750         char *          fmt
1751         int             sec
1752         int             min
1753         int             hour
1754         int             mday
1755         int             mon
1756         int             year
1757         int             wday
1758         int             yday
1759         int             isdst
1760     CODE:
1761         {
1762             char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
1763             if (buf) {
1764                 ST(0) = sv_2mortal(newSVpv(buf, 0));
1765                 Safefree(buf);
1766             }
1767         }
1768
1769 void
1770 tzset()
1771
1772 void
1773 tzname()
1774     PPCODE:
1775         EXTEND(SP,2);
1776         PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1777         PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
1778
1779 SysRet
1780 access(filename, mode)
1781         char *          filename
1782         Mode_t          mode
1783
1784 char *
1785 ctermid(s = 0)
1786         char *          s = 0;
1787
1788 char *
1789 cuserid(s = 0)
1790         char *          s = 0;
1791
1792 SysRetLong
1793 fpathconf(fd, name)
1794         int             fd
1795         int             name
1796
1797 SysRetLong
1798 pathconf(filename, name)
1799         char *          filename
1800         int             name
1801
1802 SysRet
1803 pause()
1804
1805 SysRet
1806 setgid(gid)
1807         Gid_t           gid
1808
1809 SysRet
1810 setuid(uid)
1811         Uid_t           uid
1812
1813 SysRetLong
1814 sysconf(name)
1815         int             name
1816
1817 char *
1818 ttyname(fd)
1819         int             fd
1820
1821 void
1822 getcwd()
1823     PPCODE:
1824       {
1825         dXSTARG;
1826         getcwd_sv(TARG);
1827         XSprePUSH; PUSHTARG;
1828       }
1829