#ifdef HAS_PASSWD
# ifdef I_PWD
# include <pwd.h>
-# else
-# if !defined(VMS)
+# elif !defined(VMS)
struct passwd *getpwnam (char *);
struct passwd *getpwuid (Uid_t);
-# endif
# endif
# ifdef HAS_GETPWENT
-#ifndef getpwent
+# ifndef getpwent
struct passwd *getpwent (void);
-#elif defined (VMS) && defined (my_getpwent)
+# elif defined (VMS) && defined (my_getpwent)
struct passwd *Perl_my_getpwent (pTHX);
-#endif
+# endif
# endif
#endif
struct group *getgrgid (Gid_t);
# endif
# ifdef HAS_GETGRENT
-#ifndef getgrent
+# ifndef getgrent
struct group *getgrent (void);
-#endif
+# endif
# endif
#endif
# undef my_chsize
# endif
# define my_chsize PerlLIO_chsize
+#elif defined(HAS_TRUNCATE)
+# define my_chsize PerlLIO_chsize
#else
-# ifdef HAS_TRUNCATE
-# define my_chsize PerlLIO_chsize
-# else
I32 my_chsize(int fd, Off_t length);
-# endif
#endif
#ifdef HAS_FLOCK
# if defined(HAS_FCNTL) && defined(FCNTL_CAN_LOCK)
# define FLOCK fcntl_emulate_flock
# define FCNTL_EMULATE_FLOCK
-# else /* no flock() or fcntl(F_SETLK,...) */
-# ifdef HAS_LOCKF
-# define FLOCK lockf_emulate_flock
-# define LOCKF_EMULATE_FLOCK
-# endif /* lockf */
-# endif /* no flock() or fcntl(F_SETLK,...) */
+# elif defined(HAS_LOCKF)
+# define FLOCK lockf_emulate_flock
+# define LOCKF_EMULATE_FLOCK
+# endif
# ifdef FLOCK
static int FLOCK (int, int);
#endif
#if !defined(PERL_EFF_ACCESS) && defined(HAS_ACCESSX) && defined(ACC_SELF)
- /* AIX */
-# define PERL_EFF_ACCESS(p,f) (accessx((p), (f), ACC_SELF))
+ /* AIX's accessx() doesn't declare its argument const, unlike every other platform */
+# define PERL_EFF_ACCESS(p,f) (accessx((char*)(p), (f), ACC_SELF))
#endif
#if !defined(HAS_SETREUID) && !defined(HAS_SETRESUID)
Perl_croak(aTHX_ "switching effective uid is not implemented");
#else
-#ifdef HAS_SETREUID
+# ifdef HAS_SETREUID
if (setreuid(euid, ruid))
-#else
-#ifdef HAS_SETRESUID
+# elif defined(HAS_SETRESUID)
if (setresuid(euid, ruid, (Uid_t)-1))
-#endif
-#endif
+# endif
/* diag_listed_as: entering effective %s failed */
Perl_croak(aTHX_ "entering effective uid failed");
#endif
#if !defined(HAS_SETREGID) && !defined(HAS_SETRESGID)
Perl_croak(aTHX_ "switching effective gid is not implemented");
#else
-#ifdef HAS_SETREGID
+# ifdef HAS_SETREGID
if (setregid(egid, rgid))
-#else
-#ifdef HAS_SETRESGID
+# elif defined(HAS_SETRESGID)
if (setresgid(egid, rgid, (Gid_t)-1))
-#endif
-#endif
+# endif
/* diag_listed_as: entering effective %s failed */
Perl_croak(aTHX_ "entering effective gid failed");
#endif
#ifdef HAS_SETREUID
if (setreuid(ruid, euid))
-#else
-#ifdef HAS_SETRESUID
+#elif defined(HAS_SETRESUID)
if (setresuid(ruid, euid, (Uid_t)-1))
#endif
-#endif
/* diag_listed_as: leaving effective %s failed */
Perl_croak(aTHX_ "leaving effective uid failed");
#ifdef HAS_SETREGID
if (setregid(rgid, egid))
-#else
-#ifdef HAS_SETRESGID
+#elif defined(HAS_SETRESGID)
if (setresgid(rgid, egid, (Gid_t)-1))
#endif
-#endif
/* diag_listed_as: leaving effective %s failed */
Perl_croak(aTHX_ "leaving effective gid failed");
dSP; dTARGET;
PerlIO *fp;
const char * const tmps = POPpconstx;
- const I32 gimme = GIMME_V;
+ const U8 gimme = GIMME_V;
const char *mode = "r";
TAINT_PROPER("``");
ENTER_with_name("backtick");
SAVESPTR(PL_rs);
PL_rs = &PL_sv_undef;
- sv_setpvs(TARG, ""); /* note that this preserves previous buffer */
+ SvPVCLEAR(TARG); /* note that this preserves previous buffer */
while (sv_gets(TARG, fp, SvCUR(TARG)) != NULL)
NOOP;
LEAVE_with_name("backtick");
}
else if (SP == MARK) {
exsv = &PL_sv_no;
- EXTEND(SP, 1);
+ MEXTEND(SP, 1);
SP = MARK + 1;
}
else {
}
}
if (SvROK(exsv) && !PL_warnhook)
- Perl_warn(aTHX_ "%"SVf, SVfARG(exsv));
+ Perl_warn(aTHX_ "%" SVf, SVfARG(exsv));
else warn_sv(exsv);
RETSETYES;
}
}
}
}
- else if (SvPOK(errsv) && SvCUR(errsv)) {
+ else if (SvOK(errsv) && (SvPV_nomg(errsv,len), len)) {
exsv = sv_mortalcopy(errsv);
sv_catpvs(exsv, "\t...propagated");
}
IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT;
if (IoDIRP(io))
- Perl_ck_warner_d(aTHX_ packWARN2(WARN_IO, WARN_DEPRECATED),
- "Opening dirhandle %"HEKf" also as a file",
+ Perl_croak(aTHX_ "Cannot open %" HEKf " as a filehandle: it is already open as a dirhandle",
HEKfARG(GvENAME_HEK(gv)));
mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar);
if (ok)
PUSHi( (I32)PL_forkprocess );
else if (PL_forkprocess == 0) /* we are a new child */
- PUSHi(0);
+ PUSHs(&PL_sv_zero);
else
RETPUSHUNDEF;
RETURN;
PP(pp_close)
{
dSP;
+ /* pp_coreargs pushes a NULL to indicate no args passed to
+ * CORE::close() */
GV * const gv =
MAXARG == 0 || (!TOPs && !POPs) ? PL_defoutgv : MUTABLE_GV(POPs);
if (IoIFP(wstio))
do_close(wgv, FALSE);
- if (PerlProc_pipe(fd) < 0)
+ if (PerlProc_pipe_cloexec(fd) < 0)
goto badexit;
- IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPE_OPEN_MODE);
- IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_MODE);
+ IoIFP(rstio) = PerlIO_fdopen(fd[0], "r" PIPE_OPEN_MODE);
+ IoOFP(wstio) = PerlIO_fdopen(fd[1], "w" PIPE_OPEN_MODE);
IoOFP(rstio) = IoIFP(rstio);
IoIFP(wstio) = IoOFP(wstio);
IoTYPE(rstio) = IoTYPE_RDONLY;
PerlLIO_close(fd[1]);
goto badexit;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
- goto badexit;
-#endif
RETPUSHYES;
badexit:
* (Sorry obfuscation writers. You're not going to be given this one.)
*/
stash = gv_stashsv(*MARK, 0);
- if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
- DIE(aTHX_ "Can't locate object method \"%s\" via package \"%"SVf"\"",
- methname, SVfARG(SvOK(*MARK) ? *MARK : &PL_sv_no));
- }
+ if (!stash) {
+ if (SvROK(*MARK))
+ DIE(aTHX_ "Can't locate object method \"%s\" via package \"%" SVf "\"",
+ methname, SVfARG(*MARK));
+ else if (isGV(*MARK)) {
+ /* If the glob doesn't name an existing package, using
+ * SVfARG(*MARK) would yield "*Foo::Bar" or *main::Foo. So
+ * generate the name for the error message explicitly. */
+ SV *stashname = sv_2mortal(newSV(0));
+ gv_fullname4(stashname, (GV *) *MARK, NULL, FALSE);
+ DIE(aTHX_ "Can't locate object method \"%s\" via package \"%" SVf "\"",
+ methname, SVfARG(stashname));
+ }
+ else {
+ SV *stashname = !SvPOK(*MARK) ? &PL_sv_no
+ : SvCUR(*MARK) ? *MARK
+ : sv_2mortal(newSVpvs("main"));
+ DIE(aTHX_ "Can't locate object method \"%s\" via package \"%" SVf "\""
+ " (perhaps you forgot to load \"%" SVf "\"?)",
+ methname, SVfARG(stashname), SVfARG(stashname));
+ }
+ }
+ else if (!(gv = gv_fetchmethod(stash, methname))) {
+ /* The effective name can only be NULL for stashes that have
+ * been deleted from the symbol table, which this one can't
+ * be, since we just looked it up by name.
+ */
+ DIE(aTHX_ "Can't locate object method \"%s\" via package \"%" HEKf "\"",
+ methname, HvENAME_HEK_NN(stash));
+ }
ENTER_with_name("call_TIE");
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
if ((mg = SvTIED_mg(sv, how))) {
SV * const obj = SvRV(SvTIED_obj(sv, mg));
- if (obj) {
+ if (obj && SvSTASH(obj)) {
GV * const gv = gv_fetchmethod_autoload(SvSTASH(obj), "UNTIE", FALSE);
CV *cv;
if (gv && isGV(gv) && (cv = GvCV(gv))) {
}
else if (mg && SvREFCNT(obj) > 1) {
Perl_ck_warner(aTHX_ packWARN(WARN_UNTIE),
- "untie attempted while %"UVuf" inner references still exist",
+ "untie attempted while %" UVuf " inner references still exist",
(UV)SvREFCNT(obj) - 1 ) ;
}
}
struct timeval *tbuf = &timebuf;
I32 growsize;
char *fd_sets[4];
+ SV *svs[4];
#if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
I32 masksize;
I32 offset;
SP -= 4;
for (i = 1; i <= 3; i++) {
- SV * const sv = SP[i];
+ SV * const sv = svs[i] = SP[i];
SvGETMAGIC(sv);
if (!SvOK(sv))
continue;
if (!SvPOKp(sv))
Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
"Non-string passed as bitmask");
- SvPV_force_nomg_nolen(sv); /* force string conversion */
+ if (SvGAMAGIC(sv)) {
+ svs[i] = sv_newmortal();
+ sv_copypv_nomg(svs[i], sv);
+ }
+ else
+ SvPV_force_nomg_nolen(sv); /* force string conversion */
}
- j = SvCUR(sv);
+ j = SvCUR(svs[i]);
if (maxlen < j)
maxlen = j;
}
tbuf = NULL;
for (i = 1; i <= 3; i++) {
- sv = SP[i];
+ sv = svs[i];
if (!SvOK(sv) || SvCUR(sv) == 0) {
fd_sets[i] = 0;
continue;
#endif
for (i = 1; i <= 3; i++) {
if (fd_sets[i]) {
- sv = SP[i];
+ sv = svs[i];
#if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
s = SvPVX(sv);
for (offset = 0; offset < growsize; offset += masksize) {
}
Safefree(fd_sets[i]);
#endif
- SvSETMAGIC(sv);
+ if (sv != SP[i])
+ SvSetMagicSV(SP[i], sv);
+ else
+ SvSETMAGIC(sv);
}
}
/*
-=head1 GV Functions
+=for apidoc_section $GV
=for apidoc setdefout
void
Perl_setdefout(pTHX_ GV *gv)
{
+ GV *oldgv = PL_defoutgv;
+
PERL_ARGS_ASSERT_SETDEFOUT;
+
SvREFCNT_inc_simple_void_NN(gv);
- SvREFCNT_dec(PL_defoutgv);
PL_defoutgv = gv;
+ SvREFCNT_dec(oldgv);
}
PP(pp_select)
PP(pp_getc)
{
dSP; dTARGET;
+ /* pp_coreargs pushes a NULL to indicate no args passed to
+ * CORE::getc() */
GV * const gv =
MAXARG==0 || (!TOPs && !POPs) ? PL_stdingv : MUTABLE_GV(POPs);
IO *const io = GvIO(gv);
if (io) {
const MAGIC * const mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar);
if (mg) {
- const U32 gimme = GIMME_V;
+ const U8 gimme = GIMME_V;
Perl_tied_method(aTHX_ SV_CONST(GETC), SP, MUTABLE_SV(io), mg, gimme, 0);
if (gimme == G_SCALAR) {
SPAGAIN;
S_doform(pTHX_ CV *cv, GV *gv, OP *retop)
{
PERL_CONTEXT *cx;
- const I32 gimme = GIMME_V;
+ const U8 gimme = GIMME_V;
PERL_ARGS_ASSERT_DOFORM;
if (CvCLONE(cv))
cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv))));
- PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp);
- PUSHFORMAT(cx, retop);
- if (CvDEPTH(cv) >= 2) {
- PERL_STACK_OVERFLOW_CHECK();
+ cx = cx_pushblock(CXt_FORMAT, gimme, PL_stack_sp, PL_savestack_ix);
+ cx_pushformat(cx, cv, retop, gv);
+ if (CvDEPTH(cv) >= 2)
pad_push(CvPADLIST(cv), CvDEPTH(cv));
- }
PAD_SET_CUR_NOSAVE(CvPADLIST(cv), CvDEPTH(cv));
setdefout(gv); /* locally select filehandle so $% et al work */
IO *io;
GV *fgv;
CV *cv = NULL;
- SV *tmpsv = NULL;
if (MAXARG == 0) {
EXTEND(SP, 1);
cv = GvFORM(fgv);
if (!cv) {
- tmpsv = sv_newmortal();
+ SV * const tmpsv = sv_newmortal();
gv_efullname4(tmpsv, fgv, NULL, FALSE);
- DIE(aTHX_ "Undefined format \"%"SVf"\" called", SVfARG(tmpsv));
+ DIE(aTHX_ "Undefined format \"%" SVf "\" called", SVfARG(tmpsv));
}
IoFLAGS(io) &= ~IOf_DIDTOP;
RETURNOP(doform(cv,gv,PL_op->op_next));
PP(pp_leavewrite)
{
dSP;
- GV * const gv = cxstack[cxstack_ix].blk_format.gv;
+ GV * const gv = CX_CUR()->blk_format.gv;
IO * const io = GvIOp(gv);
PerlIO *ofp;
PerlIO *fp;
SV *topname;
if (!IoFMT_NAME(io))
IoFMT_NAME(io) = savepv(GvNAME(gv));
- topname = sv_2mortal(Perl_newSVpvf(aTHX_ "%"HEKf"_TOP",
+ topname = sv_2mortal(Perl_newSVpvf(aTHX_ "%" HEKf "_TOP",
HEKfARG(GvNAME_HEK(gv))));
topgv = gv_fetchsv(topname, 0, SVt_PVFM);
if ((topgv && GvFORM(topgv)) ||
if (IoFLAGS(io) & IOf_DIDTOP) { /* Oh dear. It still doesn't fit. */
I32 lines = IoLINES_LEFT(io);
const char *s = SvPVX_const(PL_formtarget);
+ const char *e = SvEND(PL_formtarget);
if (lines <= 0) /* Yow, header didn't even fit!!! */
goto forget_top;
while (lines-- > 0) {
- s = strchr(s, '\n');
+ s = (char *) memchr(s, '\n', e - s);
if (!s)
break;
s++;
if (!cv) {
SV * const sv = sv_newmortal();
gv_efullname4(sv, fgv, NULL, FALSE);
- DIE(aTHX_ "Undefined top format \"%"SVf"\" called", SVfARG(sv));
+ DIE(aTHX_ "Undefined top format \"%" SVf "\" called", SVfARG(sv));
}
return doform(cv, gv, PL_op);
}
forget_top:
- cx = &cxstack[cxstack_ix];
+ cx = CX_CUR();
assert(CxTYPE(cx) == CXt_FORMAT);
SP = PL_stack_base + cx->blk_oldsp; /* ignore retval of formline */
CX_LEAVE_SCOPE(cx);
- POPFORMAT(cx);
- POPBLOCK(cx);
+ cx_popformat(cx);
+ cx_popblock(cx);
retop = cx->blk_sub.retop;
- cxstack_ix--;
+ CX_POP(cx);
+
+ EXTEND(SP, 1);
if (is_return)
/* XXX the semantics of doing 'return' in a format aren't documented.
/* Need TIEHANDLE method ? */
const char * const tmps = SvPV_const(sv, len);
- if (do_open_raw(gv, tmps, len, mode, perm)) {
+ if (do_open_raw(gv, tmps, len, mode, perm, NULL)) {
IoLINES(GvIOp(gv)) = 0;
PUSHs(&PL_sv_yes);
}
goto say_undef;
bufsv = *++MARK;
if (! SvOK(bufsv))
- sv_setpvs(bufsv, "");
+ SvPVCLEAR(bufsv);
length = SvIVx(*++MARK);
if (length < 0)
DIE(aTHX_ "Negative length");
if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
if (PL_op->op_type == OP_SYSREAD || PL_op->op_type == OP_RECV) {
- Perl_ck_warner(aTHX_ packWARN(WARN_DEPRECATED),
- "%s() is deprecated on :utf8 handles",
- OP_DESC(PL_op));
+ Perl_croak(aTHX_
+ "%s() isn't allowed on :utf8 handles",
+ OP_DESC(PL_op));
}
buffer = SvPVutf8_force(bufsv, blen);
/* UTF-8 may not have been set if they are all low bytes */
}
else {
buffer = SvPV_force(bufsv, blen);
- buffer_utf8 = !IN_BYTES && SvUTF8(bufsv);
+ buffer_utf8 = DO_UTF8(bufsv);
}
if (DO_UTF8(bufsv)) {
blen = sv_len_utf8_nomg(bufsv);
char namebuf[MAXPATHLEN];
if (fd < 0) {
SETERRNO(EBADF,SS_IVCHAN);
- RETPUSHUNDEF;
+ goto say_undef;
}
#if (defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)) || defined(__QNXNTO__)
bufsize = sizeof (struct sockaddr_in);
count = PerlSock_recvfrom(fd, buffer, length, offset,
(struct sockaddr *)namebuf, &bufsize);
if (count < 0)
- RETPUSHUNDEF;
+ goto say_undef;
/* MSG_TRUNC can give oversized count; quietly lose it */
if (count > length)
count = length;
const char *buffer;
SSize_t retval;
STRLEN blen;
- STRLEN orig_blen_bytes;
const int op_type = PL_op->op_type;
bool doing_utf8;
U8 *tmpbuf = NULL;
/* Do this first to trigger any overloading. */
buffer = SvPV_const(bufsv, blen);
- orig_blen_bytes = blen;
doing_utf8 = DO_UTF8(bufsv);
if (PerlIO_isutf8(IoIFP(io))) {
- Perl_ck_warner(aTHX_ packWARN(WARN_DEPRECATED),
- "%s() is deprecated on :utf8 handles",
- OP_DESC(PL_op));
- if (!SvUTF8(bufsv)) {
- /* We don't modify the original scalar. */
- tmpbuf = bytes_to_utf8((const U8*) buffer, &blen);
- buffer = (char *) tmpbuf;
- doing_utf8 = TRUE;
- }
+ Perl_croak(aTHX_
+ "%s() isn't allowed on :utf8 handles",
+ OP_DESC(PL_op));
}
else if (doing_utf8) {
STRLEN tmplen = blen;
#endif
{
Size_t length = 0; /* This length is in characters. */
- STRLEN blen_chars;
IV offset;
- if (doing_utf8) {
- if (tmpbuf) {
- /* The SV is bytes, and we've had to upgrade it. */
- blen_chars = orig_blen_bytes;
- } else {
- /* The SV really is UTF-8. */
- /* Don't call sv_len_utf8 on a magical or overloaded
- scalar, as we might get back a different result. */
- blen_chars = sv_or_pv_len_utf8(bufsv, buffer, blen);
- }
- } else {
- blen_chars = blen;
- }
-
if (MARK >= SP) {
- length = blen_chars;
+ length = blen;
} else {
#if Size_t_size > IVSIZE
length = (Size_t)SvNVx(*++MARK);
if (MARK < SP) {
offset = SvIVx(*++MARK);
if (offset < 0) {
- if (-offset > (IV)blen_chars) {
+ if (-offset > (IV)blen) {
Safefree(tmpbuf);
DIE(aTHX_ "Offset outside string");
}
- offset += blen_chars;
- } else if (offset > (IV)blen_chars) {
+ offset += blen;
+ } else if (offset > (IV)blen) {
Safefree(tmpbuf);
DIE(aTHX_ "Offset outside string");
}
} else
offset = 0;
- if (length > blen_chars - offset)
- length = blen_chars - offset;
- if (doing_utf8) {
- /* Here we convert length from characters to bytes. */
- if (tmpbuf || SvGMAGICAL(bufsv) || SvAMAGIC(bufsv)) {
- /* Either we had to convert the SV, or the SV is magical, or
- the SV has overloading, in which case we can't or mustn't
- or mustn't call it again. */
-
- buffer = (const char*)utf8_hop((const U8 *)buffer, offset);
- length = utf8_hop((U8 *)buffer, length) - (U8 *)buffer;
- } else {
- /* It's a real UTF-8 SV, and it's not going to change under
- us. Take advantage of any cache. */
- I32 start = offset;
- I32 len_I32 = length;
-
- /* Convert the start and end character positions to bytes.
- Remember that the second argument to sv_pos_u2b is relative
- to the first. */
- sv_pos_u2b(bufsv, &start, &len_I32);
-
- buffer += start;
- length = len_I32;
- }
- }
- else {
- buffer = buffer+offset;
- }
+ if (length > blen - offset)
+ length = blen - offset;
+ buffer = buffer+offset;
+
#ifdef PERL_SOCK_SYSWRITE_IS_SEND
if (IoTYPE(io) == IoTYPE_SOCKET) {
retval = PerlSock_send(fd, buffer, length, 0);
if (retval < 0)
goto say_undef;
SP = ORIGMARK;
- if (doing_utf8)
- retval = utf8_length((U8*)buffer, (U8*)buffer + retval);
Safefree(tmpbuf);
#if Size_t_size > IVSIZE
}
if (!gv)
- RETPUSHNO;
+ RETPUSHYES;
if ((io = GvIO(gv)) && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) {
return tied_method1(SV_CONST(EOF), SP, MUTABLE_SV(io), mg, newSVuv(which));
if (!MAXARG && (PL_op->op_flags & OPf_SPECIAL)) { /* eof() */
if (io && !IoIFP(io)) {
- if ((IoFLAGS(io) & IOf_START) && av_tindex(GvAVn(gv)) < 0) {
+ if ((IoFLAGS(io) & IOf_START) && av_count(GvAVn(gv)) == 0) {
SV ** svp;
IoLINES(io) = 0;
IoFLAGS(io) &= ~IOf_START;
}
#if LSEEKSIZE > IVSIZE
- PUSHn( do_tell(gv) );
+ PUSHn( (NV)do_tell(gv) );
#else
- PUSHi( do_tell(gv) );
+ PUSHi( (IV)do_tell(gv) );
#endif
RETURN;
}
*/
mode |= O_BINARY;
#endif
- tmpfd = PerlLIO_open(name, mode);
+ tmpfd = PerlLIO_open_cloexec(name, mode);
if (tmpfd < 0) {
result = 0;
else
#ifndef HAS_FCNTL
DIE(aTHX_ "fcntl is not implemented");
-#else
-#if defined(OS2) && defined(__EMX__)
+#elif defined(OS2) && defined(__EMX__)
retval = fcntl(PerlIO_fileno(IoIFP(io)), func, (int)s);
#else
retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s);
#endif
-#endif
#if defined(HAS_IOCTL) || defined(HAS_FCNTL)
if (SvPOK(argsv)) {
do_close(gv, FALSE);
TAINT_PROPER("socket");
- fd = PerlSock_socket(domain, type, protocol);
+ fd = PerlSock_socket_cloexec(domain, type, protocol);
if (fd < 0) {
- SETERRNO(EBADF,RMS_IFI);
RETPUSHUNDEF;
}
- IoIFP(io) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE); /* stdio gets confused about sockets */
- IoOFP(io) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
+ IoIFP(io) = PerlIO_fdopen(fd, "r" SOCKET_OPEN_MODE); /* stdio gets confused about sockets */
+ IoOFP(io) = PerlIO_fdopen(fd, "w" SOCKET_OPEN_MODE);
IoTYPE(io) = IoTYPE_SOCKET;
if (!IoIFP(io) || !IoOFP(io)) {
if (IoIFP(io)) PerlIO_close(IoIFP(io));
if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
RETPUSHUNDEF;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
- RETPUSHUNDEF;
-#endif
RETPUSHYES;
}
do_close(gv2, FALSE);
TAINT_PROPER("socketpair");
- if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
+ if (PerlSock_socketpair_cloexec(domain, type, protocol, fd) < 0)
RETPUSHUNDEF;
- IoIFP(io1) = PerlIO_fdopen(fd[0], "r"SOCKET_OPEN_MODE);
- IoOFP(io1) = PerlIO_fdopen(fd[0], "w"SOCKET_OPEN_MODE);
+ IoIFP(io1) = PerlIO_fdopen(fd[0], "r" SOCKET_OPEN_MODE);
+ IoOFP(io1) = PerlIO_fdopen(fd[0], "w" SOCKET_OPEN_MODE);
IoTYPE(io1) = IoTYPE_SOCKET;
- IoIFP(io2) = PerlIO_fdopen(fd[1], "r"SOCKET_OPEN_MODE);
- IoOFP(io2) = PerlIO_fdopen(fd[1], "w"SOCKET_OPEN_MODE);
+ IoIFP(io2) = PerlIO_fdopen(fd[1], "r" SOCKET_OPEN_MODE);
+ IoOFP(io2) = PerlIO_fdopen(fd[1], "w" SOCKET_OPEN_MODE);
IoTYPE(io2) = IoTYPE_SOCKET;
if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
RETPUSHUNDEF;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
- RETPUSHUNDEF;
-#endif
RETPUSHYES;
#else
goto nuts;
nstio = GvIOn(ngv);
- fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
+ fd = PerlSock_accept_cloexec(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
#if defined(OEMVS)
if (len == 0) {
/* Some platforms indicate zero length when an AF_UNIX client is
goto badexit;
if (IoIFP(nstio))
do_close(ngv, FALSE);
- IoIFP(nstio) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE);
- IoOFP(nstio) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
+ IoIFP(nstio) = PerlIO_fdopen(fd, "r" SOCKET_OPEN_MODE);
+ IoOFP(nstio) = PerlIO_fdopen(fd, "w" SOCKET_OPEN_MODE);
IoTYPE(nstio) = IoTYPE_SOCKET;
if (!IoIFP(nstio) || !IoOFP(nstio)) {
if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
goto badexit;
}
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- /* ensure close-on-exec */
- if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
- goto badexit;
-#endif
#ifdef __SCO_VERSION__
len = sizeof (struct sockaddr_in); /* OpenUNIX 8 somehow truncates info */
PUSHs(sv);
break;
case OP_SSOCKOPT: {
-#if defined(__SYMBIAN32__)
-# define SETSOCKOPT_OPTION_VALUE_T void *
-#else
-# define SETSOCKOPT_OPTION_VALUE_T const char *
-#endif
- /* XXX TODO: We need to have a proper type (a Configure probe,
- * etc.) for what the C headers think of the third argument of
- * setsockopt(), the option_value read-only buffer: is it
- * a "char *", or a "void *", const or not. Some compilers
- * don't take kindly to e.g. assuming that "char *" implicitly
- * promotes to a "void *", or to explicitly promoting/demoting
- * consts to non/vice versa. The "const void *" is the SUS
- * definition, but that does not fly everywhere for the above
- * reasons. */
- SETSOCKOPT_OPTION_VALUE_T buf;
+ const char *buf;
int aint;
if (SvPOKp(sv)) {
STRLEN l;
- buf = (SETSOCKOPT_OPTION_VALUE_T) SvPV_const(sv, l);
+ buf = SvPV_const(sv, l);
len = l;
}
else {
aint = (int)SvIV(sv);
- buf = (SETSOCKOPT_OPTION_VALUE_T) &aint;
+ buf = (const char *) &aint;
len = sizeof(int);
}
if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
if (!IoIFP(io))
goto nuts;
- sv = sv_2mortal(newSV(257));
- (void)SvPOK_only(sv);
+#ifdef HAS_SOCKADDR_STORAGE
+ len = sizeof(struct sockaddr_storage);
+#else
len = 256;
+#endif
+ sv = sv_2mortal(newSV(len+1));
+ (void)SvPOK_only(sv);
SvCUR_set(sv, len);
*SvEND(sv) ='\0';
fd = PerlIO_fileno(IoIFP(io));
dSP;
GV *gv = NULL;
IO *io = NULL;
- I32 gimme;
+ U8 gimme;
I32 max = 13;
SV* sv;
if (gv != PL_defgv) {
do_fstat_warning_check:
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "lstat() on filehandle%s%"SVf,
+ "lstat() on filehandle%s%" SVf,
gv ? " " : "",
SVfARG(gv
? sv_2mortal(newSVhek(GvENAME_HEK(gv)))
Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat");
}
- if (gv != PL_defgv) {
- bool havefp;
+ if (gv == PL_defgv) {
+ if (PL_laststatval < 0)
+ SETERRNO(EBADF,RMS_IFI);
+ } else {
do_fstat_have_io:
- havefp = FALSE;
PL_laststype = OP_STAT;
PL_statgv = gv ? gv : (GV *)io;
- sv_setpvs(PL_statname, "");
+ SvPVCLEAR(PL_statname);
if(gv) {
io = GvIO(gv);
}
if (IoIFP(io)) {
int fd = PerlIO_fileno(IoIFP(io));
if (fd < 0) {
+ report_evil_fh(gv);
PL_laststatval = -1;
SETERRNO(EBADF,RMS_IFI);
} else {
PL_laststatval = PerlLIO_fstat(fd, &PL_statcache);
- havefp = TRUE;
}
} else if (IoDIRP(io)) {
PL_laststatval =
PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache);
- havefp = TRUE;
} else {
+ report_evil_fh(gv);
PL_laststatval = -1;
+ SETERRNO(EBADF,RMS_IFI);
}
- }
- else PL_laststatval = -1;
- if (PL_laststatval < 0 && !havefp) report_evil_fh(gv);
+ } else {
+ report_evil_fh(gv);
+ PL_laststatval = -1;
+ SETERRNO(EBADF,RMS_IFI);
+ }
}
if (PL_laststatval < 0) {
}
else {
const char *file;
+ const char *temp;
+ STRLEN len;
if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
io = MUTABLE_IO(SvRV(sv));
if (PL_op->op_type == OP_LSTAT)
goto do_fstat_warning_check;
goto do_fstat_have_io;
}
-
SvTAINTED_off(PL_statname); /* previous tainting irrelevant */
- sv_setpv(PL_statname, SvPV_nomg_const_nolen(sv));
+ temp = SvPV_nomg_const(sv, len);
+ sv_setpv(PL_statname, temp);
PL_statgv = NULL;
PL_laststype = PL_op->op_type;
file = SvPV_nolen_const(PL_statname);
- if (PL_op->op_type == OP_LSTAT)
+ if (!IS_SAFE_PATHNAME(temp, len, OP_NAME(PL_op))) {
+ PL_laststatval = -1;
+ }
+ else if (PL_op->op_type == OP_LSTAT)
PL_laststatval = PerlLIO_lstat(file, &PL_statcache);
else
PL_laststatval = PerlLIO_stat(file, &PL_statcache);
if (PL_laststatval < 0) {
if (ckWARN(WARN_NEWLINE) && should_warn_nl(file)) {
/* PL_warn_nl is constant */
- GCC_DIAG_IGNORE(-Wformat-nonliteral);
+ GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
- GCC_DIAG_RESTORE;
+ GCC_DIAG_RESTORE_STMT;
}
max = 0;
}
EXTEND(SP, max);
EXTEND_MORTAL(max);
mPUSHi(PL_statcache.st_dev);
-#if ST_INO_SIZE > IVSIZE
- mPUSHn(PL_statcache.st_ino);
-#else
-# if ST_INO_SIGN <= 0
- mPUSHi(PL_statcache.st_ino);
-# else
- mPUSHu(PL_statcache.st_ino);
-# endif
-#endif
+ {
+ /*
+ * We try to represent st_ino as a native IV or UV where
+ * possible, but fall back to a decimal string where
+ * necessary. The code to generate these decimal strings
+ * is quite obtuse, because (a) we're portable to non-POSIX
+ * platforms where st_ino might be signed; (b) we didn't
+ * necessarily detect at Configure time whether st_ino is
+ * signed; (c) we're portable to non-POSIX platforms where
+ * ino_t isn't defined, so have no name for the type of
+ * st_ino; and (d) sprintf() doesn't necessarily support
+ * integers as large as st_ino.
+ */
+ bool neg;
+ Stat_t s;
+ CLANG_DIAG_IGNORE_STMT(-Wtautological-compare);
+ GCC_DIAG_IGNORE_STMT(-Wtype-limits);
+ neg = PL_statcache.st_ino < 0;
+ GCC_DIAG_RESTORE_STMT;
+ CLANG_DIAG_RESTORE_STMT;
+ if (neg) {
+ s.st_ino = (IV)PL_statcache.st_ino;
+ if (LIKELY(s.st_ino == PL_statcache.st_ino)) {
+ mPUSHi(s.st_ino);
+ } else {
+ char buf[sizeof(s.st_ino)*3+1], *p;
+ s.st_ino = PL_statcache.st_ino;
+ for (p = buf + sizeof(buf); p != buf+1; ) {
+ Stat_t t;
+ t.st_ino = s.st_ino / 10;
+ *--p = '0' + (int)(t.st_ino*10 - s.st_ino);
+ s.st_ino = t.st_ino;
+ }
+ while (*p == '0')
+ p++;
+ *--p = '-';
+ mPUSHp(p, buf+sizeof(buf) - p);
+ }
+ } else {
+ s.st_ino = (UV)PL_statcache.st_ino;
+ if (LIKELY(s.st_ino == PL_statcache.st_ino)) {
+ mPUSHu(s.st_ino);
+ } else {
+ char buf[sizeof(s.st_ino)*3], *p;
+ s.st_ino = PL_statcache.st_ino;
+ for (p = buf + sizeof(buf); p != buf; ) {
+ Stat_t t;
+ t.st_ino = s.st_ino / 10;
+ *--p = '0' + (int)(s.st_ino - t.st_ino*10);
+ s.st_ino = t.st_ino;
+ }
+ while (*p == '0')
+ p++;
+ mPUSHp(p, buf+sizeof(buf) - p);
+ }
+ }
+ }
mPUSHu(PL_statcache.st_mode);
mPUSHu(PL_statcache.st_nlink);
PUTBACK;
if (PL_op->op_private & OPpFT_STACKING) {
- while (OP_IS_FILETEST(next->op_type)
+ while (next && OP_IS_FILETEST(next->op_type)
&& next->op_private & OPpFT_STACKED)
next = next->op_next;
}
SV *const arg = *PL_stack_sp;
assert(chr != '?');
- if (!(PL_op->op_private & OPpFT_STACKING)) SvGETMAGIC(arg);
+ if (!(PL_op->op_private & OPpFT_STACKED)) SvGETMAGIC(arg);
if (SvAMAGIC(arg))
{
if (use_access) {
#if defined(HAS_ACCESS) || defined (PERL_EFF_ACCESS)
- const char *name = SvPV_nolen(*PL_stack_sp);
- if (effective) {
+ STRLEN len;
+ const char *name = SvPV(*PL_stack_sp, len);
+ if (!IS_SAFE_PATHNAME(name, len, OP_NAME(PL_op))) {
+ result = -1;
+ }
+ else if (effective) {
# ifdef PERL_EFF_ACCESS
result = PERL_EFF_ACCESS(name, access_mode);
# else
break;
}
SvSETMAGIC(TARG);
- return SvTRUE_nomg(TARG)
+ return SvTRUE_nomg_NN(TARG)
? S_ft_return_true(aTHX_ TARG) : S_ft_return_false(aTHX_ TARG);
}
}
}
tryAMAGICftest_MG(opchar);
- /* I believe that all these three are likely to be defined on most every
- system these days. */
-#ifndef S_ISUID
- if(PL_op->op_type == OP_FTSUID) {
- FT_RETURNNO;
- }
-#endif
-#ifndef S_ISGID
- if(PL_op->op_type == OP_FTSGID) {
- FT_RETURNNO;
- }
-#endif
-#ifndef S_ISVTX
- if(PL_op->op_type == OP_FTSVTX) {
- FT_RETURNNO;
- }
-#endif
-
result = my_stat_flags(0);
if (result < 0)
FT_RETURNUNDEF;
else if (name && isDIGIT(*name) && grok_atoUV(name, &uv, NULL) && uv <= PERL_INT_MAX)
fd = (int)uv;
else
- FT_RETURNUNDEF;
+ fd = -1;
if (fd < 0) {
SETERRNO(EBADF,RMS_IFI);
FT_RETURNUNDEF;
SV *sv = NULL;
GV *gv;
PerlIO *fp;
+ const U8 * first_variant;
tryAMAGICftest_MG(PL_op->op_type == OP_FTTEXT ? 'T' : 'B');
}
else {
PL_statgv = gv;
- sv_setpvs(PL_statname, "");
+ SvPVCLEAR(PL_statname);
io = GvIO(PL_statgv);
}
PL_laststatval = -1;
}
else {
const char *file;
+ const char *temp;
+ STRLEN temp_len;
int fd;
assert(sv);
- sv_setpv(PL_statname, SvPV_nomg_const_nolen(sv));
+ temp = SvPV_nomg_const(sv, temp_len);
+ sv_setpv(PL_statname, temp);
+ if (!IS_SAFE_PATHNAME(temp, temp_len, OP_NAME(PL_op))) {
+ PL_laststatval = -1;
+ PL_laststype = OP_STAT;
+ FT_RETURNUNDEF;
+ }
really_filename:
file = SvPVX_const(PL_statname);
PL_statgv = NULL;
}
if (ckWARN(WARN_NEWLINE) && should_warn_nl(file)) {
/* PL_warn_nl is constant */
- GCC_DIAG_IGNORE(-Wformat-nonliteral);
+ GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
- GCC_DIAG_RESTORE;
+ GCC_DIAG_RESTORE_STMT;
}
FT_RETURNUNDEF;
}
}
PL_laststatval = PerlLIO_fstat(fd, &PL_statcache);
if (PL_laststatval < 0) {
+ dSAVE_ERRNO;
(void)PerlIO_close(fp);
- SETERRNO(EBADF,RMS_IFI);
+ RESTORE_ERRNO;
FT_RETURNUNDEF;
}
PerlIO_binmode(aTHX_ fp, '<', O_BINARY, NULL);
#endif
assert(len);
- if (! is_invariant_string((U8 *) s, len)) {
- const U8 *ep;
+ if (! is_utf8_invariant_string_loc((U8 *) s, len, &first_variant)) {
/* Here contains a variant under UTF-8 . See if the entire string is
- * UTF-8. But the buffer may end in a partial character, so consider
- * it UTF-8 if the first non-UTF8 char is an ending partial */
- if (is_utf8_string_loc((U8 *) s, len, &ep)
- || ep + UTF8SKIP(ep) > (U8 *) (s + len))
+ * UTF-8. */
+ if (is_utf8_fixed_width_buf_flags(first_variant,
+ len - ((char *) first_variant - (char *) s),
+ 0))
{
if (PL_op->op_type == OP_FTTEXT) {
FT_RETURNYES;
}
else
#endif
- if (isPRINT_A(*s)
- /* VT occurs so rarely in text, that we consider it odd */
- || (isSPACE_A(*s) && *s != VT_NATIVE)
+ if ( isPRINT_A(*s)
+ /* VT occurs so rarely in text, that we consider it odd */
+ || (isSPACE_A(*s) && *s != VT_NATIVE)
/* But there is a fair amount of backspaces and escapes in
* some text */
- || *s == '\b'
- || *s == ESC_NATIVE)
+ || *s == '\b'
+ || *s == ESC_NATIVE)
{
continue;
}
"chdir() on unopened filehandle %" SVf, sv);
}
SETERRNO(EBADF,RMS_IFI);
- PUSHi(0);
+ PUSHs(&PL_sv_zero);
TAINT_PROPER("chdir");
RETURN;
}
HV * const table = GvHVn(PL_envgv);
SV **svp;
+ EXTEND(SP, 1);
if ( (svp = hv_fetchs(table, "HOME", FALSE))
|| (svp = hv_fetchs(table, "LOGDIR", FALSE))
#ifdef VMS
tmps = SvPV_nolen_const(*svp);
}
else {
- PUSHi(0);
+ PUSHs(&PL_sv_zero);
SETERRNO(EINVAL, LIB_INVARG);
TAINT_PROPER("chdir");
RETURN;
nuts:
report_evil_fh(gv);
SETERRNO(EBADF,RMS_IFI);
- PUSHi(0);
+ PUSHs(&PL_sv_zero);
RETURN;
#endif
}
const char * const tmps = SvPV_nolen_const(TOPs);
TAINT_PROPER(PL_op_desc[op_type]);
result =
-# if defined(HAS_LINK)
-# if defined(HAS_SYMLINK)
+# if defined(HAS_LINK) && defined(HAS_SYMLINK)
/* Both present - need to choose which. */
(op_type == OP_LINK) ?
PerlLIO_link(tmps, tmps2) : symlink(tmps, tmps2);
-# else
+# elif defined(HAS_LINK)
/* Only have link, so calls to pp_symlink will have DIE()d above. */
PerlLIO_link(tmps, tmps2);
-# endif
-# else
-# if defined(HAS_SYMLINK)
+# elif defined(HAS_SYMLINK)
/* Only have symlink, so calls to pp_link will have DIE()d above. */
symlink(tmps, tmps2);
-# endif
# endif
}
len = readlink(tmps, buf, sizeof(buf) - 1);
if (len < 0)
RETPUSHUNDEF;
- if (len != -1)
- buf[len] = '\0';
+ buf[len] = '\0';
PUSHp(buf, len);
RETURN;
#else
IO * const io = GvIOn(gv);
if ((IoIFP(io) || IoOFP(io)))
- Perl_ck_warner_d(aTHX_ packWARN2(WARN_IO, WARN_DEPRECATED),
- "Opening filehandle %"HEKf" also as a directory",
- HEKfARG(GvENAME_HEK(gv)) );
+ Perl_croak(aTHX_ "Cannot open %" HEKf " as a dirhandle: it is already open as a filehandle",
+ HEKfARG(GvENAME_HEK(gv)));
if (IoDIRP(io))
PerlDir_close(IoDIRP(io));
if (!(IoDIRP(io) = PerlDir_open(dirname)))
dSP;
SV *sv;
- const I32 gimme = GIMME_V;
+ const U8 gimme = GIMME_V;
GV * const gv = MUTABLE_GV(POPs);
const Direntry_t *dp;
IO * const io = GvIOn(gv);
if (!IoDIRP(io)) {
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "readdir() attempted on invalid dirhandle %"HEKf,
+ "readdir() attempted on invalid dirhandle %" HEKf,
HEKfARG(GvENAME_HEK(gv)));
goto nope;
}
if (!IoDIRP(io)) {
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "telldir() attempted on invalid dirhandle %"HEKf,
+ "telldir() attempted on invalid dirhandle %" HEKf,
HEKfARG(GvENAME_HEK(gv)));
goto nope;
}
if (!IoDIRP(io)) {
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "seekdir() attempted on invalid dirhandle %"HEKf,
+ "seekdir() attempted on invalid dirhandle %" HEKf,
HEKfARG(GvENAME_HEK(gv)));
goto nope;
}
if (!IoDIRP(io)) {
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "rewinddir() attempted on invalid dirhandle %"HEKf,
+ "rewinddir() attempted on invalid dirhandle %" HEKf,
HEKfARG(GvENAME_HEK(gv)));
goto nope;
}
if (!IoDIRP(io)) {
Perl_ck_warner(aTHX_ packWARN(WARN_IO),
- "closedir() attempted on invalid dirhandle %"HEKf,
+ "closedir() attempted on invalid dirhandle %" HEKf,
HEKfARG(GvENAME_HEK(gv)));
goto nope;
}
}
PUSHi(childpid);
RETURN;
-#else
-# if (defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)) || defined(__amigaos4__)
+#elif (defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)) || defined(__amigaos4__)
dSP; dTARGET;
Pid_t childpid;
RETPUSHUNDEF;
PUSHi(childpid);
RETURN;
-# else
+#else
DIE(aTHX_ PL_no_func, "fork");
-# endif
#endif
}
int result;
# endif
+ while (++MARK <= SP) {
+ SV *origsv = *MARK, *copysv;
+ STRLEN len;
+ char *pv;
+ SvGETMAGIC(origsv);
+#if defined(WIN32) || defined(__VMS)
+ /*
+ * Because of a nasty platform-specific variation on the meaning
+ * of arguments to this op, we must preserve numeric arguments
+ * as numeric, not just retain the string value.
+ */
+ if (SvNIOK(origsv) || SvNIOKp(origsv)) {
+ copysv = newSV_type(SVt_PVNV);
+ sv_2mortal(copysv);
+ if (SvPOK(origsv) || SvPOKp(origsv)) {
+ pv = SvPV_nomg(origsv, len);
+ sv_setpvn(copysv, pv, len);
+ SvPOK_off(copysv);
+ }
+ if (SvIOK(origsv) || SvIOKp(origsv))
+ SvIV_set(copysv, SvIVX(origsv));
+ if (SvNOK(origsv) || SvNOKp(origsv))
+ SvNV_set(copysv, SvNVX(origsv));
+ SvFLAGS(copysv) |= SvFLAGS(origsv) &
+ (SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK|
+ SVf_UTF8|SVf_IVisUV);
+ } else
+#endif
+ {
+ pv = SvPV_nomg(origsv, len);
+ copysv = newSVpvn_flags(pv, len,
+ (SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
+ }
+ *MARK = copysv;
+ }
+ MARK = ORIGMARK;
+
if (TAINTING_get) {
TAINT_ENV();
- while (++MARK <= SP) {
- (void)SvPV_nolen_const(*MARK); /* stringify for taint check */
- if (TAINT_get)
- break;
- }
- MARK = ORIGMARK;
TAINT_PROPER("system");
}
PERL_FLUSHALL_FOR_CHILD;
sigset_t newset, oldset;
#endif
- if (PerlProc_pipe(pp) >= 0)
+ if (PerlProc_pipe_cloexec(pp) >= 0)
did_pipes = 1;
#ifdef __amigaos4__
amigaos_fork_set_userdata(aTHX_
(void)rsignal_restore(SIGQUIT, &qhand);
#endif
STATUS_NATIVE_CHILD_SET(result == -1 ? -1 : status);
- do_execfree(); /* free any memory child malloced on fork */
SP = ORIGMARK;
if (did_pipes) {
int errkid;
unsigned n = 0;
- SSize_t n1;
while (n < sizeof(int)) {
- n1 = PerlLIO_read(pp[0],
+ const SSize_t n1 = PerlLIO_read(pp[0],
(void*)(((char*)&errkid)+n),
(sizeof(int)) - n);
if (n1 <= 0)
#ifdef HAS_SIGPROCMASK
sigprocmask(SIG_SETMASK, &oldset, NULL);
#endif
- if (did_pipes) {
+ if (did_pipes)
PerlLIO_close(pp[0]);
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
- if (fcntl(pp[1], F_SETFD, FD_CLOEXEC) < 0)
- RETPUSHUNDEF;
-#endif
- }
if (PL_op->op_flags & OPf_STACKED) {
SV * const really = *++MARK;
value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
result = 0;
if (PL_op->op_flags & OPf_STACKED) {
SV * const really = *++MARK;
-# if defined(WIN32) || defined(OS2) || defined(__SYMBIAN32__) || defined(__VMS)
+# if defined(WIN32) || defined(OS2) || defined(__VMS)
value = (I32)do_aspawn(really, MARK, SP);
# else
value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
# endif
}
else if (SP - MARK != 1) {
-# if defined(WIN32) || defined(OS2) || defined(__SYMBIAN32__) || defined(__VMS)
+# if defined(WIN32) || defined(OS2) || defined(__VMS)
value = (I32)do_aspawn(NULL, MARK, SP);
# else
value = (I32)do_aspawn(NULL, (void **)MARK, (void **)SP);
if (PL_statusvalue == -1) /* hint that value must be returned as is */
result = 1;
STATUS_NATIVE_CHILD_SET(value);
- do_execfree();
SP = ORIGMARK;
XPUSHi(result ? value : STATUS_CURRENT);
#endif /* !FORK or VMS or OS/2 */
#endif
}
+/*
+ * The glibc headers typedef __priority_which_t to an enum under C, but
+ * under C++, it keeps it as int. -Wc++-compat doesn't know this, so we
+ * need to explicitly cast it to shut up the warning.
+ */
#if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || (__GLIBC__ > 2))
# define PRIORITY_WHICH_T(which) (__priority_which_t)which
#else
{
dSP; dTARGET;
#ifdef BIG_TIME
- XPUSHn( time(NULL) );
+ XPUSHn( (NV)time(NULL) );
#else
- XPUSHi( time(NULL) );
+ XPUSHu( (UV)time(NULL) );
#endif
RETURN;
}
mPUSHn(((NV)timesbuf.tms_cstime)/(NV)PL_clocktick);
}
RETURN;
-#else
-# ifdef PERL_MICRO
+#elif defined(PERL_MICRO)
dSP;
mPUSHn(0.0);
EXTEND(SP, 4);
mPUSHn(0.0);
}
RETURN;
-# else
+#else
DIE(aTHX_ "times not implemented");
-# endif
#endif /* HAS_TIMES */
}
else {
dTARGET;
PUSHs(TARG);
- Perl_sv_setpvf_mg(aTHX_ TARG, "%s %s %2d %02d:%02d:%02d %"IVdf,
+ Perl_sv_setpvf_mg(aTHX_ TARG, "%s %s %2d %02d:%02d:%02d %" IVdf,
dayname[tmbuf.tm_wday],
monname[tmbuf.tm_mon],
tmbuf.tm_mday,
PP(pp_sleep)
{
dSP; dTARGET;
- I32 duration;
Time_t lasttime;
Time_t when;
if (MAXARG < 1 || (!TOPs && !POPs))
PerlProc_pause();
else {
- duration = POPi;
+ const I32 duration = POPi;
if (duration < 0) {
/* diag_listed_as: %s() with negative argument */
Perl_ck_warner_d(aTHX_ packWARN(WARN_MISC),
"sleep() with negative argument");
SETERRNO(EINVAL, LIB_INVARG);
- XPUSHi(0);
+ XPUSHs(&PL_sv_zero);
RETURN;
} else {
PerlProc_sleep((unsigned int)duration);
}
}
(void)time(&when);
- XPUSHi(when - lasttime);
+ XPUSHu((UV)(when - lasttime));
RETURN;
}
{
SV *target;
- PERL_ARGS_ASSERT_SPACE_JOIN_NAMES_MORTAL;
-
- if (*array) {
+ if (array && *array) {
target = newSVpvs_flags("", SVs_TEMP);
while (1) {
sv_catpv(target, *array);
DIE(aTHX_ PL_no_sock_func, PL_op_desc[PL_op->op_type]);
#endif
break;
-#ifdef HAS_SETNETENT
case OP_SNETENT:
+#ifdef HAS_SETNETENT
PerlSock_setnetent(stayopen);
#else
DIE(aTHX_ PL_no_sock_func, PL_op_desc[PL_op->op_type]);
* it is only included in special cases.
*
* In Digital UNIX/Tru64 if using the getespw*() (which seems to be
- * be preferred interface, even though also the getprpw*() interface
+ * the preferred interface, even though also the getprpw*() interface
* is available) one needs to link with -lsecurity -ldb -laud -lm.
* One also needs to call set_auth_parameters() in main() before
* doing anything else, whether one is using getespw*() or getprpw*().
* but we are accursed by our history, alas. --jhi. */
# ifdef PWCHANGE
mPUSHi(pwent->pw_change);
-# else
-# ifdef PWQUOTA
+# elif defined(PWQUOTA)
mPUSHi(pwent->pw_quota);
-# else
-# ifdef PWAGE
+# elif defined(PWAGE)
mPUSHs(newSVpv(pwent->pw_age, 0));
-# else
+# else
/* I think that you can never get this compiled, but just in case. */
PUSHs(sv_mortalcopy(&PL_sv_no));
-# endif
-# endif
# endif
/* pw_class and pw_comment are mutually exclusive--.
* see the above note for pw_change, pw_quota, and pw_age. */
# ifdef PWCLASS
mPUSHs(newSVpv(pwent->pw_class, 0));
-# else
-# ifdef PWCOMMENT
+# elif defined(PWCOMMENT)
mPUSHs(newSVpv(pwent->pw_comment, 0));
-# else
+# else
/* I think that you can never get this compiled, but just in case. */
PUSHs(sv_mortalcopy(&PL_sv_no));
-# endif
# endif
# ifdef PWGECOS