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