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