No point in going into memory-saving contortions
[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             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(1);
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(1);
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             }
1298
1299             LEAVE;
1300         }
1301 #endif
1302     OUTPUT:
1303         RETVAL
1304
1305 SysRet
1306 sigpending(sigset)
1307         POSIX::SigSet           sigset
1308
1309 SysRet
1310 sigprocmask(how, sigset, oldsigset = 0)
1311         int                     how
1312         POSIX::SigSet           sigset
1313         POSIX::SigSet           oldsigset = NO_INIT
1314 INIT:
1315         if ( items < 3 ) {
1316             oldsigset = 0;
1317         }
1318         else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
1319             IV tmp = SvIV((SV*)SvRV(ST(2)));
1320             oldsigset = INT2PTR(POSIX__SigSet,tmp);
1321         }
1322         else {
1323             New(0, oldsigset, 1, sigset_t);
1324             sigemptyset(oldsigset);
1325             sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
1326         }
1327
1328 SysRet
1329 sigsuspend(signal_mask)
1330         POSIX::SigSet           signal_mask
1331
1332 void
1333 _exit(status)
1334         int             status
1335
1336 SysRet
1337 close(fd)
1338         int             fd
1339
1340 SysRet
1341 dup(fd)
1342         int             fd
1343
1344 SysRet
1345 dup2(fd1, fd2)
1346         int             fd1
1347         int             fd2
1348
1349 SysRetLong
1350 lseek(fd, offset, whence)
1351         int             fd
1352         Off_t           offset
1353         int             whence
1354
1355 SysRet
1356 nice(incr)
1357         int             incr
1358
1359 void
1360 pipe()
1361     PPCODE:
1362         int fds[2];
1363         if (pipe(fds) != -1) {
1364             EXTEND(SP,2);
1365             PUSHs(sv_2mortal(newSViv(fds[0])));
1366             PUSHs(sv_2mortal(newSViv(fds[1])));
1367         }
1368
1369 SysRet
1370 read(fd, buffer, nbytes)
1371     PREINIT:
1372         SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1373     INPUT:
1374         int             fd
1375         size_t          nbytes
1376         char *          buffer = sv_grow( sv_buffer, nbytes+1 );
1377     CLEANUP:
1378         if (RETVAL >= 0) {
1379             SvCUR(sv_buffer) = RETVAL;
1380             SvPOK_only(sv_buffer);
1381             *SvEND(sv_buffer) = '\0';
1382             SvTAINTED_on(sv_buffer);
1383         }
1384
1385 SysRet
1386 setpgid(pid, pgid)
1387         pid_t           pid
1388         pid_t           pgid
1389
1390 pid_t
1391 setsid()
1392
1393 pid_t
1394 tcgetpgrp(fd)
1395         int             fd
1396
1397 SysRet
1398 tcsetpgrp(fd, pgrp_id)
1399         int             fd
1400         pid_t           pgrp_id
1401
1402 void
1403 uname()
1404     PPCODE:
1405 #ifdef HAS_UNAME
1406         struct utsname buf;
1407         if (uname(&buf) >= 0) {
1408             EXTEND(SP, 5);
1409             PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1410             PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1411             PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1412             PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1413             PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
1414         }
1415 #else
1416         uname((char *) 0); /* A stub to call not_here(). */
1417 #endif
1418
1419 SysRet
1420 write(fd, buffer, nbytes)
1421         int             fd
1422         char *          buffer
1423         size_t          nbytes
1424
1425 SV *
1426 tmpnam()
1427     PREINIT:
1428         STRLEN i;
1429         int len;
1430     CODE:
1431         RETVAL = newSVpvn("", 0);
1432         SvGROW(RETVAL, L_tmpnam);
1433         len = strlen(tmpnam(SvPV(RETVAL, i)));
1434         SvCUR_set(RETVAL, len);
1435     OUTPUT:
1436         RETVAL
1437
1438 void
1439 abort()
1440
1441 int
1442 mblen(s, n)
1443         char *          s
1444         size_t          n
1445
1446 size_t
1447 mbstowcs(s, pwcs, n)
1448         wchar_t *       s
1449         char *          pwcs
1450         size_t          n
1451
1452 int
1453 mbtowc(pwc, s, n)
1454         wchar_t *       pwc
1455         char *          s
1456         size_t          n
1457
1458 int
1459 wcstombs(s, pwcs, n)
1460         char *          s
1461         wchar_t *       pwcs
1462         size_t          n
1463
1464 int
1465 wctomb(s, wchar)
1466         char *          s
1467         wchar_t         wchar
1468
1469 int
1470 strcoll(s1, s2)
1471         char *          s1
1472         char *          s2
1473
1474 void
1475 strtod(str)
1476         char *          str
1477     PREINIT:
1478         double num;
1479         char *unparsed;
1480     PPCODE:
1481         SET_NUMERIC_LOCAL();
1482         num = strtod(str, &unparsed);
1483         PUSHs(sv_2mortal(newSVnv(num)));
1484         if (GIMME == G_ARRAY) {
1485             EXTEND(SP, 1);
1486             if (unparsed)
1487                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1488             else
1489                 PUSHs(&PL_sv_undef);
1490         }
1491
1492 void
1493 strtol(str, base = 0)
1494         char *          str
1495         int             base
1496     PREINIT:
1497         long num;
1498         char *unparsed;
1499     PPCODE:
1500         num = strtol(str, &unparsed, base);
1501 #if IVSIZE <= LONGSIZE
1502         if (num < IV_MIN || num > IV_MAX)
1503             PUSHs(sv_2mortal(newSVnv((double)num)));
1504         else
1505 #endif
1506             PUSHs(sv_2mortal(newSViv((IV)num)));
1507         if (GIMME == G_ARRAY) {
1508             EXTEND(SP, 1);
1509             if (unparsed)
1510                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1511             else
1512                 PUSHs(&PL_sv_undef);
1513         }
1514
1515 void
1516 strtoul(str, base = 0)
1517         char *          str
1518         int             base
1519     PREINIT:
1520         unsigned long num;
1521         char *unparsed;
1522     PPCODE:
1523         num = strtoul(str, &unparsed, base);
1524         if (num <= IV_MAX)
1525             PUSHs(sv_2mortal(newSViv((IV)num)));
1526         else
1527             PUSHs(sv_2mortal(newSVnv((double)num)));
1528         if (GIMME == G_ARRAY) {
1529             EXTEND(SP, 1);
1530             if (unparsed)
1531                 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1532             else
1533                 PUSHs(&PL_sv_undef);
1534         }
1535
1536 void
1537 strxfrm(src)
1538         SV *            src
1539     CODE:
1540         {
1541           STRLEN srclen;
1542           STRLEN dstlen;
1543           char *p = SvPV(src,srclen);
1544           srclen++;
1545           ST(0) = sv_2mortal(NEWSV(800,srclen));
1546           dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1547           if (dstlen > srclen) {
1548               dstlen++;
1549               SvGROW(ST(0), dstlen);
1550               strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1551               dstlen--;
1552           }
1553           SvCUR(ST(0)) = dstlen;
1554             SvPOK_only(ST(0));
1555         }
1556
1557 SysRet
1558 mkfifo(filename, mode)
1559         char *          filename
1560         Mode_t          mode
1561     CODE:
1562         TAINT_PROPER("mkfifo");
1563         RETVAL = mkfifo(filename, mode);
1564     OUTPUT:
1565         RETVAL
1566
1567 SysRet
1568 tcdrain(fd)
1569         int             fd
1570
1571
1572 SysRet
1573 tcflow(fd, action)
1574         int             fd
1575         int             action
1576
1577
1578 SysRet
1579 tcflush(fd, queue_selector)
1580         int             fd
1581         int             queue_selector
1582
1583 SysRet
1584 tcsendbreak(fd, duration)
1585         int             fd
1586         int             duration
1587
1588 char *
1589 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1590         int             sec
1591         int             min
1592         int             hour
1593         int             mday
1594         int             mon
1595         int             year
1596         int             wday
1597         int             yday
1598         int             isdst
1599     CODE:
1600         {
1601             struct tm mytm;
1602             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1603             mytm.tm_sec = sec;
1604             mytm.tm_min = min;
1605             mytm.tm_hour = hour;
1606             mytm.tm_mday = mday;
1607             mytm.tm_mon = mon;
1608             mytm.tm_year = year;
1609             mytm.tm_wday = wday;
1610             mytm.tm_yday = yday;
1611             mytm.tm_isdst = isdst;
1612             RETVAL = asctime(&mytm);
1613         }
1614     OUTPUT:
1615         RETVAL
1616
1617 long
1618 clock()
1619
1620 char *
1621 ctime(time)
1622         Time_t          &time
1623
1624 void
1625 times()
1626         PPCODE:
1627         struct tms tms;
1628         clock_t realtime;
1629         realtime = times( &tms );
1630         EXTEND(SP,5);
1631         PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1632         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1633         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1634         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1635         PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
1636
1637 double
1638 difftime(time1, time2)
1639         Time_t          time1
1640         Time_t          time2
1641
1642 SysRetLong
1643 mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1644         int             sec
1645         int             min
1646         int             hour
1647         int             mday
1648         int             mon
1649         int             year
1650         int             wday
1651         int             yday
1652         int             isdst
1653     CODE:
1654         {
1655             struct tm mytm;
1656             init_tm(&mytm);     /* XXX workaround - see init_tm() above */
1657             mytm.tm_sec = sec;
1658             mytm.tm_min = min;
1659             mytm.tm_hour = hour;
1660             mytm.tm_mday = mday;
1661             mytm.tm_mon = mon;
1662             mytm.tm_year = year;
1663             mytm.tm_wday = wday;
1664             mytm.tm_yday = yday;
1665             mytm.tm_isdst = isdst;
1666             RETVAL = mktime(&mytm);
1667         }
1668     OUTPUT:
1669         RETVAL
1670
1671 #XXX: if $xsubpp::WantOptimize is always the default
1672 #     sv_setpv(TARG, ...) could be used rather than
1673 #     ST(0) = sv_2mortal(newSVpv(...))
1674 void
1675 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
1676         char *          fmt
1677         int             sec
1678         int             min
1679         int             hour
1680         int             mday
1681         int             mon
1682         int             year
1683         int             wday
1684         int             yday
1685         int             isdst
1686     CODE:
1687         {
1688             char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
1689             if (buf) {
1690                 ST(0) = sv_2mortal(newSVpv(buf, 0));
1691                 Safefree(buf);
1692             }
1693         }
1694
1695 void
1696 tzset()
1697
1698 void
1699 tzname()
1700     PPCODE:
1701         EXTEND(SP,2);
1702         PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1703         PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
1704
1705 SysRet
1706 access(filename, mode)
1707         char *          filename
1708         Mode_t          mode
1709
1710 char *
1711 ctermid(s = 0)
1712         char *          s = 0;
1713
1714 char *
1715 cuserid(s = 0)
1716         char *          s = 0;
1717
1718 SysRetLong
1719 fpathconf(fd, name)
1720         int             fd
1721         int             name
1722
1723 SysRetLong
1724 pathconf(filename, name)
1725         char *          filename
1726         int             name
1727
1728 SysRet
1729 pause()
1730
1731 SysRet
1732 setgid(gid)
1733         Gid_t           gid
1734
1735 SysRet
1736 setuid(uid)
1737         Uid_t           uid
1738
1739 SysRetLong
1740 sysconf(name)
1741         int             name
1742
1743 char *
1744 ttyname(fd)
1745         int             fd
1746
1747 void
1748 getcwd()
1749     PPCODE:
1750       {
1751         dXSTARG;
1752         sv_getcwd(TARG);
1753         XSprePUSH; PUSHTARG;
1754       }
1755