Const & local: Special Victims Unit
[p5sagit/p5-mst-13.2.git] / doio.c
diff --git a/doio.c b/doio.c
index 21bf98c..e1ddfcb 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -176,7 +176,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
 
         IoTYPE(io) = PerlIO_intmode2str(rawmode, &mode[ix], &writing);
 
-       namesv = sv_2mortal(newSVpvn(oname,strlen(oname)));
+       namesv = sv_2mortal(newSVpv(oname,0));
        num_svs = 1;
        svp = &namesv;
         type = Nullch;
@@ -354,7 +354,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
 #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
@@ -408,7 +408,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                }
                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;
@@ -446,7 +446,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            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;
@@ -538,7 +538,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            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;
@@ -686,7 +686,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
     }
 #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;
     }
@@ -990,12 +990,12 @@ Perl_io_close(pTHX_ IO *io, bool not_implicit)
            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);
            }
        }
@@ -1011,10 +1011,7 @@ Perl_io_close(pTHX_ IO *io, bool not_implicit)
 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;
@@ -1023,6 +1020,7 @@ Perl_do_eof(pTHX_ GV *gv)
 
     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 */
@@ -1297,7 +1295,7 @@ Perl_my_stat(pTHX)
        return PL_laststatval;
     }
     else {
-       SV* sv = POPs;
+       SV* const sv = POPs;
        const char *s;
        STRLEN len;
        PUTBACK;
@@ -1428,10 +1426,9 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
     register char **a;
     register char *s;
     char *cmd;
-    int cmdlen;
 
     /* Make a copy so we can change it */
-    cmdlen = strlen(incmd);
+    const int cmdlen = strlen(incmd);
     Newx(cmd, cmdlen+1, char);
     strncpy(cmd, incmd, cmdlen);
     cmd[cmdlen] = 0;
@@ -1463,7 +1460,7 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
          if (*s == ' ')
              s++;
          if (*s++ == '\'') {
-             char *ncmd = s;
+             char * const ncmd = s;
 
              while (*s)
                  s++;
@@ -1572,6 +1569,19 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
     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); }                         \
@@ -1725,7 +1735,7 @@ nothing in the core.
        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 */
@@ -1737,7 +1747,7 @@ nothing in the core.
        }
        else {
            while (++mark <= sp) {
-               I32 proc = SvIVx(*mark);
+               const I32 proc = SvIVx(*mark);
                APPLY_TAINT_PROPER();
                if (PerlProc_kill(proc, val))
                    tot--;
@@ -1766,12 +1776,15 @@ nothing in the core.
            }
        }
        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
@@ -1782,8 +1795,8 @@ nothing in the core.
            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
@@ -1793,7 +1806,12 @@ nothing in the core.
                 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
@@ -1804,10 +1822,38 @@ nothing in the core.
            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
@@ -1823,9 +1869,10 @@ nothing in the core.
 /* 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]
@@ -1877,7 +1924,7 @@ Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register const Stat_t *statbufp)
 #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. */
@@ -1908,7 +1955,7 @@ Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
 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;
@@ -1939,19 +1986,16 @@ Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **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)
     {
@@ -2019,7 +2063,7 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
     }
     else
     {
-       IV i = SvIV(astr);
+       const IV i = SvIV(astr);
        a = INT2PTR(char *,i);          /* ouch */
     }
     SETERRNO(0,0);
@@ -2065,17 +2109,16 @@ I32
 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);
@@ -2088,14 +2131,13 @@ I32
 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);
@@ -2125,14 +2167,12 @@ I32
 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);
@@ -2143,7 +2183,7 @@ Perl_do_semop(pTHX_ SV **mark, SV **sp)
     {
         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;
@@ -2178,16 +2218,14 @@ I32
 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;