[perl #35847] File::Find not performing as documented
[p5sagit/p5-mst-13.2.git] / doio.c
diff --git a/doio.c b/doio.c
index 21bf98c..be67c6e 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;
@@ -1572,6 +1572,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); }                         \
@@ -1766,12 +1779,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
@@ -1793,7 +1809,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 +1825,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 *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 +1872,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 +1927,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. */