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