#ifdef WIN32
#define _POSIX_
#endif
+
+#define PERL_NO_GET_CONTEXT
+
#include "EXTERN.h"
#define PERLIO_NOT_STDIO 1
#include "perl.h"
#include "XSUB.h"
+#if defined(PERL_OBJECT) || defined(PERL_CAPI) || defined(PERL_IMPLICIT_SYS)
+# undef signal
+# undef open
+# undef setmode
+# define open PerlLIO_open3
+#endif
#include <ctype.h>
#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
#include <dirent.h>
#endif
#include <setjmp.h>
#include <signal.h>
-#ifdef I_STDARG
#include <stdarg.h>
-#endif
+
#ifdef I_STDDEF
#include <stddef.h>
#endif
+
+#ifdef I_UNISTD
+#include <unistd.h>
+#endif
+
/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
metaconfig for future extension writers. We don't use them in POSIX.
(This is really sneaky :-) --AD
#include <sys/types.h>
#include <time.h>
#ifdef I_UNISTD
-#include <unistd.h> /* see hints/sunos_4_1.sh */
+#include <unistd.h>
+#endif
+#ifdef MACOS_TRADITIONAL
+#undef fdopen
#endif
#include <fcntl.h>
+#ifdef HAS_TZNAME
+# if !defined(WIN32) && !defined(__CYGWIN__)
+extern char *tzname[];
+# endif
+#else
+#if !defined(WIN32) || (defined(__MINGW32__) && !defined(tzname))
+char *tzname[] = { "" , "" };
+#endif
+#endif
+
#if defined(__VMS) && !defined(__POSIX_SOURCE)
# include <libdef.h> /* LIB$_INVARG constant */
# include <lib$routines.h> /* prototype for lib$ediv() */
# define pid_t int /* old versions of DECC miss this in types.h */
# endif
-# undef mkfifo /* #defined in perl.h */
+# undef mkfifo
# define mkfifo(a,b) (not_here("mkfifo"),-1)
# define tzset() not_here("tzset")
/* The non-POSIX CRTL times() has void return type, so we just get the
current time directly */
clock_t vms_times(struct tms *bufptr) {
+ dTHX;
clock_t retval;
/* Get wall time and convert to 10 ms intervals to
* produce the return value that the POSIX standard expects */
}
# define times(t) vms_times(t)
#else
+#if defined (__CYGWIN__)
+# define tzname _tzname
+#endif
#if defined (WIN32)
-# undef mkfifo /* #defined in perl.h */
+# undef mkfifo
# define mkfifo(a,b) not_here("mkfifo")
-# define ttyname(a) not_here("ttyname")
+# define ttyname(a) (char*)not_here("ttyname")
# define sigset_t long
# define pid_t long
# ifdef __BORLANDC__
# ifdef _MSC_VER
# define mode_t short
# endif
+# ifdef __MINGW32__
+# define mode_t short
+# ifndef tzset
+# define tzset() not_here("tzset")
+# endif
+# ifndef _POSIX_OPEN_MAX
+# define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
+# endif
+# endif
# define sigaction(a,b,c) not_here("sigaction")
# define sigpending(a) not_here("sigpending")
# define sigprocmask(a,b,c) not_here("sigprocmask")
# define sigfillset(a) not_here("sigfillset")
# define sigismember(a,b) not_here("sigismember")
#else
-# include <grp.h>
-# include <sys/times.h>
-# ifdef HAS_UNAME
-# include <sys/utsname.h>
+
+# ifndef HAS_MKFIFO
+# if defined(OS2) || defined(MACOS_TRADITIONAL)
+# define mkfifo(a,b) not_here("mkfifo")
+# else /* !( defined OS2 ) */
+# ifndef mkfifo
+# define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
+# endif
+# endif
+# endif /* !HAS_MKFIFO */
+
+# ifdef MACOS_TRADITIONAL
+# define ttyname(a) (char*)not_here("ttyname")
+# define tzset() not_here("tzset")
+# else
+# include <grp.h>
+# include <sys/times.h>
+# ifdef HAS_UNAME
+# include <sys/utsname.h>
+# endif
+# include <sys/wait.h>
# endif
-# include <sys/wait.h>
# ifdef I_UTIME
# include <utime.h>
# endif
#endif
/* Possibly needed prototypes */
-char *cuserid _((char *));
-double strtod _((const char *, char **));
-long strtol _((const char *, char **, int));
-unsigned long strtoul _((const char *, char **, int));
+char *cuserid (char *);
+double strtod (const char *, char **);
+long strtol (const char *, char **, int);
+unsigned long strtoul (const char *, char **, int);
#ifndef HAS_CUSERID
#define cuserid(a) (char *) not_here("cuserid")
#define localeconv() not_here("localeconv")
#endif
-#ifndef WIN32
-#ifdef HAS_TZNAME
-extern char *tzname[];
-#else
-char *tzname[] = { "" , "" };
-#endif
-#endif
-
-/* XXX struct tm on some systems (SunOS4/BSD) contains extra (non POSIX)
- * fields for which we don't have Configure support yet:
- * char *tm_zone; -- abbreviation of timezone name
- * long tm_gmtoff; -- offset from GMT in seconds
- * To workaround core dumps from the uninitialised tm_zone we get the
- * system to give us a reasonable struct to copy. This fix means that
- * strftime uses the tm_zone and tm_gmtoff values returned by
- * localtime(time()). That should give the desired result most of the
- * time. But probably not always!
- *
- * This is a temporary workaround to be removed once Configure
- * support is added and NETaa14816 is considered in full.
- * It does not address tzname aspects of NETaa14816.
- */
-#ifdef HAS_GNULIBC
-# ifndef STRUCT_TM_HASZONE
-# define STRUCT_TM_HAS_ZONE
-# endif
-#endif
-
-#ifdef STRUCT_TM_HASZONE
-static void
-init_tm(ptm) /* see mktime, strftime and asctime */
- struct tm *ptm;
-{
- Time_t now;
- (void)time(&now);
- Copy(localtime(&now), ptm, 1, struct tm);
-}
-
-#else
-# define init_tm(ptm)
-#endif
-
-
#ifdef HAS_LONG_DOUBLE
-# if LONG_DOUBLESIZE > DOUBLESIZE
+# if LONG_DOUBLESIZE > NVSIZE
# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
# endif
#endif
-#ifndef HAS_LONG_DOUBLE
+#ifndef HAS_LONG_DOUBLE
#ifdef LDBL_MAX
#undef LDBL_MAX
#endif
}
static
-#ifdef HAS_LONG_DOUBLE
-long double
-#else
-double
-#endif
+NV
constant(char *name, int arg)
{
errno = 0;
#else
goto not_there;
#endif
+ break;
+ case 'L':
if (strEQ(name, "ELOOP"))
#ifdef ELOOP
return ELOOP;
break;
case 'H':
if (strEQ(name, "HUGE_VAL"))
+#if defined(USE_LONG_DOUBLE) && defined(HUGE_VALL)
+ /* HUGE_VALL is admittedly non-POSIX but if we are using long doubles
+ * we might as well use long doubles. --jhi */
+ return HUGE_VALL;
+#endif
#ifdef HUGE_VAL
return HUGE_VAL;
#else
#else
goto not_there;
#endif
- if (strEQ(name, "L_tmpname"))
-#ifdef L_tmpname
- return L_tmpname;
+ /* L_tmpnam[e] was a typo--retained for compatibility */
+ if (strEQ(name, "L_tmpname") || strEQ(name, "L_tmpnam"))
+#ifdef L_tmpnam
+ return L_tmpnam;
#else
goto not_there;
#endif
#else
goto not_there;
#endif
- if (strEQ(name, "STRERR_FILENO"))
-#ifdef STRERR_FILENO
- return STRERR_FILENO;
+ if (strEQ(name, "STDERR_FILENO"))
+#ifdef STDERR_FILENO
+ return STDERR_FILENO;
#else
goto not_there;
#endif
case '_':
if (strnEQ(name, "_PC_", 4)) {
if (strEQ(name, "_PC_CHOWN_RESTRICTED"))
-#ifdef _PC_CHOWN_RESTRICTED
+#if defined(_PC_CHOWN_RESTRICTED) || HINT_SC_EXIST
return _PC_CHOWN_RESTRICTED;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_LINK_MAX"))
-#ifdef _PC_LINK_MAX
+#if defined(_PC_LINK_MAX) || HINT_SC_EXIST
return _PC_LINK_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_MAX_CANON"))
-#ifdef _PC_MAX_CANON
+#if defined(_PC_MAX_CANON) || HINT_SC_EXIST
return _PC_MAX_CANON;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_MAX_INPUT"))
-#ifdef _PC_MAX_INPUT
+#if defined(_PC_MAX_INPUT) || HINT_SC_EXIST
return _PC_MAX_INPUT;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_NAME_MAX"))
-#ifdef _PC_NAME_MAX
+#if defined(_PC_NAME_MAX) || HINT_SC_EXIST
return _PC_NAME_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_NO_TRUNC"))
-#ifdef _PC_NO_TRUNC
+#if defined(_PC_NO_TRUNC) || HINT_SC_EXIST
return _PC_NO_TRUNC;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_PATH_MAX"))
-#ifdef _PC_PATH_MAX
+#if defined(_PC_PATH_MAX) || HINT_SC_EXIST
return _PC_PATH_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_PIPE_BUF"))
-#ifdef _PC_PIPE_BUF
+#if defined(_PC_PIPE_BUF) || HINT_SC_EXIST
return _PC_PIPE_BUF;
#else
goto not_there;
#endif
if (strEQ(name, "_PC_VDISABLE"))
-#ifdef _PC_VDISABLE
+#if defined(_PC_VDISABLE) || HINT_SC_EXIST
return _PC_VDISABLE;
#else
goto not_there;
}
if (strnEQ(name, "_SC_", 4)) {
if (strEQ(name, "_SC_ARG_MAX"))
-#ifdef _SC_ARG_MAX
+#if defined(_SC_ARG_MAX) || HINT_SC_EXIST
return _SC_ARG_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_CHILD_MAX"))
-#ifdef _SC_CHILD_MAX
+#if defined(_SC_CHILD_MAX) || HINT_SC_EXIST
return _SC_CHILD_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_CLK_TCK"))
-#ifdef _SC_CLK_TCK
+#if defined(_SC_CLK_TCK) || HINT_SC_EXIST
return _SC_CLK_TCK;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_JOB_CONTROL"))
-#ifdef _SC_JOB_CONTROL
+#if defined(_SC_JOB_CONTROL) || HINT_SC_EXIST
return _SC_JOB_CONTROL;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_NGROUPS_MAX"))
-#ifdef _SC_NGROUPS_MAX
+#if defined(_SC_NGROUPS_MAX) || HINT_SC_EXIST
return _SC_NGROUPS_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_OPEN_MAX"))
-#ifdef _SC_OPEN_MAX
+#if defined(_SC_OPEN_MAX) || HINT_SC_EXIST
return _SC_OPEN_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_SAVED_IDS"))
-#ifdef _SC_SAVED_IDS
+#if defined(_SC_SAVED_IDS) || HINT_SC_EXIST
return _SC_SAVED_IDS;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_STREAM_MAX"))
-#ifdef _SC_STREAM_MAX
+#if defined(_SC_STREAM_MAX) || HINT_SC_EXIST
return _SC_STREAM_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_TZNAME_MAX"))
-#ifdef _SC_TZNAME_MAX
+#if defined(_SC_TZNAME_MAX) || HINT_SC_EXIST
return _SC_TZNAME_MAX;
#else
goto not_there;
#endif
if (strEQ(name, "_SC_VERSION"))
-#ifdef _SC_VERSION
+#if defined(_SC_VERSION) || HINT_SC_EXIST
return _SC_VERSION;
#else
goto not_there;
errno = EINVAL;
return 0;
+ if (0) {
+ not_here(""); /* -Wall */
+ }
+
not_there:
errno = ENOENT;
return 0;
}
+static void
+restore_sigmask(sigset_t *ossetp)
+{
+ /* Fortunately, restoring the signal mask can't fail, because
+ * there's nothing we can do about it if it does -- we're not
+ * supposed to return -1 from sigaction unless the disposition
+ * was unaffected.
+ */
+ (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
+}
+
MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
POSIX::SigSet
CODE:
{
int i;
- RETVAL = (sigset_t*)safemalloc(sizeof(sigset_t));
+ New(0, RETVAL, 1, sigset_t);
sigemptyset(RETVAL);
for (i = 1; i < items; i++)
sigaddset(RETVAL, SvIV(ST(i)));
DESTROY(sigset)
POSIX::SigSet sigset
CODE:
- safefree((char *)sigset);
+ Safefree(sigset);
SysRet
sigaddset(sigset, sig)
CODE:
{
#ifdef I_TERMIOS
- RETVAL = (struct termios*)safemalloc(sizeof(struct termios));
+ New(0, RETVAL, 1, struct termios);
#else
not_here("termios");
RETVAL = 0;
POSIX::Termios termios_ref
CODE:
#ifdef I_TERMIOS
- safefree((char *)termios_ref);
+ Safefree(termios_ref);
#else
not_here("termios");
#endif
MODULE = POSIX PACKAGE = POSIX
-double
+NV
constant(name,arg)
char * name
int arg
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isalnum(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isalpha(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!iscntrl(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isdigit(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isgraph(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!islower(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isprint(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!ispunct(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isspace(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isupper(*s))
RETVAL = 0;
unsigned char * charstring
CODE:
unsigned char *s = charstring;
- unsigned char *e = s + na; /* "na" set by typemap side effect */
+ unsigned char *e = s + PL_na; /* "PL_na" set by typemap side effect */
for (RETVAL = 1; RETVAL && s < e; s++)
if (!isxdigit(*s))
RETVAL = 0;
#ifdef HAS_LOCALECONV
struct lconv *lcbuf;
RETVAL = newHV();
- SET_NUMERIC_LOCAL();
- if (lcbuf = localeconv()) {
+ if ((lcbuf = localeconv())) {
/* the strings */
if (lcbuf->decimal_point && *lcbuf->decimal_point)
hv_store(RETVAL, "decimal_point", 13,
if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
hv_store(RETVAL, "thousands_sep", 13,
newSVpv(lcbuf->thousands_sep, 0), 0);
+#ifndef NO_LOCALECONV_GROUPING
if (lcbuf->grouping && *lcbuf->grouping)
hv_store(RETVAL, "grouping", 8,
newSVpv(lcbuf->grouping, 0), 0);
+#endif
if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
hv_store(RETVAL, "int_curr_symbol", 15,
newSVpv(lcbuf->int_curr_symbol, 0), 0);
hv_store(RETVAL, "mon_thousands_sep", 17,
newSVpv(lcbuf->mon_thousands_sep, 0), 0);
#endif
+#ifndef NO_LOCALECONV_MON_GROUPING
if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
hv_store(RETVAL, "mon_grouping", 12,
newSVpv(lcbuf->mon_grouping, 0), 0);
+#endif
if (lcbuf->positive_sign && *lcbuf->positive_sign)
hv_store(RETVAL, "positive_sign", 13,
newSVpv(lcbuf->positive_sign, 0), 0);
else
#endif
newctype = RETVAL;
- perl_new_ctype(newctype);
+ new_ctype(newctype);
}
#endif /* USE_LOCALE_CTYPE */
#ifdef USE_LOCALE_COLLATE
else
#endif
newcoll = RETVAL;
- perl_new_collate(newcoll);
+ new_collate(newcoll);
}
#endif /* USE_LOCALE_COLLATE */
#ifdef USE_LOCALE_NUMERIC
else
#endif
newnum = RETVAL;
- perl_new_numeric(newnum);
+ new_numeric(newnum);
}
#endif /* USE_LOCALE_NUMERIC */
}
RETVAL
-double
+NV
acos(x)
- double x
+ NV x
-double
+NV
asin(x)
- double x
+ NV x
-double
+NV
atan(x)
- double x
+ NV x
-double
+NV
ceil(x)
- double x
+ NV x
-double
+NV
cosh(x)
- double x
+ NV x
-double
+NV
floor(x)
- double x
+ NV x
-double
+NV
fmod(x,y)
- double x
- double y
+ NV x
+ NV y
void
frexp(x)
- double x
+ NV x
PPCODE:
int expvar;
/* (We already know stack is long enough.) */
PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
PUSHs(sv_2mortal(newSViv(expvar)));
-double
+NV
ldexp(x,exp)
- double x
+ NV x
int exp
-double
+NV
log10(x)
- double x
+ NV x
void
modf(x)
- double x
+ NV x
PPCODE:
- double intvar;
+ NV intvar;
/* (We already know stack is long enough.) */
- PUSHs(sv_2mortal(newSVnv(modf(x,&intvar))));
+ PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
PUSHs(sv_2mortal(newSVnv(intvar)));
-double
+NV
sinh(x)
- double x
+ NV x
-double
+NV
tan(x)
- double x
+ NV x
-double
+NV
tanh(x)
- double x
+ NV x
SysRet
-sigaction(sig, action, oldaction = 0)
+sigaction(sig, optaction, oldaction = 0)
int sig
- POSIX::SigAction action
+ SV * optaction
POSIX::SigAction oldaction
CODE:
#ifdef WIN32
# This code is really grody because we're trying to make the signal
# interface look beautiful, which is hard.
- if (!siggv)
- gv_fetchpv("SIG", TRUE, SVt_PVHV);
-
{
+ POSIX__SigAction action;
+ GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
struct sigaction act;
struct sigaction oact;
+ sigset_t sset;
+ sigset_t osset;
POSIX__SigSet sigset;
SV** svp;
SV** sigsvp = hv_fetch(GvHVn(siggv),
- sig_name[sig],
- strlen(sig_name[sig]),
+ PL_sig_name[sig],
+ strlen(PL_sig_name[sig]),
TRUE);
- /* Remember old handler name if desired. */
+ /* Check optaction and set action */
+ if(SvTRUE(optaction)) {
+ if(sv_isa(optaction, "POSIX::SigAction"))
+ action = (HV*)SvRV(optaction);
+ else
+ croak("action is not of type POSIX::SigAction");
+ }
+ else {
+ action=0;
+ }
+
+ /* sigaction() is supposed to look atomic. In particular, any
+ * signal handler invoked during a sigaction() call should
+ * see either the old or the new disposition, and not something
+ * in between. We use sigprocmask() to make it so.
+ */
+ sigfillset(&sset);
+ RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
+ if(RETVAL == -1)
+ XSRETURN(1);
+ ENTER;
+ /* Restore signal mask no matter how we exit this block. */
+ SAVEDESTRUCTOR(restore_sigmask, &osset);
+
+ RETVAL=-1; /* In case both oldaction and action are 0. */
+
+ /* Remember old disposition if desired. */
if (oldaction) {
- char *hand = SvPVx(*sigsvp, na);
svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
- sv_setpv(*svp, *hand ? hand : "DEFAULT");
+ if(!svp)
+ croak("Can't supply an oldaction without a HANDLER");
+ if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
+ sv_setsv(*svp, *sigsvp);
+ }
+ else {
+ sv_setpv(*svp, "DEFAULT");
+ }
+ RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
+ if(RETVAL == -1)
+ XSRETURN(1);
+ /* Get back the mask. */
+ svp = hv_fetch(oldaction, "MASK", 4, TRUE);
+ if (sv_isa(*svp, "POSIX::SigSet")) {
+ IV tmp = SvIV((SV*)SvRV(*svp));
+ sigset = INT2PTR(sigset_t*, tmp);
+ }
+ else {
+ New(0, sigset, 1, sigset_t);
+ sv_setptrobj(*svp, sigset, "POSIX::SigSet");
+ }
+ *sigset = oact.sa_mask;
+
+ /* Get back the flags. */
+ svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
+ sv_setiv(*svp, oact.sa_flags);
}
if (action) {
svp = hv_fetch(action, "HANDLER", 7, FALSE);
if (!svp)
croak("Can't supply an action without a HANDLER");
- sv_setpv(*sigsvp, SvPV(*svp, na));
+ sv_setsv(*sigsvp, *svp);
mg_set(*sigsvp); /* handles DEFAULT and IGNORE */
- act.sa_handler = sighandler;
+ if(SvPOK(*svp)) {
+ char *s=SvPVX(*svp);
+ if(strEQ(s,"IGNORE")) {
+ act.sa_handler = SIG_IGN;
+ }
+ else if(strEQ(s,"DEFAULT")) {
+ act.sa_handler = SIG_DFL;
+ }
+ else {
+ act.sa_handler = PL_sighandlerp;
+ }
+ }
+ else {
+ act.sa_handler = PL_sighandlerp;
+ }
/* Set up any desired mask. */
svp = hv_fetch(action, "MASK", 4, FALSE);
if (svp && sv_isa(*svp, "POSIX::SigSet")) {
- unsigned long tmp;
- tmp = (unsigned long)SvNV((SV*)SvRV(*svp));
- sigset = (sigset_t*) tmp;
+ IV tmp = SvIV((SV*)SvRV(*svp));
+ sigset = INT2PTR(sigset_t*, tmp);
act.sa_mask = *sigset;
}
else
/* Set up any desired flags. */
svp = hv_fetch(action, "FLAGS", 5, FALSE);
act.sa_flags = svp ? SvIV(*svp) : 0;
- }
- /* Now work around sigaction oddities */
- if (action && oldaction)
- RETVAL = sigaction(sig, & act, & oact);
- else if (action)
+ /* Don't worry about cleaning up *sigsvp if this fails,
+ * because that means we tried to disposition a
+ * nonblockable signal, in which case *sigsvp is
+ * essentially meaningless anyway.
+ */
RETVAL = sigaction(sig, & act, (struct sigaction *)0);
- else if (oldaction)
- RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
- else
- RETVAL = -1;
-
- if (oldaction) {
- /* Get back the mask. */
- svp = hv_fetch(oldaction, "MASK", 4, TRUE);
- if (sv_isa(*svp, "POSIX::SigSet")) {
- unsigned long tmp;
- tmp = (unsigned long)SvNV((SV*)SvRV(*svp));
- sigset = (sigset_t*) tmp;
- }
- else {
- sigset = (sigset_t*)safemalloc(sizeof(sigset_t));
- sv_setptrobj(*svp, sigset, "POSIX::SigSet");
- }
- *sigset = oact.sa_mask;
-
- /* Get back the flags. */
- svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
- sv_setiv(*svp, oact.sa_flags);
}
+
+ LEAVE;
}
#endif
OUTPUT:
sigprocmask(how, sigset, oldsigset = 0)
int how
POSIX::SigSet sigset
- POSIX::SigSet oldsigset
+ POSIX::SigSet oldsigset = NO_INIT
+INIT:
+ if ( items < 3 ) {
+ oldsigset = 0;
+ }
+ else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
+ IV tmp = SvIV((SV*)SvRV(ST(2)));
+ oldsigset = INT2PTR(POSIX__SigSet,tmp);
+ }
+ else {
+ New(0, oldsigset, 1, sigset_t);
+ sigemptyset(oldsigset);
+ sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
+ }
SysRet
sigsuspend(signal_mask)
nice(incr)
int incr
-int
+void
pipe()
PPCODE:
int fds[2];
int fd
pid_t pgrp_id
-int
+void
uname()
PPCODE:
#ifdef HAS_UNAME
char * buffer
size_t nbytes
-char *
-tmpnam(s = 0)
- char * s = 0;
+SV *
+tmpnam()
+ PREINIT:
+ STRLEN i;
+ int len;
+ CODE:
+ RETVAL = newSVpvn("", 0);
+ SvGROW(RETVAL, L_tmpnam);
+ len = strlen(tmpnam(SvPV(RETVAL, i)));
+ SvCUR_set(RETVAL, len);
+ OUTPUT:
+ RETVAL
void
abort()
if (unparsed)
PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
else
- PUSHs(&sv_undef);
+ PUSHs(&PL_sv_undef);
}
void
char *unparsed;
PPCODE:
num = strtol(str, &unparsed, base);
- if (num >= IV_MIN && num <= IV_MAX)
- PUSHs(sv_2mortal(newSViv((IV)num)));
- else
+#if IVSIZE <= LONGSIZE
+ if (num < IV_MIN || num > IV_MAX)
PUSHs(sv_2mortal(newSVnv((double)num)));
+ else
+#endif
+ PUSHs(sv_2mortal(newSViv((IV)num)));
if (GIMME == G_ARRAY) {
EXTEND(SP, 1);
if (unparsed)
PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
else
- PUSHs(&sv_undef);
+ PUSHs(&PL_sv_undef);
}
void
if (unparsed)
PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
else
- PUSHs(&sv_undef);
+ PUSHs(&PL_sv_undef);
}
-SV *
+void
strxfrm(src)
SV * src
CODE:
OUTPUT:
RETVAL
-char *
-strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+#XXX: if $xsubpp::WantOptimize is always the default
+# sv_setpv(TARG, ...) could be used rather than
+# ST(0) = sv_2mortal(newSVpv(...))
+void
+strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
char * fmt
int sec
int min
int isdst
CODE:
{
- char tmpbuf[128];
- struct tm mytm;
- int len;
- init_tm(&mytm); /* XXX workaround - see init_tm() above */
- mytm.tm_sec = sec;
- mytm.tm_min = min;
- mytm.tm_hour = hour;
- mytm.tm_mday = mday;
- mytm.tm_mon = mon;
- mytm.tm_year = year;
- mytm.tm_wday = wday;
- mytm.tm_yday = yday;
- mytm.tm_isdst = isdst;
- len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
- ST(0) = sv_2mortal(newSVpv(tmpbuf, len));
+ char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
+ if (buf) {
+ ST(0) = sv_2mortal(newSVpv(buf, 0));
+ Safefree(buf);
+ }
}
void
tzname()
PPCODE:
EXTEND(SP,2);
- PUSHs(sv_2mortal(newSVpv(tzname[0],strlen(tzname[0]))));
- PUSHs(sv_2mortal(newSVpv(tzname[1],strlen(tzname[1]))));
+ PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
+ PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
SysRet
access(filename, mode)
SysRet
pause()
+SysRet
+setgid(gid)
+ Gid_t gid
+
+SysRet
+setuid(uid)
+ Uid_t uid
+
SysRetLong
sysconf(name)
int name
char *
ttyname(fd)
int fd
+
+#XXX: use sv_getcwd()
+void
+getcwd()
+ PPCODE:
+#ifdef HAS_GETCWD
+ char * buf;
+ int buflen = 128;
+
+ New(0, buf, buflen, char);
+ /* Many getcwd()s know how to automatically allocate memory
+ * for the directory if the buffer argument is NULL but...
+ * (1) we cannot assume all getcwd()s do that
+ * (2) this may interfere with Perl's malloc
+ * So let's not. --jhi */
+ while ((getcwd(buf, buflen) == NULL) && errno == ERANGE) {
+ buflen += 128;
+ if (buflen > MAXPATHLEN) {
+ Safefree(buf);
+ buf = NULL;
+ break;
+ }
+ Renew(buf, buflen, char);
+ }
+ if (buf) {
+ PUSHs(sv_2mortal(newSVpv(buf, 0)));
+ Safefree(buf);
+ }
+ else
+ PUSHs(&PL_sv_undef);
+#else
+ require_pv("Cwd.pm");
+ /* Module require may have grown the stack */
+ SPAGAIN;
+ PUSHMARK(sp);
+ PUTBACK;
+ XSRETURN(call_pv("Cwd::cwd", GIMME_V));
+#endif