[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 4f30a59..be67c6e 100644 (file)
--- a/doio.c
+++ b/doio.c
 #include <signal.h>
 
 bool
-Perl_do_open(pTHX_ GV *gv, register const 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 const 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 const char *oname, I32 len, int as_raw,
              int rawmode, int rawperm, PerlIO *supplied_fp, SV **svp,
              I32 num_svs)
@@ -194,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;
@@ -372,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 +390,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                        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);
                        }
                    }
@@ -426,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;
@@ -464,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;
@@ -556,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;
@@ -955,52 +937,6 @@ Perl_nextargv(pTHX_ register GV *gv)
     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)
@@ -1043,7 +979,7 @@ Perl_io_close(pTHX_ IO *io, 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 {
@@ -1224,20 +1160,6 @@ fail_discipline:
     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)
@@ -1441,20 +1363,12 @@ Perl_my_lstat(pTHX)
     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) {
@@ -1505,13 +1419,7 @@ Perl_do_execfree(pTHX)
     PL_Cmd = Nullch;
 }
 
-#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(SYMBIAN) && !defined(MACOS_TRADITIONAL)
-
-bool
-Perl_do_exec(pTHX_ const char *cmd)
-{
-    return do_exec3(cmd,0,0);
-}
+#ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
 
 bool
 Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
@@ -1664,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); }                         \
@@ -1858,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
@@ -1885,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
@@ -1896,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
@@ -1915,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]
@@ -1969,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. */