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