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