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