X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2FPOSIX%2FPOSIX.xs;h=f079b7b257a46ac4b50f08b59bdda3987f3df75d;hb=8fa7f3676ed75809365905727fbae97dc8767f29;hp=c3bacb4e2967a8fdf8920460fe282540aab2d1b5;hpb=35ff78560a01016ce2a3dffe29f18ce851bc0b90;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index c3bacb4..f079b7b 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -1,16 +1,18 @@ #ifdef WIN32 #define _POSIX_ #endif + +#define PERL_NO_GET_CONTEXT + #include "EXTERN.h" #define PERLIO_NOT_STDIO 1 #include "perl.h" #include "XSUB.h" -#ifdef PERL_OBJECT /* XXX _very_ temporary hacks */ +#if defined(PERL_OBJECT) || defined(PERL_CAPI) || defined(PERL_IMPLICIT_SYS) # undef signal # undef open +# undef setmode # define open PerlLIO_open3 -# undef TAINT_PROPER -# define TAINT_PROPER(a) #endif #include #ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */ @@ -30,12 +32,16 @@ #endif #include #include -#ifdef I_STDARG #include -#endif + #ifdef I_STDDEF #include #endif + +#ifdef I_UNISTD +#include +#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 @@ -51,10 +57,23 @@ #include #include #ifdef I_UNISTD -#include /* see hints/sunos_4_1.sh */ +#include +#endif +#ifdef MACOS_TRADITIONAL +#undef fdopen #endif #include +#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 /* LIB$_INVARG constant */ # include /* prototype for lib$ediv() */ @@ -63,7 +82,7 @@ # 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") @@ -79,6 +98,7 @@ /* 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 */ @@ -103,8 +123,11 @@ } # 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) (char*)not_here("ttyname") # define sigset_t long @@ -115,6 +138,15 @@ # 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") @@ -125,12 +157,28 @@ # define sigfillset(a) not_here("sigfillset") # define sigismember(a,b) not_here("sigismember") #else -# include -# include -# ifdef HAS_UNAME -# include + +# 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 +# include +# ifdef HAS_UNAME +# include +# endif +# include # endif -# include # ifdef I_UTIME # include # endif @@ -162,10 +210,10 @@ typedef struct termios* POSIX__Termios; #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") @@ -262,56 +310,13 @@ unsigned long strtoul _((const char *, char **, int)); #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 @@ -331,11 +336,7 @@ not_here(char *s) } static -#ifdef HAS_LONG_DOUBLE -long double -#else -double -#endif +NV constant(char *name, int arg) { errno = 0; @@ -803,6 +804,8 @@ constant(char *name, int arg) #else goto not_there; #endif + break; + case 'L': if (strEQ(name, "ELOOP")) #ifdef ELOOP return ELOOP; @@ -1292,6 +1295,11 @@ constant(char *name, int arg) 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 @@ -1500,9 +1508,10 @@ constant(char *name, int arg) #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 @@ -2065,9 +2074,9 @@ constant(char *name, int arg) #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 @@ -2540,6 +2549,17 @@ not_there: 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 @@ -2548,7 +2568,7 @@ new(packname = "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))); @@ -2560,7 +2580,7 @@ void DESTROY(sigset) POSIX::SigSet sigset CODE: - safefree((char *)sigset); + Safefree(sigset); SysRet sigaddset(sigset, sig) @@ -2594,7 +2614,7 @@ new(packname = "POSIX::Termios", ...) CODE: { #ifdef I_TERMIOS - RETVAL = (struct termios*)safemalloc(sizeof(struct termios)); + New(0, RETVAL, 1, struct termios); #else not_here("termios"); RETVAL = 0; @@ -2608,7 +2628,7 @@ DESTROY(termios_ref) POSIX::Termios termios_ref CODE: #ifdef I_TERMIOS - safefree((char *)termios_ref); + Safefree(termios_ref); #else not_here("termios"); #endif @@ -2779,7 +2799,7 @@ setcc(termios_ref, ccix, cc) MODULE = POSIX PACKAGE = POSIX -double +NV constant(name,arg) char * name int arg @@ -2789,7 +2809,7 @@ isalnum(charstring) 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; @@ -2801,7 +2821,7 @@ isalpha(charstring) 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; @@ -2813,7 +2833,7 @@ iscntrl(charstring) 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; @@ -2825,7 +2845,7 @@ isdigit(charstring) 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; @@ -2837,7 +2857,7 @@ isgraph(charstring) 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; @@ -2849,7 +2869,7 @@ islower(charstring) 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; @@ -2861,7 +2881,7 @@ isprint(charstring) 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; @@ -2873,7 +2893,7 @@ ispunct(charstring) 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; @@ -2885,7 +2905,7 @@ isspace(charstring) 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; @@ -2897,7 +2917,7 @@ isupper(charstring) 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; @@ -2909,7 +2929,7 @@ isxdigit(charstring) 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; @@ -2935,8 +2955,7 @@ localeconv() #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, @@ -2944,9 +2963,11 @@ localeconv() 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); @@ -2961,9 +2982,11 @@ localeconv() 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); @@ -3023,7 +3046,7 @@ setlocale(category, locale = 0) else #endif newctype = RETVAL; - perl_new_ctype(newctype); + new_ctype(newctype); } #endif /* USE_LOCALE_CTYPE */ #ifdef USE_LOCALE_COLLATE @@ -3040,7 +3063,7 @@ setlocale(category, locale = 0) else #endif newcoll = RETVAL; - perl_new_collate(newcoll); + new_collate(newcoll); } #endif /* USE_LOCALE_COLLATE */ #ifdef USE_LOCALE_NUMERIC @@ -3057,7 +3080,7 @@ setlocale(category, locale = 0) else #endif newnum = RETVAL; - perl_new_numeric(newnum); + new_numeric(newnum); } #endif /* USE_LOCALE_NUMERIC */ } @@ -3065,78 +3088,78 @@ setlocale(category, locale = 0) 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 @@ -3145,24 +3168,75 @@ sigaction(sig, action, oldaction = 0) # 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) { @@ -3171,16 +3245,29 @@ sigaction(sig, action, oldaction = 0) 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 @@ -3189,36 +3276,16 @@ sigaction(sig, action, oldaction = 0) /* 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: @@ -3232,7 +3299,20 @@ SysRet 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) @@ -3265,7 +3345,7 @@ SysRet nice(incr) int incr -int +void pipe() PPCODE: int fds[2]; @@ -3308,7 +3388,7 @@ tcsetpgrp(fd, pgrp_id) int fd pid_t pgrp_id -int +void uname() PPCODE: #ifdef HAS_UNAME @@ -3331,9 +3411,18 @@ write(fd, buffer, nbytes) 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() @@ -3386,7 +3475,7 @@ strtod(str) if (unparsed) PUSHs(sv_2mortal(newSViv(strlen(unparsed)))); else - PUSHs(&sv_undef); + PUSHs(&PL_sv_undef); } void @@ -3398,16 +3487,18 @@ strtol(str, base = 0) 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 @@ -3428,10 +3519,10 @@ strtoul(str, base = 0) if (unparsed) PUSHs(sv_2mortal(newSViv(strlen(unparsed)))); else - PUSHs(&sv_undef); + PUSHs(&PL_sv_undef); } -SV * +void strxfrm(src) SV * src CODE: @@ -3566,8 +3657,11 @@ mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0) 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 @@ -3580,21 +3674,11 @@ strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0) 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 @@ -3604,8 +3688,8 @@ 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) @@ -3633,6 +3717,14 @@ pathconf(filename, name) SysRet pause() +SysRet +setgid(gid) + Gid_t gid + +SysRet +setuid(uid) + Uid_t uid + SysRetLong sysconf(name) int name @@ -3640,3 +3732,40 @@ sysconf(name) char * ttyname(fd) int fd + +char * +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