X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2FPOSIX%2FPOSIX.xs;h=41c6ba35de6b40fd80ffbdf443a9dd4859fe7445;hb=fa4efe8e185f853b396be995a5d8d97c8d245e03;hp=2a1338200da39637824193bfc3abb5e32aae75e4;hpb=8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 2a13382..41c6ba3 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -1,16 +1,25 @@ +#ifdef WIN32 +#define _POSIX_ +#endif #include "EXTERN.h" +#define PERLIO_NOT_STDIO 1 #include "perl.h" #include "XSUB.h" +#ifdef PERL_OBJECT /* XXX _very_ temporary hacks */ +# undef signal +# undef open +# 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? */ #include #endif #include -#include #ifdef I_FLOAT #include #endif -#include #ifdef I_LIMITS #include #endif @@ -21,9 +30,8 @@ #endif #include #include -#ifdef I_STDARG #include -#endif + #ifdef I_STDDEF #include #endif @@ -34,26 +42,109 @@ #if defined(I_TERMIOS) #include #endif -#include #ifdef I_STDLIB #include #endif #include #include -#include #include -#ifdef HAS_UNAME -#include -#endif -#include #include +#ifdef I_UNISTD #include -#ifdef I_UTIME -#include #endif +#include + +#if defined(__VMS) && !defined(__POSIX_SOURCE) +# include /* LIB$_INVARG constant */ +# include /* prototype for lib$ediv() */ +# include /* prototype for sys$gettim() */ +# if DECC_VERSION < 50000000 +# define pid_t int /* old versions of DECC miss this in types.h */ +# endif + +# undef mkfifo /* #defined in perl.h */ +# define mkfifo(a,b) (not_here("mkfifo"),-1) +# define tzset() not_here("tzset") + +#if ((__VMS_VER >= 70000000) && (__DECC_VER >= 50200000)) || (__CRTL_VER >= 70000000) +# define HAS_TZNAME /* shows up in VMS 7.0 or Dec C 5.6 */ +# include +# endif /* __VMS_VER >= 70000000 or Dec C 5.6 */ + + /* The POSIX notion of ttyname() is better served by getname() under VMS */ + static char ttnambuf[64]; +# define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL) + + /* The non-POSIX CRTL times() has void return type, so we just get the + current time directly */ + clock_t vms_times(struct tms *bufptr) { + clock_t retval; + /* Get wall time and convert to 10 ms intervals to + * produce the return value that the POSIX standard expects */ +# if defined(__DECC) && defined (__ALPHA) +# include + uint64 vmstime; + _ckvmssts(sys$gettim(&vmstime)); + vmstime /= 100000; + retval = vmstime & 0x7fffffff; +# else + /* (Older hw or ccs don't have an atomic 64-bit type, so we + * juggle 32-bit ints (and a float) to produce a time_t result + * with minimal loss of information.) */ + long int vmstime[2],remainder,divisor = 100000; + _ckvmssts(sys$gettim((unsigned long int *)vmstime)); + vmstime[1] &= 0x7fff; /* prevent overflow in EDIV */ + _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder)); +# endif + /* Fill in the struct tms using the CRTL routine . . .*/ + times((tbuffer_t *)bufptr); + return (clock_t) retval; + } +# define times(t) vms_times(t) +#else +#if defined (WIN32) +# undef mkfifo /* #defined in perl.h */ +# define mkfifo(a,b) not_here("mkfifo") +# define ttyname(a) (char*)not_here("ttyname") +# define sigset_t long +# define pid_t long +# ifdef __BORLANDC__ +# define tzname _tzname +# endif +# 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 sigsuspend(a) not_here("sigsuspend") +# define sigemptyset(a) not_here("sigemptyset") +# define sigaddset(a,b) not_here("sigaddset") +# define sigdelset(a,b) not_here("sigdelset") +# define sigfillset(a) not_here("sigfillset") +# define sigismember(a,b) not_here("sigismember") +#else +# include +# include +# ifdef HAS_UNAME +# include +# endif +# include +# ifdef I_UTIME +# include +# endif +#endif /* WIN32 */ +#endif /* __VMS */ -typedef FILE * InputStream; -typedef FILE * OutputStream; typedef int SysRet; typedef long SysRetLong; typedef sigset_t* POSIX__SigSet; @@ -80,6 +171,9 @@ typedef struct termios* POSIX__Termios; /* Possibly needed prototypes */ 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") @@ -116,6 +210,15 @@ char *cuserid _((char *)); #ifndef HAS_STRCOLL #define strcoll(s1,s2) not_here("strcoll") #endif +#ifndef HAS_STRTOD +#define strtod(s1,s2) not_here("strtod") +#endif +#ifndef HAS_STRTOL +#define strtol(s1,s2,b) not_here("strtol") +#endif +#ifndef HAS_STRTOUL +#define strtoul(s1,s2,b) not_here("strtoul") +#endif #ifndef HAS_STRXFRM #define strxfrm(s1,s2,n) not_here("strxfrm") #endif @@ -135,13 +238,6 @@ char *cuserid _((char *)); #define waitpid(a,b,c) not_here("waitpid") #endif -#ifndef HAS_FGETPOS -#define fgetpos(a,b) not_here("fgetpos") -#endif -#ifndef HAS_FSETPOS -#define fsetpos(a,b) not_here("fsetpos") -#endif - #ifndef HAS_MBLEN #ifndef mblen #define mblen(a,b) not_here("mblen") @@ -175,12 +271,57 @@ char *cuserid _((char *)); #endif #ifdef HAS_TZNAME +# ifndef WIN32 extern char *tzname[]; +# endif #else +#if !defined(WIN32) || (defined(__MINGW32__) && !defined(tzname)) 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 +# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */ +# endif +#endif -#ifndef HAS_LONG_DOUBLE /* XXX What to do about long doubles? */ +#ifndef HAS_LONG_DOUBLE #ifdef LDBL_MAX #undef LDBL_MAX #endif @@ -193,17 +334,19 @@ char *tzname[] = { "" , "" }; #endif static int -not_here(s) -char *s; +not_here(char *s) { croak("POSIX::%s not implemented on this architecture", s); return -1; } -static double -constant(name, arg) -char *name; -int arg; +static +#ifdef HAS_LONG_DOUBLE +long double +#else +double +#endif +constant(char *name, int arg) { errno = 0; switch (*name) { @@ -476,12 +619,36 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EADDRINUSE")) +#ifdef EADDRINUSE + return EADDRINUSE; +#else + goto not_there; +#endif + if (strEQ(name, "EADDRNOTAVAIL")) +#ifdef EADDRNOTAVAIL + return EADDRNOTAVAIL; +#else + goto not_there; +#endif + if (strEQ(name, "EAFNOSUPPORT")) +#ifdef EAFNOSUPPORT + return EAFNOSUPPORT; +#else + goto not_there; +#endif if (strEQ(name, "EAGAIN")) #ifdef EAGAIN return EAGAIN; #else goto not_there; #endif + if (strEQ(name, "EALREADY")) +#ifdef EALREADY + return EALREADY; +#else + goto not_there; +#endif break; case 'B': if (strEQ(name, "EBADF")) @@ -528,6 +695,24 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "ECONNABORTED")) +#ifdef ECONNABORTED + return ECONNABORTED; +#else + goto not_there; +#endif + if (strEQ(name, "ECONNREFUSED")) +#ifdef ECONNREFUSED + return ECONNREFUSED; +#else + goto not_there; +#endif + if (strEQ(name, "ECONNRESET")) +#ifdef ECONNRESET + return ECONNRESET; +#else + goto not_there; +#endif break; case 'D': if (strEQ(name, "EDEADLK")) @@ -536,12 +721,24 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EDESTADDRREQ")) +#ifdef EDESTADDRREQ + return EDESTADDRREQ; +#else + goto not_there; +#endif if (strEQ(name, "EDOM")) #ifdef EDOM return EDOM; #else goto not_there; #endif + if (strEQ(name, "EDQUOT")) +#ifdef EDQUOT + return EDQUOT; +#else + goto not_there; +#endif break; case 'E': if (strEQ(name, "EEXIST")) @@ -565,7 +762,27 @@ int arg; goto not_there; #endif break; + case 'H': + if (strEQ(name, "EHOSTDOWN")) +#ifdef EHOSTDOWN + return EHOSTDOWN; +#else + goto not_there; +#endif + if (strEQ(name, "EHOSTUNREACH")) +#ifdef EHOSTUNREACH + return EHOSTUNREACH; +#else + goto not_there; +#endif + break; case 'I': + if (strEQ(name, "EINPROGRESS")) +#ifdef EINPROGRESS + return EINPROGRESS; +#else + goto not_there; +#endif if (strEQ(name, "EINTR")) #ifdef EINTR return EINTR; @@ -584,12 +801,24 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EISCONN")) +#ifdef EISCONN + return EISCONN; +#else + goto not_there; +#endif if (strEQ(name, "EISDIR")) #ifdef EISDIR return EISDIR; #else goto not_there; #endif + if (strEQ(name, "ELOOP")) +#ifdef ELOOP + return ELOOP; +#else + goto not_there; +#endif break; case 'M': if (strEQ(name, "EMFILE")) @@ -604,29 +833,71 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EMSGSIZE")) +#ifdef EMSGSIZE + return EMSGSIZE; +#else + goto not_there; +#endif break; case 'N': + if (strEQ(name, "ENETDOWN")) +#ifdef ENETDOWN + return ENETDOWN; +#else + goto not_there; +#endif + if (strEQ(name, "ENETRESET")) +#ifdef ENETRESET + return ENETRESET; +#else + goto not_there; +#endif + if (strEQ(name, "ENETUNREACH")) +#ifdef ENETUNREACH + return ENETUNREACH; +#else + goto not_there; +#endif + if (strEQ(name, "ENOBUFS")) +#ifdef ENOBUFS + return ENOBUFS; +#else + goto not_there; +#endif + if (strEQ(name, "ENOEXEC")) +#ifdef ENOEXEC + return ENOEXEC; +#else + goto not_there; +#endif if (strEQ(name, "ENOMEM")) #ifdef ENOMEM return ENOMEM; #else goto not_there; #endif + if (strEQ(name, "ENOPROTOOPT")) +#ifdef ENOPROTOOPT + return ENOPROTOOPT; +#else + goto not_there; +#endif if (strEQ(name, "ENOSPC")) #ifdef ENOSPC return ENOSPC; #else goto not_there; #endif - if (strEQ(name, "ENOEXEC")) -#ifdef ENOEXEC - return ENOEXEC; + if (strEQ(name, "ENOTBLK")) +#ifdef ENOTBLK + return ENOTBLK; #else goto not_there; #endif - if (strEQ(name, "ENOTTY")) -#ifdef ENOTTY - return ENOTTY; + if (strEQ(name, "ENOTCONN")) +#ifdef ENOTCONN + return ENOTCONN; #else goto not_there; #endif @@ -642,6 +913,18 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "ENOTSOCK")) +#ifdef ENOTSOCK + return ENOTSOCK; +#else + goto not_there; +#endif + if (strEQ(name, "ENOTTY")) +#ifdef ENOTTY + return ENOTTY; +#else + goto not_there; +#endif if (strEQ(name, "ENFILE")) #ifdef ENFILE return ENFILE; @@ -692,6 +975,12 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EOPNOTSUPP")) +#ifdef EOPNOTSUPP + return EOPNOTSUPP; +#else + goto not_there; +#endif break; case 'P': if (strEQ(name, "EPERM")) @@ -700,12 +989,36 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EPFNOSUPPORT")) +#ifdef EPFNOSUPPORT + return EPFNOSUPPORT; +#else + goto not_there; +#endif if (strEQ(name, "EPIPE")) #ifdef EPIPE return EPIPE; #else goto not_there; #endif + if (strEQ(name, "EPROCLIM")) +#ifdef EPROCLIM + return EPROCLIM; +#else + goto not_there; +#endif + if (strEQ(name, "EPROTONOSUPPORT")) +#ifdef EPROTONOSUPPORT + return EPROTONOSUPPORT; +#else + goto not_there; +#endif + if (strEQ(name, "EPROTOTYPE")) +#ifdef EPROTOTYPE + return EPROTOTYPE; +#else + goto not_there; +#endif break; case 'R': if (strEQ(name, "ERANGE")) @@ -714,6 +1027,18 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "EREMOTE")) +#ifdef EREMOTE + return EREMOTE; +#else + goto not_there; +#endif + if (strEQ(name, "ERESTART")) +#ifdef ERESTART + return ERESTART; +#else + goto not_there; +#endif if (strEQ(name, "EROFS")) #ifdef EROFS return EROFS; @@ -722,6 +1047,18 @@ int arg; #endif break; case 'S': + if (strEQ(name, "ESHUTDOWN")) +#ifdef ESHUTDOWN + return ESHUTDOWN; +#else + goto not_there; +#endif + if (strEQ(name, "ESOCKTNOSUPPORT")) +#ifdef ESOCKTNOSUPPORT + return ESOCKTNOSUPPORT; +#else + goto not_there; +#endif if (strEQ(name, "ESPIPE")) #ifdef ESPIPE return ESPIPE; @@ -734,7 +1071,49 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "ESTALE")) +#ifdef ESTALE + return ESTALE; +#else + goto not_there; +#endif break; + case 'T': + if (strEQ(name, "ETIMEDOUT")) +#ifdef ETIMEDOUT + return ETIMEDOUT; +#else + goto not_there; +#endif + if (strEQ(name, "ETOOMANYREFS")) +#ifdef ETOOMANYREFS + return ETOOMANYREFS; +#else + goto not_there; +#endif + if (strEQ(name, "ETXTBSY")) +#ifdef ETXTBSY + return ETXTBSY; +#else + goto not_there; +#endif + break; + case 'U': + if (strEQ(name, "EUSERS")) +#ifdef EUSERS + return EUSERS; +#else + goto not_there; +#endif + break; + case 'W': + if (strEQ(name, "EWOULDBLOCK")) +#ifdef EWOULDBLOCK + return EWOULDBLOCK; +#else + goto not_there; +#endif + break; case 'X': if (strEQ(name, "EXIT_FAILURE")) #ifdef EXIT_FAILURE @@ -1344,13 +1723,13 @@ int arg; goto not_there; #endif #ifdef SIG_DFL - if (strEQ(name, "SIG_DFL")) return (int)SIG_DFL; + if (strEQ(name, "SIG_DFL")) return (IV)SIG_DFL; #endif #ifdef SIG_ERR - if (strEQ(name, "SIG_ERR")) return (int)SIG_ERR; + if (strEQ(name, "SIG_ERR")) return (IV)SIG_ERR; #endif #ifdef SIG_IGN - if (strEQ(name, "SIG_IGN")) return (int)SIG_IGN; + if (strEQ(name, "SIG_IGN")) return (IV)SIG_IGN; #endif if (strEQ(name, "SIG_SETMASK")) #ifdef SIG_SETMASK @@ -1483,21 +1862,6 @@ int arg; break; } if (name[1] == '_') { -#ifdef S_ISBLK - if (strEQ(name, "S_ISBLK")) return S_ISBLK(arg); -#endif -#ifdef S_ISCHR - if (strEQ(name, "S_ISCHR")) return S_ISCHR(arg); -#endif -#ifdef S_ISDIR - if (strEQ(name, "S_ISDIR")) return S_ISDIR(arg); -#endif -#ifdef S_ISFIFO - if (strEQ(name, "S_ISFIFO")) return S_ISFIFO(arg); -#endif -#ifdef S_ISREG - if (strEQ(name, "S_ISREG")) return S_ISREG(arg); -#endif if (strEQ(name, "S_ISGID")) #ifdef S_ISGID return S_ISGID; @@ -1582,6 +1946,22 @@ int arg; #else goto not_there; #endif + errno = EAGAIN; /* the following aren't constants */ +#ifdef S_ISBLK + if (strEQ(name, "S_ISBLK")) return S_ISBLK(arg); +#endif +#ifdef S_ISCHR + if (strEQ(name, "S_ISCHR")) return S_ISCHR(arg); +#endif +#ifdef S_ISDIR + if (strEQ(name, "S_ISDIR")) return S_ISDIR(arg); +#endif +#ifdef S_ISFIFO + if (strEQ(name, "S_ISFIFO")) return S_ISFIFO(arg); +#endif +#ifdef S_ISREG + if (strEQ(name, "S_ISREG")) return S_ISREG(arg); +#endif break; } if (strEQ(name, "SEEK_CUR")) @@ -1620,12 +2000,51 @@ int arg; #else goto not_there; #endif - if (strEQ(name, "SA_NOCLDSTOP")) + if (strnEQ(name, "SA_", 3)) { + if (strEQ(name, "SA_NOCLDSTOP")) #ifdef SA_NOCLDSTOP - return SA_NOCLDSTOP; + return SA_NOCLDSTOP; #else - goto not_there; + goto not_there; +#endif + if (strEQ(name, "SA_NOCLDWAIT")) +#ifdef SA_NOCLDWAIT + return SA_NOCLDWAIT; +#else + goto not_there; +#endif + if (strEQ(name, "SA_NODEFER")) +#ifdef SA_NODEFER + return SA_NODEFER; +#else + goto not_there; +#endif + if (strEQ(name, "SA_ONSTACK")) +#ifdef SA_ONSTACK + return SA_ONSTACK; +#else + goto not_there; +#endif + if (strEQ(name, "SA_RESETHAND")) +#ifdef SA_RESETHAND + return SA_RESETHAND; +#else + goto not_there; +#endif + if (strEQ(name, "SA_RESTART")) +#ifdef SA_RESTART + return SA_RESTART; +#else + goto not_there; #endif + if (strEQ(name, "SA_SIGINFO")) +#ifdef SA_SIGINFO + return SA_SIGINFO; +#else + goto not_there; +#endif + break; + } if (strEQ(name, "SCHAR_MAX")) #ifdef SCHAR_MAX return SCHAR_MAX; @@ -1844,6 +2263,19 @@ int arg; #else goto not_there; #endif + if (strEQ(name, "WNOHANG")) +#ifdef WNOHANG + return WNOHANG; +#else + goto not_there; +#endif + if (strEQ(name, "WUNTRACED")) +#ifdef WUNTRACED + return WUNTRACED; +#else + goto not_there; +#endif + errno = EAGAIN; /* the following aren't constants */ #ifdef WEXITSTATUS if (strEQ(name, "WEXITSTATUS")) return WEXITSTATUS(arg); #endif @@ -1856,24 +2288,12 @@ int arg; #ifdef WIFSTOPPED if (strEQ(name, "WIFSTOPPED")) return WIFSTOPPED(arg); #endif - if (strEQ(name, "WNOHANG")) -#ifdef WNOHANG - return WNOHANG; -#else - goto not_there; -#endif #ifdef WSTOPSIG if (strEQ(name, "WSTOPSIG")) return WSTOPSIG(arg); #endif #ifdef WTERMSIG if (strEQ(name, "WTERMSIG")) return WTERMSIG(arg); #endif - if (strEQ(name, "WUNTRACED")) -#ifdef WUNTRACED - return WUNTRACED; -#else - goto not_there; -#endif break; case 'X': if (strEQ(name, "X_OK")) @@ -1886,55 +2306,55 @@ int arg; 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; @@ -2060,86 +2480,67 @@ int arg; } 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; #endif break; } - if (strEQ(name, "_IOFBF")) -#ifdef _IOFBF - return _IOFBF; -#else - goto not_there; -#endif - if (strEQ(name, "_IOLBF")) -#ifdef _IOLBF - return _IOLBF; -#else - goto not_there; -#endif - if (strEQ(name, "_IONBF")) -#ifdef _IONBF - return _IONBF; -#else - goto not_there; -#endif - break; } errno = EINVAL; return 0; @@ -2206,6 +2607,7 @@ new(packname = "POSIX::Termios", ...) RETVAL = (struct termios*)safemalloc(sizeof(struct termios)); #else not_here("termios"); + RETVAL = 0; #endif } OUTPUT: @@ -2255,7 +2657,8 @@ getiflag(termios_ref) #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */ RETVAL = termios_ref->c_iflag; #else - not_here("getiflag"); + not_here("getiflag"); + RETVAL = 0; #endif OUTPUT: RETVAL @@ -2267,7 +2670,8 @@ getoflag(termios_ref) #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */ RETVAL = termios_ref->c_oflag; #else - not_here("getoflag"); + not_here("getoflag"); + RETVAL = 0; #endif OUTPUT: RETVAL @@ -2279,7 +2683,8 @@ getcflag(termios_ref) #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */ RETVAL = termios_ref->c_cflag; #else - not_here("getcflag"); + not_here("getcflag"); + RETVAL = 0; #endif OUTPUT: RETVAL @@ -2291,7 +2696,8 @@ getlflag(termios_ref) #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */ RETVAL = termios_ref->c_lflag; #else - not_here("getlflag"); + not_here("getlflag"); + RETVAL = 0; #endif OUTPUT: RETVAL @@ -2306,7 +2712,8 @@ getcc(termios_ref, ccix) croak("Bad getcc subscript"); RETVAL = termios_ref->c_cc[ccix]; #else - not_here("getcc"); + not_here("getcc"); + RETVAL = 0; #endif OUTPUT: RETVAL @@ -2380,65 +2787,6 @@ setcc(termios_ref, ccix, cc) #endif - -MODULE = FileHandle PACKAGE = FileHandle PREFIX = f - -SV * -fgetpos(handle) - InputStream handle - CODE: - { - Fpos_t pos; - fgetpos(handle, &pos); - ST(0) = sv_2mortal(newSVpv((char*)&pos, sizeof(Fpos_t))); - } - -SysRet -fsetpos(handle, pos) - InputStream handle - SV * pos - CODE: - RETVAL = fsetpos(handle, (Fpos_t*)SvPVX(pos)); - OUTPUT: - RETVAL - -int -ungetc(handle, c) - InputStream handle - int c - CODE: - RETVAL = ungetc(c, handle); - OUTPUT: - RETVAL - -OutputStream -new_tmpfile(packname = "FileHandle") - char * packname - CODE: - RETVAL = tmpfile(); - OUTPUT: - RETVAL - -int -ferror(handle) - InputStream handle - -SysRet -fflush(handle) - OutputStream handle - -void -setbuf(handle, buf) - OutputStream handle - char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), BUFSIZ) : 0; - -SysRet -setvbuf(handle, buf, type, size) - OutputStream handle - char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0; - int type - int size - MODULE = POSIX PACKAGE = POSIX double @@ -2448,11 +2796,11 @@ constant(name,arg) int isalnum(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isalnum(*s)) RETVAL = 0; OUTPUT: @@ -2460,11 +2808,11 @@ isalnum(charstring) int isalpha(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isalpha(*s)) RETVAL = 0; OUTPUT: @@ -2472,11 +2820,11 @@ isalpha(charstring) int iscntrl(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!iscntrl(*s)) RETVAL = 0; OUTPUT: @@ -2484,11 +2832,11 @@ iscntrl(charstring) int isdigit(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isdigit(*s)) RETVAL = 0; OUTPUT: @@ -2496,11 +2844,11 @@ isdigit(charstring) int isgraph(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isgraph(*s)) RETVAL = 0; OUTPUT: @@ -2508,11 +2856,11 @@ isgraph(charstring) int islower(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!islower(*s)) RETVAL = 0; OUTPUT: @@ -2520,11 +2868,11 @@ islower(charstring) int isprint(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isprint(*s)) RETVAL = 0; OUTPUT: @@ -2532,11 +2880,11 @@ isprint(charstring) int ispunct(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!ispunct(*s)) RETVAL = 0; OUTPUT: @@ -2544,11 +2892,11 @@ ispunct(charstring) int isspace(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isspace(*s)) RETVAL = 0; OUTPUT: @@ -2556,11 +2904,11 @@ isspace(charstring) int isupper(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isupper(*s)) RETVAL = 0; OUTPUT: @@ -2568,11 +2916,11 @@ isupper(charstring) int isxdigit(charstring) - char * charstring + unsigned char * charstring CODE: - char *s; - RETVAL = 1; - for (s = charstring; *s && RETVAL; s++) + unsigned char *s = charstring; + unsigned char *e = s + na; /* "na" set by typemap side effect */ + for (RETVAL = 1; RETVAL && s < e; s++) if (!isxdigit(*s)) RETVAL = 0; OUTPUT: @@ -2597,6 +2945,7 @@ localeconv() #ifdef HAS_LOCALECONV struct lconv *lcbuf; RETVAL = newHV(); + SET_NUMERIC_LOCAL(); if (lcbuf = localeconv()) { /* the strings */ if (lcbuf->decimal_point && *lcbuf->decimal_point) @@ -2617,9 +2966,11 @@ localeconv() if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point) hv_store(RETVAL, "mon_decimal_point", 17, newSVpv(lcbuf->mon_decimal_point, 0), 0); +#ifndef NO_LOCALECONV_MON_THOUSANDS_SEP if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep) hv_store(RETVAL, "mon_thousands_sep", 17, newSVpv(lcbuf->mon_thousands_sep, 0), 0); +#endif if (lcbuf->mon_grouping && *lcbuf->mon_grouping) hv_store(RETVAL, "mon_grouping", 12, newSVpv(lcbuf->mon_grouping, 0), 0); @@ -2662,9 +3013,67 @@ localeconv() RETVAL char * -setlocale(category, locale) +setlocale(category, locale = 0) int category char * locale + CODE: + RETVAL = setlocale(category, locale); + if (RETVAL) { +#ifdef USE_LOCALE_CTYPE + if (category == LC_CTYPE +#ifdef LC_ALL + || category == LC_ALL +#endif + ) + { + char *newctype; +#ifdef LC_ALL + if (category == LC_ALL) + newctype = setlocale(LC_CTYPE, NULL); + else +#endif + newctype = RETVAL; + perl_new_ctype(newctype); + } +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + if (category == LC_COLLATE +#ifdef LC_ALL + || category == LC_ALL +#endif + ) + { + char *newcoll; +#ifdef LC_ALL + if (category == LC_ALL) + newcoll = setlocale(LC_COLLATE, NULL); + else +#endif + newcoll = RETVAL; + perl_new_collate(newcoll); + } +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + if (category == LC_NUMERIC +#ifdef LC_ALL + || category == LC_ALL +#endif + ) + { + char *newnum; +#ifdef LC_ALL + if (category == LC_ALL) + newnum = setlocale(LC_NUMERIC, NULL); + else +#endif + newnum = RETVAL; + perl_new_numeric(newnum); + } +#endif /* USE_LOCALE_NUMERIC */ + } + OUTPUT: + RETVAL + double acos(x) @@ -2740,7 +3149,9 @@ sigaction(sig, action, oldaction = 0) POSIX::SigAction action POSIX::SigAction oldaction CODE: - +#ifdef WIN32 + RETVAL = not_here("sigaction"); +#else # This code is really grody because we're trying to make the signal # interface look beautiful, which is hard. @@ -2753,8 +3164,8 @@ sigaction(sig, action, oldaction = 0) POSIX__SigSet sigset; SV** svp; SV** sigsvp = hv_fetch(GvHVn(siggv), - whichsigname(sig), - strlen(whichsigname(sig)), + sig_name[sig], + strlen(sig_name[sig]), TRUE); /* Remember old handler name if desired. */ @@ -2794,9 +3205,9 @@ sigaction(sig, action, oldaction = 0) if (action && oldaction) RETVAL = sigaction(sig, & act, & oact); else if (action) - RETVAL = sigaction(sig, & act, (struct sigaction*)0); + RETVAL = sigaction(sig, & act, (struct sigaction *)0); else if (oldaction) - RETVAL = sigaction(sig, (struct sigaction*)0, & oact); + RETVAL = sigaction(sig, (struct sigaction *)0, & oact); else RETVAL = -1; @@ -2819,6 +3230,7 @@ sigaction(sig, action, oldaction = 0) sv_setiv(*svp, oact.sa_flags); } } +#endif OUTPUT: RETVAL @@ -2868,28 +3280,26 @@ pipe() PPCODE: int fds[2]; if (pipe(fds) != -1) { - EXTEND(sp,2); + EXTEND(SP,2); PUSHs(sv_2mortal(newSViv(fds[0]))); PUSHs(sv_2mortal(newSViv(fds[1]))); } SysRet read(fd, buffer, nbytes) - int fd - char * buffer = sv_grow(ST(1),SvIV(ST(2))+1); - size_t nbytes + PREINIT: + SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1); + INPUT: + int fd + size_t nbytes + char * buffer = sv_grow( sv_buffer, nbytes+1 ); CLEANUP: - if (RETVAL >= 0) { - SvCUR(ST(1)) = RETVAL; - SvPOK_only(ST(1)); - *SvEND(ST(1)) = '\0'; - if (tainting) - sv_magic(ST(1), 0, 't', 0, 0); - } - -SysRet -setgid(gid) - Gid_t gid + if (RETVAL >= 0) { + SvCUR(sv_buffer) = RETVAL; + SvPOK_only(sv_buffer); + *SvEND(sv_buffer) = '\0'; + SvTAINTED_on(sv_buffer); + } SysRet setpgid(pid, pgid) @@ -2899,10 +3309,6 @@ setpgid(pid, pgid) pid_t setsid() -SysRet -setuid(uid) - Uid_t uid - pid_t tcgetpgrp(fd) int fd @@ -2918,7 +3324,7 @@ uname() #ifdef HAS_UNAME struct utsname buf; if (uname(&buf) >= 0) { - EXTEND(sp, 5); + EXTEND(SP, 5); PUSHs(sv_2mortal(newSVpv(buf.sysname, 0))); PUSHs(sv_2mortal(newSVpv(buf.nodename, 0))); PUSHs(sv_2mortal(newSVpv(buf.release, 0))); @@ -2975,6 +3381,66 @@ strcoll(s1, s2) char * s1 char * s2 +void +strtod(str) + char * str + PREINIT: + double num; + char *unparsed; + PPCODE: + SET_NUMERIC_LOCAL(); + num = strtod(str, &unparsed); + PUSHs(sv_2mortal(newSVnv(num))); + if (GIMME == G_ARRAY) { + EXTEND(SP, 1); + if (unparsed) + PUSHs(sv_2mortal(newSViv(strlen(unparsed)))); + else + PUSHs(&sv_undef); + } + +void +strtol(str, base = 0) + char * str + int base + PREINIT: + long num; + char *unparsed; + PPCODE: + num = strtol(str, &unparsed, base); + if (num >= IV_MIN && num <= IV_MAX) + PUSHs(sv_2mortal(newSViv((IV)num))); + else + PUSHs(sv_2mortal(newSVnv((double)num))); + if (GIMME == G_ARRAY) { + EXTEND(SP, 1); + if (unparsed) + PUSHs(sv_2mortal(newSViv(strlen(unparsed)))); + else + PUSHs(&sv_undef); + } + +void +strtoul(str, base = 0) + char * str + int base + PREINIT: + unsigned long num; + char *unparsed; + PPCODE: + num = strtoul(str, &unparsed, base); + if (num <= IV_MAX) + PUSHs(sv_2mortal(newSViv((IV)num))); + else + PUSHs(sv_2mortal(newSVnv((double)num))); + if (GIMME == G_ARRAY) { + EXTEND(SP, 1); + if (unparsed) + PUSHs(sv_2mortal(newSViv(strlen(unparsed)))); + else + PUSHs(&sv_undef); + } + SV * strxfrm(src) SV * src @@ -3041,6 +3507,7 @@ asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0) CODE: { struct tm mytm; + init_tm(&mytm); /* XXX workaround - see init_tm() above */ mytm.tm_sec = sec; mytm.tm_min = min; mytm.tm_hour = hour; @@ -3062,6 +3529,19 @@ char * ctime(time) Time_t &time +void +times() + PPCODE: + struct tms tms; + clock_t realtime; + realtime = times( &tms ); + EXTEND(SP,5); + PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) ); + PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) ); + PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) ); + PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) ); + PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) ); + double difftime(time1, time2) Time_t time1 @@ -3081,6 +3561,7 @@ mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0) CODE: { struct tm mytm; + init_tm(&mytm); /* XXX workaround - see init_tm() above */ mytm.tm_sec = sec; mytm.tm_min = min; mytm.tm_hour = hour; @@ -3112,6 +3593,7 @@ strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0) 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; @@ -3131,7 +3613,7 @@ tzset() void tzname() PPCODE: - EXTEND(sp,2); + EXTEND(SP,2); PUSHs(sv_2mortal(newSVpv(tzname[0],strlen(tzname[0])))); PUSHs(sv_2mortal(newSVpv(tzname[1],strlen(tzname[1]))));