#include <signal.h>
bool
-Perl_do_open(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
- int rawmode, int rawperm, PerlIO *supplied_fp)
-{
- return do_openn(gv, name, len, as_raw, rawmode, rawperm,
- supplied_fp, (SV **) NULL, 0);
-}
-
-bool
-Perl_do_open9(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
- int rawmode, int rawperm, PerlIO *supplied_fp, SV *svs,
- I32 num_svs)
-{
- PERL_UNUSED_ARG(num_svs);
- return do_openn(gv, name, len, as_raw, rawmode, rawperm,
- supplied_fp, &svs, 1);
-}
-
-bool
-Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
+Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
int rawmode, int rawperm, PerlIO *supplied_fp, SV **svp,
I32 num_svs)
{
IoTYPE(io) = PerlIO_intmode2str(rawmode, &mode[ix], &writing);
- namesv = sv_2mortal(newSVpvn(name,strlen(name)));
+ namesv = sv_2mortal(newSVpv(oname,0));
num_svs = 1;
svp = &namesv;
type = Nullch;
}
else {
/* Regular (non-sys) open */
- char *oname = name;
+ char *name;
STRLEN olen = len;
char *tend;
int dodup = 0;
PerlIO *that_fp = NULL;
- type = savepvn(name, len);
+ type = savepvn(oname, len);
tend = type+len;
SAVEFREEPV(type);
if (num_svs) {
/* New style explicit name, type is just mode and layer info */
#ifdef USE_STDIO
- if (SvROK(*svp) && !strchr(name,'&')) {
+ if (SvROK(*svp) && !strchr(oname,'&')) {
if (ckWARN(WARN_IO))
Perl_warner(aTHX_ packWARN(WARN_IO),
"Can't open a reference");
#ifdef USE_SFIO
/* sfio fails to clear error on next
sfwrite, contrary to documentation.
- -- Nick Clark */
+ -- Nicholas Clark */
if (PerlIO_seek(that_fp, 0, SEEK_CUR) == -1)
PerlIO_clearerr(that_fp);
#endif
else
was_fdopen = TRUE;
if (!(fp = PerlIO_openn(aTHX_ type,mode,fd,0,0,NULL,num_svs,svp))) {
- if (dodup)
+ if (dodup && fd >= 0)
PerlLIO_close(fd);
}
}
}
else {
if (!num_svs) {
- namesv = sv_2mortal(newSVpvn(type,strlen(type)));
+ namesv = sv_2mortal(newSVpvn(type,tend - type));
num_svs = 1;
svp = &namesv;
type = Nullch;
}
else {
if (!num_svs) {
- namesv = sv_2mortal(newSVpvn(type,strlen(type)));
+ namesv = sv_2mortal(newSVpvn(type,tend - type));
num_svs = 1;
svp = &namesv;
type = Nullch;
}
else {
if (!num_svs) {
- namesv = sv_2mortal(newSVpvn(type,strlen(type)));
+ namesv = sv_2mortal(newSVpvn(type,tend - type));
num_svs = 1;
svp = &namesv;
type = Nullch;
}
}
if (!fp) {
- if (IoTYPE(io) == IoTYPE_RDONLY && strchr(name, '\n')
- && ckWARN(WARN_NEWLINE)
+ if (IoTYPE(io) == IoTYPE_RDONLY && ckWARN(WARN_NEWLINE)
+ && strchr(oname, '\n')
+
)
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
goto say_false;
}
#if defined(HAS_FCNTL) && defined(F_SETFD)
if (fd >= 0) {
- int save_errno = errno;
+ const int save_errno = errno;
fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */
errno = save_errno;
}
#endif
Uid_t fileuid;
Gid_t filegid;
- IO *io = GvIOp(gv);
+ IO * const io = GvIOp(gv);
if (!PL_argvoutgv)
PL_argvoutgv = gv_fetchpv("ARGVOUT",TRUE,SVt_PVIO);
continue;
}
if (*PL_inplace) {
- char *star = strchr(PL_inplace, '*');
+ const char *star = strchr(PL_inplace, '*');
if (star) {
- char *begin = PL_inplace;
+ const char *begin = PL_inplace;
sv_setpvn(sv, "", 0);
do {
sv_catpvn(sv, begin, star - begin);
return Nullfp;
}
-#ifdef HAS_PIPE
-void
-Perl_do_pipe(pTHX_ SV *sv, GV *rgv, GV *wgv)
-{
- register IO *rstio;
- register IO *wstio;
- int fd[2];
-
- if (!rgv)
- goto badexit;
- if (!wgv)
- goto badexit;
-
- rstio = GvIOn(rgv);
- wstio = GvIOn(wgv);
-
- if (IoIFP(rstio))
- do_close(rgv,FALSE);
- if (IoIFP(wstio))
- do_close(wgv,FALSE);
-
- if (PerlProc_pipe(fd) < 0)
- goto badexit;
- 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;
- IoTYPE(wstio) = IoTYPE_WRONLY;
- if (!IoIFP(rstio) || !IoOFP(wstio)) {
- if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
- else PerlLIO_close(fd[0]);
- if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
- else PerlLIO_close(fd[1]);
- goto badexit;
- }
-
- sv_setsv(sv,&PL_sv_yes);
- return;
-
-badexit:
- sv_setsv(sv,&PL_sv_undef);
- return;
-}
-#endif
-
/* explicit renamed to avoid C++ conflict -- kja */
bool
Perl_do_close(pTHX_ GV *gv, bool not_implicit)
if (IoTYPE(io) == IoTYPE_PIPE) {
const int status = PerlProc_pclose(IoIFP(io));
if (not_implicit) {
- STATUS_NATIVE_SET(status);
+ STATUS_NATIVE_CHILD_SET(status);
retval = (STATUS_UNIX == 0);
}
else {
retval = TRUE;
else {
if (IoOFP(io) && IoOFP(io) != IoIFP(io)) { /* a socket */
- bool prev_err = PerlIO_error(IoOFP(io));
+ const bool prev_err = PerlIO_error(IoOFP(io));
retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
}
else {
- bool prev_err = PerlIO_error(IoIFP(io));
+ const bool prev_err = PerlIO_error(IoIFP(io));
retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
}
}
bool
Perl_do_eof(pTHX_ GV *gv)
{
- register IO *io;
- int ch;
-
- io = GvIO(gv);
+ register IO * const io = GvIO(gv);
if (!io)
return TRUE;
while (IoIFP(io)) {
int saverrno;
+ int ch;
if (PerlIO_has_cntptr(IoIFP(io))) { /* (the code works without this) */
if (PerlIO_get_cnt(IoIFP(io)) > 0) /* cheat a little, since */
return mode;
}
-int
-Perl_do_binmode(pTHX_ PerlIO *fp, int iotype, int mode)
-{
- /* The old body of this is now in non-LAYER part of perlio.c
- * This is a stub for any XS code which might have been calling it.
- */
- const char *name = ":raw";
-#ifdef PERLIO_USING_CRLF
- if (!(mode & O_BINARY))
- name = ":crlf";
-#endif
- return PerlIO_binmode(aTHX_ fp, iotype, mode, name);
-}
-
#if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE)
I32
my_chsize(int fd, Off_t length)
return TRUE;
case SVt_IV:
if (SvIOK(sv)) {
- if (SvGMAGICAL(sv))
- mg_get(sv);
+ SvGETMAGIC(sv);
if (SvIsUV(sv))
PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
else
return PL_laststatval;
}
else {
- SV* sv = POPs;
+ SV* const sv = POPs;
const char *s;
STRLEN len;
PUTBACK;
s = SvPVX_const(PL_statname); /* s now NUL-terminated */
PL_laststype = OP_STAT;
PL_laststatval = PerlLIO_stat(s, &PL_statcache);
- if (PL_laststatval < 0 && strchr(s, '\n') && ckWARN(WARN_NEWLINE))
+ if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n'))
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
return PL_laststatval;
}
return PL_laststatval;
}
-#ifndef OS2
-bool
-Perl_do_aexec(pTHX_ SV *really, register SV **mark, register SV **sp)
-{
- return do_aexec5(really, mark, sp, 0, 0);
-}
-#endif
-
bool
Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
int fd, int do_report)
{
dVAR;
-#if defined(MACOS_TRADITIONAL) || defined(SYMBIAN)
+#if defined(MACOS_TRADITIONAL) || defined(__SYMBIAN32__)
Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
#else
if (sp > mark) {
PL_Cmd = Nullch;
}
-#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(SYMBIAN) && !defined(MACOS_TRADITIONAL)
+#ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
bool
-Perl_do_exec(pTHX_ char *cmd)
-{
- return do_exec3(cmd,0,0);
-}
-
-bool
-Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
+Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
{
dVAR;
register char **a;
register char *s;
+ char *cmd;
+
+ /* Make a copy so we can change it */
+ const int cmdlen = strlen(incmd);
+ Newx(cmd, cmdlen+1, char);
+ strncpy(cmd, incmd, cmdlen);
+ cmd[cmdlen] = 0;
while (*cmd && isSPACE(*cmd))
cmd++;
if (*s == ' ')
s++;
if (*s++ == '\'') {
- char *ncmd = s;
+ char * const ncmd = s;
while (*s)
s++;
PerlProc_execl(PL_cshname,"csh", flags, ncmd, (char*)0);
PERL_FPU_POST_EXEC
*s = '\'';
+ Safefree(cmd);
return FALSE;
}
}
PERL_FPU_PRE_EXEC
PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
PERL_FPU_POST_EXEC
+ Safefree(cmd);
return FALSE;
}
}
}
}
do_execfree();
+ Safefree(cmd);
return FALSE;
}
const char *s;
SV ** const oldmark = mark;
+ /* Doing this ahead of the switch statement preserves the old behaviour,
+ where attempting to use kill as a taint test test would fail on
+ platforms where kill was not defined. */
+#ifndef HAS_KILL
+ if (type == OP_KILL)
+ Perl_die(aTHX_ PL_no_func, "kill");
+#endif
+#ifndef HAS_CHOWN
+ if (type == OP_CHOWN)
+ Perl_die(aTHX_ PL_no_func, "chown");
+#endif
+
+
#define APPLY_TAINT_PROPER() \
STMT_START { \
if (PL_tainted) { TAINT_PROPER(what); } \
APPLY_TAINT_PROPER();
tot = sp - mark;
while (++mark <= sp) {
- const char *name = SvPV_nolen_const(*mark);
- APPLY_TAINT_PROPER();
- if (PerlLIO_chmod(name, val))
- tot--;
+ GV* gv;
+ if (SvTYPE(*mark) == SVt_PVGV) {
+ gv = (GV*)*mark;
+ do_fchmod:
+ if (GvIO(gv) && IoIFP(GvIOp(gv))) {
+#ifdef HAS_FCHMOD
+ APPLY_TAINT_PROPER();
+ if (fchmod(PerlIO_fileno(IoIFP(GvIOn(gv))), val))
+ tot--;
+#else
+ Perl_die(aTHX_ PL_no_func, "fchmod");
+#endif
+ }
+ else {
+ tot--;
+ }
+ }
+ else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+ gv = (GV*)SvRV(*mark);
+ goto do_fchmod;
+ }
+ else {
+ const char *name = SvPV_nolen_const(*mark);
+ APPLY_TAINT_PROPER();
+ if (PerlLIO_chmod(name, val))
+ tot--;
+ }
}
}
break;
APPLY_TAINT_PROPER();
tot = sp - mark;
while (++mark <= sp) {
- const char *name = SvPV_nolen_const(*mark);
- APPLY_TAINT_PROPER();
- if (PerlLIO_chown(name, val, val2))
- tot--;
+ GV* gv;
+ if (SvTYPE(*mark) == SVt_PVGV) {
+ gv = (GV*)*mark;
+ do_fchown:
+ if (GvIO(gv) && IoIFP(GvIOp(gv))) {
+#ifdef HAS_FCHOWN
+ APPLY_TAINT_PROPER();
+ if (fchown(PerlIO_fileno(IoIFP(GvIOn(gv))), val, val2))
+ tot--;
+#else
+ Perl_die(aTHX_ PL_no_func, "fchown");
+#endif
+ }
+ else {
+ tot--;
+ }
+ }
+ else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+ gv = (GV*)SvRV(*mark);
+ goto do_fchown;
+ }
+ else {
+ const char *name = SvPV_nolen_const(*mark);
+ APPLY_TAINT_PROPER();
+ if (PerlLIO_chown(name, val, val2))
+ tot--;
+ }
}
}
break;
if (val < 0) {
val = -val;
while (++mark <= sp) {
- I32 proc = SvIVx(*mark);
+ const I32 proc = SvIVx(*mark);
APPLY_TAINT_PROPER();
#ifdef HAS_KILLPG
if (PerlProc_killpg(proc,val)) /* BSD */
}
else {
while (++mark <= sp) {
- I32 proc = SvIVx(*mark);
+ const I32 proc = SvIVx(*mark);
APPLY_TAINT_PROPER();
if (PerlProc_kill(proc, val))
tot--;
}
}
break;
-#ifdef HAS_UTIME
+#if defined(HAS_UTIME) || defined(HAS_FUTIMES)
case OP_UTIME:
what = "utime";
APPLY_TAINT_PROPER();
if (sp - mark > 2) {
-#if defined(I_UTIME) || defined(VMS)
+#if defined(HAS_FUTIMES)
+ struct timeval utbuf[2];
+ void *utbufp = utbuf;
+#elif defined(I_UTIME) || defined(VMS)
struct utimbuf utbuf;
struct utimbuf *utbufp = &utbuf;
#else
void *utbufp = &utbuf;
#endif
- SV* accessed = *++mark;
- SV* modified = *++mark;
+ SV* const accessed = *++mark;
+ SV* const modified = *++mark;
/* Be like C, and if both times are undefined, let the C
* library figure out what to do. This usually means
utbufp = NULL;
else {
Zero(&utbuf, sizeof utbuf, char);
-#ifdef BIG_TIME
+#ifdef HAS_FUTIMES
+ utbuf[0].tv_sec = (long)SvIVx(accessed); /* time accessed */
+ utbuf[0].tv_usec = 0;
+ utbuf[1].tv_sec = (long)SvIVx(modified); /* time modified */
+ utbuf[1].tv_usec = 0;
+#elif defined(BIG_TIME)
utbuf.actime = (Time_t)SvNVx(accessed); /* time accessed */
utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
#else
APPLY_TAINT_PROPER();
tot = sp - mark;
while (++mark <= sp) {
- char *name = SvPV_nolen(*mark);
- APPLY_TAINT_PROPER();
- if (PerlLIO_utime(name, utbufp))
- tot--;
+ GV* gv;
+ if (SvTYPE(*mark) == SVt_PVGV) {
+ gv = (GV*)*mark;
+ do_futimes:
+ if (GvIO(gv) && IoIFP(GvIOp(gv))) {
+#ifdef HAS_FUTIMES
+ APPLY_TAINT_PROPER();
+ if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))), utbufp))
+ tot--;
+#else
+ Perl_die(aTHX_ PL_no_func, "futimes");
+#endif
+ }
+ else {
+ tot--;
+ }
+ }
+ else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+ gv = (GV*)SvRV(*mark);
+ goto do_futimes;
+ }
+ else {
+ const char * const name = SvPV_nolen_const(*mark);
+ APPLY_TAINT_PROPER();
+#ifdef HAS_FUTIMES
+ if (utimes(name, utbufp))
+#else
+ if (PerlLIO_utime(name, utbufp))
+#endif
+ tot--;
+ }
+
}
}
else
/* Do the permissions allow some operation? Assumes statcache already set. */
#ifndef VMS /* VMS' cando is in vms.c */
bool
-Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register const Stat_t *statbufp)
-/* Note: we use "effective" both for uids and gids.
- * Here we are betting on Uid_t being equal or wider than Gid_t. */
+Perl_cando(pTHX_ Mode_t mode, bool effective, register const Stat_t *statbufp)
+/* effective is a flag, true for EUID, or for checking if the effective gid
+ * is in the list of groups returned from getgroups().
+ */
{
#ifdef DOSISH
/* [Comments and code from Len Reed]
#endif /* ! VMS */
bool
-Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
+Perl_ingroup(pTHX_ Gid_t testgid, bool effective)
{
#ifdef MACOS_TRADITIONAL
/* This is simply not correct for AppleShare, but fix it yerself. */
I32
Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
{
- key_t key = (key_t)SvNVx(*++mark);
+ const key_t key = (key_t)SvNVx(*++mark);
const I32 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
const I32 flags = SvIVx(*++mark);
(void)sp;
I32
Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
{
- SV *astr;
char *a;
- STRLEN infosize;
- I32 getinfo;
I32 ret = -1;
const I32 id = SvIVx(*++mark);
const I32 n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
const I32 cmd = SvIVx(*++mark);
- PERL_UNUSED_ARG(sp);
+ SV * const astr = *++mark;
+ STRLEN infosize = 0;
+ I32 getinfo = (cmd == IPC_STAT);
- astr = *++mark;
- infosize = 0;
- getinfo = (cmd == IPC_STAT);
+ PERL_UNUSED_ARG(sp);
switch (optype)
{
}
else
{
- IV i = SvIV(astr);
+ const IV i = SvIV(astr);
a = INT2PTR(char *,i); /* ouch */
}
SETERRNO(0,0);
Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
{
#ifdef HAS_MSG
- SV *mstr;
- const char *mbuf;
- I32 msize, flags;
STRLEN len;
const I32 id = SvIVx(*++mark);
+ SV * const mstr = *++mark;
+ const I32 flags = SvIVx(*++mark);
+ const char * const mbuf = SvPV_const(mstr, len);
+ const I32 msize = len - sizeof(long);
+
PERL_UNUSED_ARG(sp);
- mstr = *++mark;
- flags = SvIVx(*++mark);
- mbuf = SvPV_const(mstr, len);
- if ((msize = len - sizeof(long)) < 0)
+ if (msize < 0)
Perl_croak(aTHX_ "Arg too short for msgsnd");
SETERRNO(0,0);
return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
{
#ifdef HAS_MSG
- SV *mstr;
char *mbuf;
long mtype;
I32 msize, flags, ret;
const I32 id = SvIVx(*++mark);
+ SV * const mstr = *++mark;
PERL_UNUSED_ARG(sp);
- mstr = *++mark;
/* suppress warning when reading into undef var --jhi */
if (! SvOK(mstr))
sv_setpvn(mstr, "", 0);
Perl_do_semop(pTHX_ SV **mark, SV **sp)
{
#ifdef HAS_SEM
- SV *opstr;
- const char *opbuf;
STRLEN opsize;
const I32 id = SvIVx(*++mark);
+ SV * const opstr = *++mark;
+ const char * const opbuf = SvPV_const(opstr, opsize);
PERL_UNUSED_ARG(sp);
- opstr = *++mark;
- opbuf = SvPV_const(opstr, opsize);
if (opsize < 3 * SHORTSIZE
|| (opsize % (3 * SHORTSIZE))) {
SETERRNO(EINVAL,LIB_INVARG);
{
const int nsops = opsize / (3 * sizeof (short));
int i = nsops;
- short *ops = (short *) opbuf;
+ short * const ops = (short *) opbuf;
short *o = ops;
struct sembuf *temps, *t;
I32 result;
Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
{
#ifdef HAS_SHM
- SV *mstr;
char *shm;
- I32 mpos, msize;
struct shmid_ds shmds;
const I32 id = SvIVx(*++mark);
+ SV * const mstr = *++mark;
+ const I32 mpos = SvIVx(*++mark);
+ const I32 msize = SvIVx(*++mark);
PERL_UNUSED_ARG(sp);
- mstr = *++mark;
- mpos = SvIVx(*++mark);
- msize = SvIVx(*++mark);
SETERRNO(0,0);
if (shmctl(id, IPC_STAT, &shmds) == -1)
return -1;
Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
{
dVAR;
- SV *tmpcmd = NEWSV(55, 0);
+ SV * const tmpcmd = NEWSV(55, 0);
PerlIO *fp;
ENTER;
SAVEFREESV(tmpcmd);