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