(Retracted by #11175)
[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(sigset_t *ossetp)
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             (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
533 }
534
535 MODULE = SigSet         PACKAGE = POSIX::SigSet         PREFIX = sig
536
537 POSIX::SigSet
538 new(packname = "POSIX::SigSet", ...)
539     char *              packname
540     CODE:
541         {
542             int i;
543             New(0, RETVAL, 1, sigset_t);
544             sigemptyset(RETVAL);
545             for (i = 1; i < items; i++)
546                 sigaddset(RETVAL, SvIV(ST(i)));
547         }
548     OUTPUT:
549         RETVAL
550
551 void
552 DESTROY(sigset)
553         POSIX::SigSet   sigset
554     CODE:
555         Safefree(sigset);
556
557 SysRet
558 sigaddset(sigset, sig)
559         POSIX::SigSet   sigset
560         int             sig
561
562 SysRet
563 sigdelset(sigset, sig)
564         POSIX::SigSet   sigset
565         int             sig
566
567 SysRet
568 sigemptyset(sigset)
569         POSIX::SigSet   sigset
570
571 SysRet
572 sigfillset(sigset)
573         POSIX::SigSet   sigset
574
575 int
576 sigismember(sigset, sig)
577         POSIX::SigSet   sigset
578         int             sig
579
580
581 MODULE = Termios        PACKAGE = POSIX::Termios        PREFIX = cf
582
583 POSIX::Termios
584 new(packname = "POSIX::Termios", ...)
585     char *              packname
586     CODE:
587         {
588 #ifdef I_TERMIOS
589             New(0, RETVAL, 1, struct termios);
590 #else
591             not_here("termios");
592         RETVAL = 0;
593 #endif
594         }
595     OUTPUT:
596         RETVAL
597
598 void
599 DESTROY(termios_ref)
600         POSIX::Termios  termios_ref
601     CODE:
602 #ifdef I_TERMIOS
603         Safefree(termios_ref);
604 #else
605             not_here("termios");
606 #endif
607
608 SysRet
609 getattr(termios_ref, fd = 0)
610         POSIX::Termios  termios_ref
611         int             fd
612     CODE:
613         RETVAL = tcgetattr(fd, termios_ref);
614     OUTPUT:
615         RETVAL
616
617 SysRet
618 setattr(termios_ref, fd = 0, optional_actions = 0)
619         POSIX::Termios  termios_ref
620         int             fd
621         int             optional_actions
622     CODE:
623         RETVAL = tcsetattr(fd, optional_actions, termios_ref);
624     OUTPUT:
625         RETVAL
626
627 speed_t
628 cfgetispeed(termios_ref)
629         POSIX::Termios  termios_ref
630
631 speed_t
632 cfgetospeed(termios_ref)
633         POSIX::Termios  termios_ref
634
635 tcflag_t
636 getiflag(termios_ref)
637         POSIX::Termios  termios_ref
638     CODE:
639 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
640         RETVAL = termios_ref->c_iflag;
641 #else
642      not_here("getiflag");
643      RETVAL = 0;
644 #endif
645     OUTPUT:
646         RETVAL
647
648 tcflag_t
649 getoflag(termios_ref)
650         POSIX::Termios  termios_ref
651     CODE:
652 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
653         RETVAL = termios_ref->c_oflag;
654 #else
655      not_here("getoflag");
656      RETVAL = 0;
657 #endif
658     OUTPUT:
659         RETVAL
660
661 tcflag_t
662 getcflag(termios_ref)
663         POSIX::Termios  termios_ref
664     CODE:
665 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
666         RETVAL = termios_ref->c_cflag;
667 #else
668      not_here("getcflag");
669      RETVAL = 0;
670 #endif
671     OUTPUT:
672         RETVAL
673
674 tcflag_t
675 getlflag(termios_ref)
676         POSIX::Termios  termios_ref
677     CODE:
678 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
679         RETVAL = termios_ref->c_lflag;
680 #else
681      not_here("getlflag");
682      RETVAL = 0;
683 #endif
684     OUTPUT:
685         RETVAL
686
687 cc_t
688 getcc(termios_ref, ccix)
689         POSIX::Termios  termios_ref
690         int             ccix
691     CODE:
692 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
693         if (ccix >= NCCS)
694             croak("Bad getcc subscript");
695         RETVAL = termios_ref->c_cc[ccix];
696 #else
697      not_here("getcc");
698      RETVAL = 0;
699 #endif
700     OUTPUT:
701         RETVAL
702
703 SysRet
704 cfsetispeed(termios_ref, speed)
705         POSIX::Termios  termios_ref
706         speed_t         speed
707
708 SysRet
709 cfsetospeed(termios_ref, speed)
710         POSIX::Termios  termios_ref
711         speed_t         speed
712
713 void
714 setiflag(termios_ref, iflag)
715         POSIX::Termios  termios_ref
716         tcflag_t        iflag
717     CODE:
718 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
719         termios_ref->c_iflag = iflag;
720 #else
721             not_here("setiflag");
722 #endif
723
724 void
725 setoflag(termios_ref, oflag)
726         POSIX::Termios  termios_ref
727         tcflag_t        oflag
728     CODE:
729 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
730         termios_ref->c_oflag = oflag;
731 #else
732             not_here("setoflag");
733 #endif
734
735 void
736 setcflag(termios_ref, cflag)
737         POSIX::Termios  termios_ref
738         tcflag_t        cflag
739     CODE:
740 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
741         termios_ref->c_cflag = cflag;
742 #else
743             not_here("setcflag");
744 #endif
745
746 void
747 setlflag(termios_ref, lflag)
748         POSIX::Termios  termios_ref
749         tcflag_t        lflag
750     CODE:
751 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
752         termios_ref->c_lflag = lflag;
753 #else
754             not_here("setlflag");
755 #endif
756
757 void
758 setcc(termios_ref, ccix, cc)
759         POSIX::Termios  termios_ref
760         int             ccix
761         cc_t            cc
762     CODE:
763 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
764         if (ccix >= NCCS)
765             croak("Bad setcc subscript");
766         termios_ref->c_cc[ccix] = cc;
767 #else
768             not_here("setcc");
769 #endif
770
771
772 MODULE = POSIX          PACKAGE = POSIX
773
774 INCLUDE: constants.xs
775
776 void
777 int_macro_int(sv, iv)
778     PREINIT:
779         dXSTARG;
780         STRLEN          len;
781         int             type;
782     INPUT:
783         SV *            sv;
784         const char *    s = SvPV(sv, len);
785         IV              iv;
786     PPCODE:
787         /* Change this to int_macro_int(s, len, &iv, &nv);
788            if you need to return both NVs and IVs */
789         type = int_macro_int(s, len, &iv);
790       /* Return 1 or 2 items. First is error message, or undef if no error.
791            Second, if present, is found value */
792         switch (type) {
793         case PERL_constant_NOTFOUND:
794           sv = sv_2mortal(newSVpvf("%s is not a valid POSIX macro", s));
795           EXTEND(SP, 1);
796           PUSHs(&PL_sv_undef);
797           PUSHs(sv);
798           break;
799         case PERL_constant_NOTDEF:
800           sv = sv_2mortal(newSVpvf(
801             "Your vendor has not defined POSIX macro %s, used", s));
802           EXTEND(SP, 1);
803           PUSHs(&PL_sv_undef);
804           PUSHs(sv);
805           break;
806         case PERL_constant_ISIV:
807           PUSHi(iv);
808           break;
809         default:
810           sv = sv_2mortal(newSVpvf(
811             "Unexpected return type %d while processing POSIX macro %s, used",
812                type, s));
813           EXTEND(SP, 1);
814           PUSHs(&PL_sv_undef);
815           PUSHs(sv);
816         }
817
818 int
819 isalnum(charstring)
820         unsigned char * charstring
821     CODE:
822         unsigned char *s = charstring;
823         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
824         for (RETVAL = 1; RETVAL && s < e; s++)
825             if (!isalnum(*s))
826                 RETVAL = 0;
827     OUTPUT:
828         RETVAL
829
830 int
831 isalpha(charstring)
832         unsigned char * charstring
833     CODE:
834         unsigned char *s = charstring;
835         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
836         for (RETVAL = 1; RETVAL && s < e; s++)
837             if (!isalpha(*s))
838                 RETVAL = 0;
839     OUTPUT:
840         RETVAL
841
842 int
843 iscntrl(charstring)
844         unsigned char * charstring
845     CODE:
846         unsigned char *s = charstring;
847         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
848         for (RETVAL = 1; RETVAL && s < e; s++)
849             if (!iscntrl(*s))
850                 RETVAL = 0;
851     OUTPUT:
852         RETVAL
853
854 int
855 isdigit(charstring)
856         unsigned char * charstring
857     CODE:
858         unsigned char *s = charstring;
859         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
860         for (RETVAL = 1; RETVAL && s < e; s++)
861             if (!isdigit(*s))
862                 RETVAL = 0;
863     OUTPUT:
864         RETVAL
865
866 int
867 isgraph(charstring)
868         unsigned char * charstring
869     CODE:
870         unsigned char *s = charstring;
871         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
872         for (RETVAL = 1; RETVAL && s < e; s++)
873             if (!isgraph(*s))
874                 RETVAL = 0;
875     OUTPUT:
876         RETVAL
877
878 int
879 islower(charstring)
880         unsigned char * charstring
881     CODE:
882         unsigned char *s = charstring;
883         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
884         for (RETVAL = 1; RETVAL && s < e; s++)
885             if (!islower(*s))
886                 RETVAL = 0;
887     OUTPUT:
888         RETVAL
889
890 int
891 isprint(charstring)
892         unsigned char * charstring
893     CODE:
894         unsigned char *s = charstring;
895         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
896         for (RETVAL = 1; RETVAL && s < e; s++)
897             if (!isprint(*s))
898                 RETVAL = 0;
899     OUTPUT:
900         RETVAL
901
902 int
903 ispunct(charstring)
904         unsigned char * charstring
905     CODE:
906         unsigned char *s = charstring;
907         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
908         for (RETVAL = 1; RETVAL && s < e; s++)
909             if (!ispunct(*s))
910                 RETVAL = 0;
911     OUTPUT:
912         RETVAL
913
914 int
915 isspace(charstring)
916         unsigned char * charstring
917     CODE:
918         unsigned char *s = charstring;
919         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
920         for (RETVAL = 1; RETVAL && s < e; s++)
921             if (!isspace(*s))
922                 RETVAL = 0;
923     OUTPUT:
924         RETVAL
925
926 int
927 isupper(charstring)
928         unsigned char * charstring
929     CODE:
930         unsigned char *s = charstring;
931         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
932         for (RETVAL = 1; RETVAL && s < e; s++)
933             if (!isupper(*s))
934                 RETVAL = 0;
935     OUTPUT:
936         RETVAL
937
938 int
939 isxdigit(charstring)
940         unsigned char * charstring
941     CODE:
942         unsigned char *s = charstring;
943         unsigned char *e = s + PL_na;   /* "PL_na" set by typemap side effect */
944         for (RETVAL = 1; RETVAL && s < e; s++)
945             if (!isxdigit(*s))
946                 RETVAL = 0;
947     OUTPUT:
948         RETVAL
949
950 SysRet
951 open(filename, flags = O_RDONLY, mode = 0666)
952         char *          filename
953         int             flags
954         Mode_t          mode
955     CODE:
956         if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
957             TAINT_PROPER("open");
958         RETVAL = open(filename, flags, mode);
959     OUTPUT:
960         RETVAL
961
962
963 HV *
964 localeconv()
965     CODE:
966 #ifdef HAS_LOCALECONV
967         struct lconv *lcbuf;
968         RETVAL = newHV();
969         if ((lcbuf = localeconv())) {
970             /* the strings */
971             if (lcbuf->decimal_point && *lcbuf->decimal_point)
972                 hv_store(RETVAL, "decimal_point", 13,
973                     newSVpv(lcbuf->decimal_point, 0), 0);
974             if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
975                 hv_store(RETVAL, "thousands_sep", 13,
976                     newSVpv(lcbuf->thousands_sep, 0), 0);
977 #ifndef NO_LOCALECONV_GROUPING
978             if (lcbuf->grouping && *lcbuf->grouping)
979                 hv_store(RETVAL, "grouping", 8,
980                     newSVpv(lcbuf->grouping, 0), 0);
981 #endif
982             if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
983                 hv_store(RETVAL, "int_curr_symbol", 15,
984                     newSVpv(lcbuf->int_curr_symbol, 0), 0);
985             if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
986                 hv_store(RETVAL, "currency_symbol", 15,
987                     newSVpv(lcbuf->currency_symbol, 0), 0);
988             if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
989                 hv_store(RETVAL, "mon_decimal_point", 17,
990                     newSVpv(lcbuf->mon_decimal_point, 0), 0);
991 #ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
992             if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
993                 hv_store(RETVAL, "mon_thousands_sep", 17,
994                     newSVpv(lcbuf->mon_thousands_sep, 0), 0);
995 #endif                    
996 #ifndef NO_LOCALECONV_MON_GROUPING
997             if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
998                 hv_store(RETVAL, "mon_grouping", 12,
999                     newSVpv(lcbuf->mon_grouping, 0), 0);
1000 #endif
1001             if (lcbuf->positive_sign && *lcbuf->positive_sign)
1002                 hv_store(RETVAL, "positive_sign", 13,
1003                     newSVpv(lcbuf->positive_sign, 0), 0);
1004             if (lcbuf->negative_sign && *lcbuf->negative_sign)
1005                 hv_store(RETVAL, "negative_sign", 13,
1006                     newSVpv(lcbuf->negative_sign, 0), 0);
1007             /* the integers */
1008             if (lcbuf->int_frac_digits != CHAR_MAX)
1009                 hv_store(RETVAL, "int_frac_digits", 15,
1010                     newSViv(lcbuf->int_frac_digits), 0);
1011             if (lcbuf->frac_digits != CHAR_MAX)
1012                 hv_store(RETVAL, "frac_digits", 11,
1013                     newSViv(lcbuf->frac_digits), 0);
1014             if (lcbuf->p_cs_precedes != CHAR_MAX)
1015                 hv_store(RETVAL, "p_cs_precedes", 13,
1016                     newSViv(lcbuf->p_cs_precedes), 0);
1017             if (lcbuf->p_sep_by_space != CHAR_MAX)
1018                 hv_store(RETVAL, "p_sep_by_space", 14,
1019                     newSViv(lcbuf->p_sep_by_space), 0);
1020             if (lcbuf->n_cs_precedes != CHAR_MAX)
1021                 hv_store(RETVAL, "n_cs_precedes", 13,
1022                     newSViv(lcbuf->n_cs_precedes), 0);
1023             if (lcbuf->n_sep_by_space != CHAR_MAX)
1024                 hv_store(RETVAL, "n_sep_by_space", 14,
1025                     newSViv(lcbuf->n_sep_by_space), 0);
1026             if (lcbuf->p_sign_posn != CHAR_MAX)
1027                 hv_store(RETVAL, "p_sign_posn", 11,
1028                     newSViv(lcbuf->p_sign_posn), 0);
1029             if (lcbuf->n_sign_posn != CHAR_MAX)
1030                 hv_store(RETVAL, "n_sign_posn", 11,
1031                     newSViv(lcbuf->n_sign_posn), 0);
1032         }
1033 #else
1034         localeconv(); /* A stub to call not_here(). */
1035 #endif
1036     OUTPUT:
1037         RETVAL
1038
1039 char *
1040 setlocale(category, locale = 0)
1041         int             category
1042         char *          locale
1043     CODE:
1044         RETVAL = setlocale(category, locale);
1045         if (RETVAL) {
1046 #ifdef USE_LOCALE_CTYPE
1047             if (category == LC_CTYPE
1048 #ifdef LC_ALL
1049                 || category == LC_ALL
1050 #endif
1051                 )
1052             {
1053                 char *newctype;
1054 #ifdef LC_ALL
1055                 if (category == LC_ALL)
1056                     newctype = setlocale(LC_CTYPE, NULL);
1057                 else
1058 #endif
1059                     newctype = RETVAL;
1060                 new_ctype(newctype);
1061             }
1062 #endif /* USE_LOCALE_CTYPE */
1063 #ifdef USE_LOCALE_COLLATE
1064             if (category == LC_COLLATE
1065 #ifdef LC_ALL
1066                 || category == LC_ALL
1067 #endif
1068                 )
1069             {
1070                 char *newcoll;
1071 #ifdef LC_ALL
1072                 if (category == LC_ALL)
1073                     newcoll = setlocale(LC_COLLATE, NULL);
1074                 else
1075 #endif
1076                     newcoll = RETVAL;
1077                 new_collate(newcoll);
1078             }
1079 #endif /* USE_LOCALE_COLLATE */
1080 #ifdef USE_LOCALE_NUMERIC
1081             if (category == LC_NUMERIC
1082 #ifdef LC_ALL
1083                 || category == LC_ALL
1084 #endif
1085                 )
1086             {
1087                 char *newnum;
1088 #ifdef LC_ALL
1089                 if (category == LC_ALL)
1090                     newnum = setlocale(LC_NUMERIC, NULL);
1091                 else
1092 #endif
1093                     newnum = RETVAL;
1094                 new_numeric(newnum);
1095             }
1096 #endif /* USE_LOCALE_NUMERIC */
1097         }
1098     OUTPUT:
1099         RETVAL
1100
1101
1102 NV
1103 acos(x)
1104         NV              x
1105
1106 NV
1107 asin(x)
1108         NV              x
1109
1110 NV
1111 atan(x)
1112         NV              x
1113
1114 NV
1115 ceil(x)
1116         NV              x
1117
1118 NV
1119 cosh(x)
1120         NV              x
1121
1122 NV
1123 floor(x)
1124         NV              x
1125
1126 NV
1127 fmod(x,y)
1128         NV              x
1129         NV              y
1130
1131 void
1132 frexp(x)
1133         NV              x
1134     PPCODE:
1135         int expvar;
1136         /* (We already know stack is long enough.) */
1137         PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1138         PUSHs(sv_2mortal(newSViv(expvar)));
1139
1140 NV
1141 ldexp(x,exp)
1142         NV              x
1143         int             exp
1144
1145 NV
1146 log10(x)
1147         NV              x
1148
1149 void
1150 modf(x)
1151         NV              x
1152     PPCODE:
1153         NV intvar;
1154         /* (We already know stack is long enough.) */
1155         PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
1156         PUSHs(sv_2mortal(newSVnv(intvar)));
1157
1158 NV
1159 sinh(x)
1160         NV              x
1161
1162 NV
1163 tan(x)
1164         NV              x
1165
1166 NV
1167 tanh(x)
1168         NV              x
1169
1170 SysRet
1171 sigaction(sig, optaction, oldaction = 0)
1172         int                     sig
1173         SV *                    optaction
1174         POSIX::SigAction        oldaction
1175     CODE:
1176 #if defined(WIN32) || defined(NETWARE)
1177         RETVAL = not_here("sigaction");
1178 #else
1179 # This code is really grody because we're trying to make the signal
1180 # interface look beautiful, which is hard.
1181
1182         {
1183             POSIX__SigAction action;
1184             GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
1185             struct sigaction act;
1186             struct sigaction oact;
1187             sigset_t sset;
1188             static sigset_t osset;
1189             POSIX__SigSet sigset;
1190             SV** svp;
1191             SV** sigsvp = hv_fetch(GvHVn(siggv),
1192                                  PL_sig_name[sig],
1193                                  strlen(PL_sig_name[sig]),
1194                                  TRUE);
1195
1196             /* Check optaction and set action */
1197             if(SvTRUE(optaction)) {
1198                 if(sv_isa(optaction, "POSIX::SigAction"))
1199                         action = (HV*)SvRV(optaction);
1200                 else
1201                         croak("action is not of type POSIX::SigAction");
1202             }
1203             else {
1204                 action=0;
1205             }
1206
1207             /* sigaction() is supposed to look atomic. In particular, any
1208              * signal handler invoked during a sigaction() call should
1209              * see either the old or the new disposition, and not something
1210              * in between. We use sigprocmask() to make it so.
1211              */
1212             sigfillset(&sset);
1213             RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1214             if(RETVAL == -1)
1215                XSRETURN_UNDEF;
1216             ENTER;
1217             /* Restore signal mask no matter how we exit this block. */
1218             SAVEDESTRUCTOR(restore_sigmask, &osset);
1219
1220             RETVAL=-1; /* In case both oldaction and action are 0. */
1221
1222             /* Remember old disposition if desired. */
1223             if (oldaction) {
1224                 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1225                 if(!svp)
1226                     croak("Can't supply an oldaction without a HANDLER");
1227                 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1228                         sv_setsv(*svp, *sigsvp);
1229                 }
1230                 else {
1231                         sv_setpv(*svp, "DEFAULT");
1232                 }
1233                 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1234                 if(RETVAL == -1)
1235                    XSRETURN_UNDEF;
1236                 /* Get back the mask. */
1237                 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1238                 if (sv_isa(*svp, "POSIX::SigSet")) {
1239                     IV tmp = SvIV((SV*)SvRV(*svp));
1240                     sigset = INT2PTR(sigset_t*, tmp);
1241                 }
1242                 else {
1243                     New(0, sigset, 1, sigset_t);
1244                     sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1245                 }
1246                 *sigset = oact.sa_mask;
1247
1248                 /* Get back the flags. */
1249                 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1250                 sv_setiv(*svp, oact.sa_flags);
1251             }
1252
1253             if (action) {
1254                 /* Vector new handler through %SIG.  (We always use sighandler
1255                    for the C signal handler, which reads %SIG to dispatch.) */
1256                 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1257                 if (!svp)
1258                     croak("Can't supply an action without a HANDLER");
1259                 sv_setsv(*sigsvp, *svp);
1260                 mg_set(*sigsvp);        /* handles DEFAULT and IGNORE */
1261                 if(SvPOK(*svp)) {
1262                         char *s=SvPVX(*svp);
1263                         if(strEQ(s,"IGNORE")) {
1264                                 act.sa_handler = SIG_IGN;
1265                         }
1266                         else if(strEQ(s,"DEFAULT")) {
1267                                 act.sa_handler = SIG_DFL;
1268                         }
1269                         else {
1270                                 act.sa_handler = PL_sighandlerp;
1271                         }
1272                 }
1273                 else {
1274                         act.sa_handler = PL_sighandlerp;
1275                 }
1276
1277                 /* Set up any desired mask. */
1278                 svp = hv_fetch(action, "MASK", 4, FALSE);
1279                 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
1280                     IV tmp = SvIV((SV*)SvRV(*svp));
1281                     sigset = INT2PTR(sigset_t*, tmp);
1282                     act.sa_mask = *sigset;
1283                 }
1284                 else
1285                     sigemptyset(& act.sa_mask);
1286
1287                 /* Set up any desired flags. */
1288                 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1289                 act.sa_flags = svp ? SvIV(*svp) : 0;
1290
1291                 /* Don't worry about cleaning up *sigsvp if this fails,
1292                  * because that means we tried to disposition a
1293                  * nonblockable signal, in which case *sigsvp is
1294                  * essentially meaningless anyway.
1295                  */
1296                 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
1297                if(RETVAL == -1)
1298                    XSRETURN_UNDEF;
1299             }
1300
1301             LEAVE;
1302         }
1303 #endif
1304     OUTPUT:
1305         RETVAL
1306
1307 SysRet
1308 sigpending(sigset)
1309         POSIX::SigSet           sigset
1310
1311 SysRet
1312 sigprocmask(how, sigset, oldsigset = 0)
1313         int                     how
1314         POSIX::SigSet           sigset
1315         POSIX::SigSet           oldsigset = NO_INIT
1316 INIT:
1317         if ( items < 3 ) {
1318             oldsigset = 0;
1319         }
1320         else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
1321             IV tmp = SvIV((SV*)SvRV(ST(2)));
1322             oldsigset = INT2PTR(POSIX__SigSet,tmp);
1323         }
1324         else {
1325             New(0, oldsigset, 1, sigset_t);
1326             sigemptyset(oldsigset);
1327             sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
1328         }
1329
1330 SysRet
1331 sigsuspend(signal_mask)
1332         POSIX::SigSet           signal_mask
1333
1334 void
1335 _exit(status)
1336         int             status
1337
1338 SysRet
1339 close(fd)
1340         int             fd
1341
1342 SysRet
1343 dup(fd)
1344         int             fd
1345
1346 SysRet
1347 dup2(fd1, fd2)
1348         int             fd1
1349         int             fd2
1350
1351 SysRetLong
1352 lseek(fd, offset, whence)
1353         int             fd
1354         Off_t           offset
1355         int             whence
1356
1357 SysRet
1358 nice(incr)
1359         int             incr
1360
1361 void
1362 pipe()
1363     PPCODE:
1364         int fds[2];
1365         if (pipe(fds) != -1) {
1366             EXTEND(SP,2);
1367             PUSHs(sv_2mortal(newSViv(fds[0])));
1368             PUSHs(sv_2mortal(newSViv(fds[1])));
1369         }
1370
1371 SysRet
1372 read(fd, buffer, nbytes)
1373     PREINIT:
1374         SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1375     INPUT:
1376         int             fd
1377         size_t          nbytes
1378         char *          buffer = sv_grow( sv_buffer, nbytes+1 );
1379     CLEANUP:
1380         if (RETVAL >= 0) {
1381             SvCUR(sv_buffer) = RETVAL;
1382             SvPOK_only(sv_buffer);
1383             *SvEND(sv_buffer) = '\0';
1384             SvTAINTED_on(sv_buffer);
1385         }
1386
1387 SysRet
1388 setpgid(pid, pgid)
1389         pid_t           pid
1390         pid_t           pgid
1391
1392 pid_t
1393 setsid()
1394
1395 pid_t
1396 tcgetpgrp(fd)
1397         int             fd
1398
1399 SysRet
1400 tcsetpgrp(fd, pgrp_id)
1401         int             fd
1402         pid_t           pgrp_id
1403
1404 void
1405 uname()
1406     PPCODE:
1407 #ifdef HAS_UNAME
1408         struct utsname buf;
1409         if (uname(&buf) >= 0) {
1410             EXTEND(SP, 5);
1411             PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1412             PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1413             PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1414             PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1415             PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
1416         }
1417 #else
1418         uname((char *) 0); /* A stub to call not_here(). */
1419 #endif
1420
1421 SysRet
1422 write(fd, buffer, nbytes)
1423         int             fd
1424         char *          buffer
1425         size_t          nbytes
1426
1427 SV *
1428 tmpnam()
1429     PREINIT:
1430         STRLEN i;
1431         int len;
1432     CODE:
1433         RETVAL = newSVpvn("", 0);
1434         SvGROW(RETVAL, L_tmpnam);
1435         len = strlen(tmpnam(SvPV(RETVAL, i)));
1436         SvCUR_set(RETVAL, len);
1437     OUTPUT:
1438         RETVAL
1439
1440 void
1441 abort()
1442
1443 int
1444 mblen(s, n)
1445         char *          s
1446         size_t          n
1447
1448 size_t
1449 mbstowcs(s, pwcs, n)
1450         wchar_t *       s
1451         char *          pwcs
1452         size_t          n
1453
1454 int
1455 mbtowc(pwc, s, n)
1456         wchar_t *       pwc
1457         char *          s
1458         size_t          n
1459
1460 int
1461 wcstombs(s, pwcs, n)
1462         char *          s
1463         wchar_t *       pwcs
1464         size_t          n
1465
1466 int
1467 wctomb(s, wchar)
1468         char *          s
1469         wchar_t         wchar
1470
1471 int
1472 strcoll(s1, s2)
1473         char *          s1
1474         char *          s2
1475
1476 void
1477 strtod(str)
1478         char *          str
1479     PREINIT:
1480         double num;
1481         char *unparsed;
1482     PPCODE:
1483         SET_NUMERIC_LOCAL();
1484         num = strtod(str, &unparsed);
1485         PUSHs(sv_2mortal(newSVnv(num)));
1486         if (GIMME == G_ARRAY) {
1487             EXTEND(SP, 1);
1488             if (unparsed)
1489                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1490             else
1491                 PUSHs(&PL_sv_undef);
1492         }
1493
1494 void
1495 strtol(str, base = 0)
1496         char *          str
1497         int             base
1498     PREINIT:
1499         long num;
1500         char *unparsed;
1501     PPCODE:
1502         num = strtol(str, &unparsed, base);
1503 #if IVSIZE <= LONGSIZE
1504         if (num < IV_MIN || num > IV_MAX)
1505             PUSHs(sv_2mortal(newSVnv((double)num)));
1506         else
1507 #endif
1508             PUSHs(sv_2mortal(newSViv((IV)num)));
1509         if (GIMME == G_ARRAY) {
1510             EXTEND(SP, 1);
1511             if (unparsed)
1512                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1513             else
1514                 PUSHs(&PL_sv_undef);
1515         }
1516
1517 void
1518 strtoul(str, base = 0)
1519         char *          str
1520         int             base
1521     PREINIT:
1522         unsigned long num;
1523         char *unparsed;
1524     PPCODE:
1525         num = strtoul(str, &unparsed, base);
1526         if (num <= IV_MAX)
1527             PUSHs(sv_2mortal(newSViv((IV)num)));
1528         else
1529             PUSHs(sv_2mortal(newSVnv((double)num)));
1530         if (GIMME == G_ARRAY) {
1531             EXTEND(SP, 1);
1532             if (unparsed)
1533                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1534             else
1535                 PUSHs(&PL_sv_undef);
1536         }
1537
1538 void
1539 strxfrm(src)
1540         SV *            src
1541     CODE:
1542         {
1543           STRLEN srclen;
1544           STRLEN dstlen;
1545           char *p = SvPV(src,srclen);
1546           srclen++;
1547           ST(0) = sv_2mortal(NEWSV(800,srclen));
1548           dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1549           if (dstlen > srclen) {
1550               dstlen++;
1551               SvGROW(ST(0), dstlen);
1552               strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1553               dstlen--;
1554           }
1555           SvCUR(ST(0)) = dstlen;
1556             SvPOK_only(ST(0));
1557         }
1558
1559 SysRet
1560 mkfifo(filename, mode)
1561         char *          filename
1562         Mode_t          mode
1563     CODE:
1564         TAINT_PROPER("mkfifo");
1565         RETVAL = mkfifo(filename, mode);
1566     OUTPUT:
1567         RETVAL
1568
1569 SysRet
1570 tcdrain(fd)
1571         int             fd
1572
1573
1574 SysRet
1575 tcflow(fd, action)
1576         int             fd
1577         int             action
1578
1579
1580 SysRet
1581 tcflush(fd, queue_selector)
1582         int             fd
1583         int             queue_selector
1584
1585 SysRet
1586 tcsendbreak(fd, duration)
1587         int             fd
1588         int             duration
1589
1590 char *
1591 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1592         int             sec
1593         int             min
1594         int             hour
1595         int             mday
1596         int             mon
1597         int             year
1598         int             wday
1599         int             yday
1600         int             isdst
1601     CODE:
1602         {
1603             struct tm mytm;
1604             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1605             mytm.tm_sec = sec;
1606             mytm.tm_min = min;
1607             mytm.tm_hour = hour;
1608             mytm.tm_mday = mday;
1609             mytm.tm_mon = mon;
1610             mytm.tm_year = year;
1611             mytm.tm_wday = wday;
1612             mytm.tm_yday = yday;
1613             mytm.tm_isdst = isdst;
1614             RETVAL = asctime(&mytm);
1615         }
1616     OUTPUT:
1617         RETVAL
1618
1619 long
1620 clock()
1621
1622 char *
1623 ctime(time)
1624         Time_t          &time
1625
1626 void
1627 times()
1628         PPCODE:
1629         struct tms tms;
1630         clock_t realtime;
1631         realtime = times( &tms );
1632         EXTEND(SP,5);
1633         PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1634         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1635         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1636         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1637         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
1638
1639 double
1640 difftime(time1, time2)
1641         Time_t          time1
1642         Time_t          time2
1643
1644 SysRetLong
1645 mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1646         int             sec
1647         int             min
1648         int             hour
1649         int             mday
1650         int             mon
1651         int             year
1652         int             wday
1653         int             yday
1654         int             isdst
1655     CODE:
1656         {
1657             struct tm mytm;
1658             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1659             mytm.tm_sec = sec;
1660             mytm.tm_min = min;
1661             mytm.tm_hour = hour;
1662             mytm.tm_mday = mday;
1663             mytm.tm_mon = mon;
1664             mytm.tm_year = year;
1665             mytm.tm_wday = wday;
1666             mytm.tm_yday = yday;
1667             mytm.tm_isdst = isdst;
1668             RETVAL = mktime(&mytm);
1669         }
1670     OUTPUT:
1671         RETVAL
1672
1673 #XXX: if $xsubpp::WantOptimize is always the default
1674 #     sv_setpv(TARG, ...) could be used rather than
1675 #     ST(0) = sv_2mortal(newSVpv(...))
1676 void
1677 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
1678         char *          fmt
1679         int             sec
1680         int             min
1681         int             hour
1682         int             mday
1683         int             mon
1684         int             year
1685         int             wday
1686         int             yday
1687         int             isdst
1688     CODE:
1689         {
1690             char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
1691             if (buf) {
1692                 ST(0) = sv_2mortal(newSVpv(buf, 0));
1693                 Safefree(buf);
1694             }
1695         }
1696
1697 void
1698 tzset()
1699
1700 void
1701 tzname()
1702     PPCODE:
1703         EXTEND(SP,2);
1704         PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1705         PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
1706
1707 SysRet
1708 access(filename, mode)
1709         char *          filename
1710         Mode_t          mode
1711
1712 char *
1713 ctermid(s = 0)
1714         char *          s = 0;
1715
1716 char *
1717 cuserid(s = 0)
1718         char *          s = 0;
1719
1720 SysRetLong
1721 fpathconf(fd, name)
1722         int             fd
1723         int             name
1724
1725 SysRetLong
1726 pathconf(filename, name)
1727         char *          filename
1728         int             name
1729
1730 SysRet
1731 pause()
1732
1733 SysRet
1734 setgid(gid)
1735         Gid_t           gid
1736
1737 SysRet
1738 setuid(uid)
1739         Uid_t           uid
1740
1741 SysRetLong
1742 sysconf(name)
1743         int             name
1744
1745 char *
1746 ttyname(fd)
1747         int             fd
1748
1749 void
1750 getcwd()
1751     PPCODE:
1752       {
1753         dXSTARG;
1754         getcwd_sv(TARG);
1755         XSprePUSH; PUSHTARG;
1756       }
1757