#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)
# undef signal
# undef open
+# undef setmode
# define open PerlLIO_open3
-# undef TAINT_PROPER
-# define TAINT_PROPER(a)
#endif
#include <ctype.h>
#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
#ifdef I_STDDEF
#include <stddef.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
# 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) {
+ clock_t vms_times(struct tms *PL_bufptr) {
+ dTHX;
clock_t retval;
/* Get wall time and convert to 10 ms intervals to
* produce the return value that the POSIX standard expects */
_ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));
# endif
/* Fill in the struct tms using the CRTL routine . . .*/
- times((tbuffer_t *)bufptr);
+ times((tbuffer_t *)PL_bufptr);
return (clock_t) retval;
}
# define times(t) vms_times(t)
#else
+#if defined (CYGWIN)
+# define tzname _tzname
+# undef MB_CUR_MAX /* XXX: bug in b20.1 */
+#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
# define sigfillset(a) not_here("sigfillset")
# define sigismember(a,b) not_here("sigismember")
#else
+
+# ifndef HAS_MKFIFO
+# ifdef OS2
+# 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 */
+
# include <grp.h>
# include <sys/times.h>
# ifdef HAS_UNAME
#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")
extern char *tzname[];
# endif
#else
-#if !defined(__GNUC__) && !defined(tzname)
+#if !defined(WIN32) || (defined(__MINGW32__) && !defined(tzname))
char *tzname[] = { "" , "" };
#endif
#endif
*/
#ifdef HAS_GNULIBC
# ifndef STRUCT_TM_HASZONE
-# define STRUCT_TM_HAS_ZONE
+# define STRUCT_TM_HASZONE
# endif
#endif
#ifdef STRUCT_TM_HASZONE
static void
-init_tm(ptm) /* see mktime, strftime and asctime */
- struct tm *ptm;
+init_tm(struct tm *ptm) /* see mktime, strftime and asctime */
{
Time_t now;
(void)time(&now);
}
static
-#ifdef HAS_LONG_DOUBLE
+#if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)
long double
#else
double
#else
goto not_there;
#endif
+ break;
+ case 'L':
if (strEQ(name, "ELOOP"))
#ifdef ELOOP
return ELOOP;
#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
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
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()) {
/* the strings */
if (lcbuf->decimal_point && *lcbuf->decimal_point)
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 */
}
# This code is really grody because we're trying to make the signal
# interface look beautiful, which is hard.
- if (!siggv)
+ if (!PL_siggv)
gv_fetchpv("SIG", TRUE, SVt_PVHV);
{
struct sigaction oact;
POSIX__SigSet sigset;
SV** svp;
- SV** sigsvp = hv_fetch(GvHVn(siggv),
- sig_name[sig],
- strlen(sig_name[sig]),
+ SV** sigsvp = hv_fetch(GvHVn(PL_siggv),
+ PL_sig_name[sig],
+ strlen(PL_sig_name[sig]),
TRUE);
+ STRLEN n_a;
/* Remember old handler name if desired. */
if (oldaction) {
- char *hand = SvPVx(*sigsvp, na);
+ char *hand = SvPVx(*sigsvp, n_a);
svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
sv_setpv(*svp, *hand ? hand : "DEFAULT");
}
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_setpv(*sigsvp, SvPV(*svp, n_a));
mg_set(*sigsvp); /* handles DEFAULT and IGNORE */
- act.sa_handler = sighandler;
+ act.sa_handler = PL_sighandlerp;
/* Set up any desired mask. */
svp = hv_fetch(action, "MASK", 4, FALSE);
sigset = (sigset_t*) tmp;
}
else {
- sigset = (sigset_t*)safemalloc(sizeof(sigset_t));
+ New(0, sigset, 1, sigset_t);
sv_setptrobj(*svp, sigset, "POSIX::SigSet");
}
*sigset = oact.sa_mask;
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)
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 *
RETVAL
char *
-strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
char * fmt
int sec
int min
mytm.tm_wday = wday;
mytm.tm_yday = yday;
mytm.tm_isdst = isdst;
+#if defined(HINT_STRFTIME_NEEDS_MKTIME)
+ (void) mktime(&mytm);
+#endif
len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
- ST(0) = sv_2mortal(newSVpv(tmpbuf, len));
+ /*
+ ** The following is needed to handle to the situation where
+ ** tmpbuf overflows. Basically we want to allocate a buffer
+ ** and try repeatedly. The reason why it is so complicated
+ ** is that getting a return value of 0 from strftime can indicate
+ ** one of the following:
+ ** 1. buffer overflowed,
+ ** 2. illegal conversion specifier, or
+ ** 3. the format string specifies nothing to be returned(not
+ ** an error). This could be because format is an empty string
+ ** or it specifies %p that yields an empty string in some locale.
+ ** If there is a better way to make it portable, go ahead by
+ ** all means.
+ */
+ if ( ( len > 0 && len < sizeof(tmpbuf) )
+ || ( len == 0 && strlen(fmt) == 0 ) ) {
+ ST(0) = sv_2mortal(newSVpv(tmpbuf, len));
+ } else {
+ /* Possibly buf overflowed - try again with a bigger buf */
+ int bufsize = strlen(fmt) + sizeof(tmpbuf);
+ char* buf;
+ int buflen;
+
+ New(0, buf, bufsize, char);
+ while( buf ) {
+ buflen = strftime(buf, bufsize, fmt, &mytm);
+ if ( buflen > 0 && buflen < bufsize ) break;
+ bufsize *= 2;
+ Renew(buf, bufsize, char);
+ }
+ if ( buf ) {
+ ST(0) = sv_2mortal(newSVpvn(buf, buflen));
+ Safefree(buf);
+ } else {
+ ST(0) = sv_2mortal(newSVpvn(tmpbuf, len));
+ }
+ }
}
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)