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