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