Upgrade to Test-Simple-0.70
[p5sagit/p5-mst-13.2.git] / doio.c
diff --git a/doio.c b/doio.c
index f5f59a3..e1acc67 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -1,7 +1,7 @@
 /*    doio.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -258,17 +258,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            mode[0] = 'w';
            writing = 1;
-#ifdef HAS_STRLCAT
             if (out_raw)
-                strlcat(mode, "b", PERL_MODE_MAX - 1);
+                my_strlcat(mode, "b", PERL_MODE_MAX - 1);
             else if (out_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX - 1); 
-#else
-           if (out_raw)
-               strcat(mode, "b");
-           else if (out_crlf)
-               strcat(mode, "t");
-#endif
+                my_strlcat(mode, "t", PERL_MODE_MAX - 1); 
            if (num_svs > 1) {
                fp = PerlProc_popen_list(mode, num_svs, svp);
            }
@@ -296,17 +289,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            writing = 1;
 
-#ifdef HAS_STRLCAT
             if (out_raw)
-                strlcat(mode, "b", PERL_MODE_MAX - 1);
+                my_strlcat(mode, "b", PERL_MODE_MAX - 1);
             else if (out_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX - 1);
-#else
-           if (out_raw)
-               strcat(mode, "b");
-           else if (out_crlf)
-               strcat(mode, "t");
-#endif
+                my_strlcat(mode, "t", PERL_MODE_MAX - 1);
            if (*type == '&') {
              duplicity:
                dodup = PERLIO_DUP_FD;
@@ -429,17 +415,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                type++;
            } while (isSPACE(*type));
            mode[0] = 'r';
-#ifdef HAS_STRLCAT
             if (in_raw)
-                strlcat(mode, "b", PERL_MODE_MAX - 1);
+                my_strlcat(mode, "b", PERL_MODE_MAX - 1);
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX - 1);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+                my_strlcat(mode, "t", PERL_MODE_MAX - 1);
            if (*type == '&') {
                goto duplicity;
            }
@@ -490,17 +469,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            TAINT_PROPER("piped open");
            mode[0] = 'r';
 
-#ifdef HAS_STRLCAT
             if (in_raw)
-                strlcat(mode, "b", PERL_MODE_MAX - 1);
+                my_strlcat(mode, "b", PERL_MODE_MAX - 1);
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX - 1);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+                my_strlcat(mode, "t", PERL_MODE_MAX - 1);
 
            if (num_svs > 1) {
                fp = PerlProc_popen_list(mode,num_svs,svp);
@@ -528,17 +500,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                ;
            mode[0] = 'r';
 
-#ifdef HAS_STRLCAT
             if (in_raw)
-                strlcat(mode, "b", PERL_MODE_MAX - 1);
+                my_strlcat(mode, "b", PERL_MODE_MAX - 1);
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX - 1);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+                my_strlcat(mode, "t", PERL_MODE_MAX - 1);
 
            if (*name == '-' && name[1] == '\0') {
                fp = PerlIO_stdin();
@@ -745,10 +710,9 @@ Perl_nextargv(pTHX_ register GV *gv)
     if (io && (IoFLAGS(io) & IOf_ARGV) && (IoFLAGS(io) & IOf_START)) {
        IoFLAGS(io) &= ~IOf_START;
        if (PL_inplace) {
-           if (!PL_argvout_stack)
-               PL_argvout_stack = newAV();
            assert(PL_defoutgv);
-           av_push(PL_argvout_stack, SvREFCNT_inc_simple_NN(PL_defoutgv));
+           Perl_av_create_and_push(aTHX_ &PL_argvout_stack,
+                                   SvREFCNT_inc_simple_NN(PL_defoutgv));
        }
     }
     if (PL_filemode & (S_ISUID|S_ISGID)) {
@@ -822,7 +786,7 @@ Perl_nextargv(pTHX_ register GV *gv)
                        if (ckWARN_d(WARN_INPLACE))     
                            Perl_warner(aTHX_ packWARN(WARN_INPLACE),
                              "Can't do inplace edit: %"SVf" would not be unique",
-                             sv);
+                             SVfARG(sv));
                        do_close(gv,FALSE);
                        continue;
                    }
@@ -833,7 +797,7 @@ Perl_nextargv(pTHX_ register GV *gv)
                        if (ckWARN_d(WARN_INPLACE))     
                            Perl_warner(aTHX_ packWARN(WARN_INPLACE),
                              "Can't rename %s to %"SVf": %s, skipping file",
-                             PL_oldname, (void*)sv, Strerror(errno));
+                             PL_oldname, SVfARG(sv), Strerror(errno));
                        do_close(gv,FALSE);
                        continue;
                    }
@@ -850,7 +814,7 @@ Perl_nextargv(pTHX_ register GV *gv)
                        if (ckWARN_d(WARN_INPLACE))     
                            Perl_warner(aTHX_ packWARN(WARN_INPLACE),
                              "Can't rename %s to %"SVf": %s, skipping file",
-                             PL_oldname, sv, Strerror(errno) );
+                             PL_oldname, SVfARG(sv), Strerror(errno) );
                        do_close(gv,FALSE);
                        continue;
                    }
@@ -1232,32 +1196,24 @@ bool
 Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
 {
     dVAR;
-    register const char *tmps;
-    STRLEN len;
-    U8 *tmpbuf = NULL;
-    bool happy = TRUE;
-
     /* assuming fp is checked earlier */
     if (!sv)
        return TRUE;
-    switch (SvTYPE(sv)) {
-    case SVt_NULL:
-       if (ckWARN(WARN_UNINITIALIZED))
-           report_uninit(sv);
-       return TRUE;
-    case SVt_IV:
-       if (SvIOK(sv)) {
-           assert(!SvGMAGICAL(sv));
-           if (SvIsUV(sv))
-               PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
-           else
-               PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
-           return !PerlIO_error(fp);
-       }
-       /* FALL THROUGH */
-    default:
+    if (SvTYPE(sv) == SVt_IV && SvIOK(sv)) {
+       assert(!SvGMAGICAL(sv));
+       if (SvIsUV(sv))
+           PerlIO_printf(fp, "%"UVuf, (UV)SvUVX(sv));
+       else
+           PerlIO_printf(fp, "%"IVdf, (IV)SvIVX(sv));
+       return !PerlIO_error(fp);
+    }
+    else {
+       STRLEN len;
        /* Do this first to trigger any overloading.  */
-       tmps = SvPV_const(sv, len);
+       const char *tmps = SvPV_const(sv, len);
+       U8 *tmpbuf = NULL;
+       bool happy = TRUE;
+
        if (PerlIO_isutf8(fp)) {
            if (!SvUTF8(sv)) {
                /* We don't modify the original scalar.  */
@@ -1282,18 +1238,17 @@ Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
                }
            }
        }
-       break;
+       /* To detect whether the process is about to overstep its
+        * filesize limit we would need getrlimit().  We could then
+        * also transparently raise the limit with setrlimit() --
+        * but only until the system hard limit/the filesystem limit,
+        * at which we would get EPERM.  Note that when using buffered
+        * io the write failure can be delayed until the flush/close. --jhi */
+       if (len && (PerlIO_write(fp,tmps,len) == 0))
+           happy = FALSE;
+       Safefree(tmpbuf);
+       return happy ? !PerlIO_error(fp) : FALSE;
     }
-    /* To detect whether the process is about to overstep its
-     * filesize limit we would need getrlimit().  We could then
-     * also transparently raise the limit with setrlimit() --
-     * but only until the system hard limit/the filesystem limit,
-     * at which we would get EPERM.  Note that when using buffered
-     * io the write failure can be delayed until the flush/close. --jhi */
-    if (len && (PerlIO_write(fp,tmps,len) == 0))
-       happy = FALSE;
-    Safefree(tmpbuf);
-    return happy ? !PerlIO_error(fp) : FALSE;
 }
 
 I32
@@ -1308,22 +1263,38 @@ Perl_my_stat(pTHX)
        EXTEND(SP,1);
        gv = cGVOP_gv;
       do_fstat:
+        if (gv == PL_defgv)
+            return PL_laststatval;
        io = GvIO(gv);
-       if (io && IoIFP(io)) {
-           PL_statgv = gv;
-           sv_setpvn(PL_statname,"", 0);
-           PL_laststype = OP_STAT;
-           return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
-       }
-       else {
-           if (gv == PL_defgv)
-               return PL_laststatval;
-           if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
-               report_evil_fh(gv, io, PL_op->op_type);
-           PL_statgv = NULL;
-           sv_setpvn(PL_statname,"", 0);
-           return (PL_laststatval = -1);
-       }
+        do_fstat_have_io:
+        PL_laststype = OP_STAT;
+        PL_statgv = gv;
+        sv_setpvn(PL_statname, "", 0);
+        if(io) {
+           if (IoIFP(io)) {
+               return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
+            } else if (IoDIRP(io)) {
+#ifdef HAS_DIRFD
+                return (PL_laststatval = PerlLIO_fstat(dirfd(IoDIRP(io)), &PL_statcache));
+#else
+                Perl_die(aTHX_ PL_no_func, "dirfd");
+               /* NOT REACHED */
+               return 0;
+               /* Can't use NORETURN_FUNCTION_END because Perl_die is not
+                *     __attribute__noreturn__
+                * Can't use DIE because that does not return an integer
+                */
+#endif
+            } else {
+                if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
+                    report_evil_fh(gv, io, PL_op->op_type);
+                return (PL_laststatval = -1);
+            }
+       } else {
+            if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
+                report_evil_fh(gv, io, PL_op->op_type);
+            return (PL_laststatval = -1);
+        }
     }
     else if (PL_op->op_private & OPpFT_STACKED) {
        return PL_laststatval;
@@ -1341,6 +1312,11 @@ Perl_my_stat(pTHX)
            gv = (GV*)SvRV(sv);
            goto do_fstat;
        }
+        else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
+            io = (IO*)SvRV(sv);
+           gv = NULL;
+            goto do_fstat_have_io;
+        }
 
        s = SvPV_const(sv, len);
        PL_statgv = NULL;
@@ -1396,6 +1372,19 @@ Perl_my_lstat(pTHX)
     return PL_laststatval;
 }
 
+static void
+S_exec_failed(pTHX_ const char *cmd, int fd, int do_report)
+{
+    const int e = errno;
+    if (ckWARN(WARN_EXEC))
+       Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
+                   cmd, Strerror(e));
+    if (do_report) {
+       PerlLIO_write(fd, (void*)&e, sizeof(int));
+       PerlLIO_close(fd);
+    }
+}
+
 bool
 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
               int fd, int do_report)
@@ -1428,15 +1417,7 @@ Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
        else
            PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
        PERL_FPU_POST_EXEC
-       if (ckWARN(WARN_EXEC))
-           Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
-               (really ? tmps : PL_Argv[0]), Strerror(errno));
-       if (do_report) {
-           const int e = errno;
-
-           PerlLIO_write(fd, (void*)&e, sizeof(int));
-           PerlLIO_close(fd);
-       }
+       S_exec_failed(aTHX_ (really ? tmps : PL_Argv[0]), fd, do_report);
     }
     do_execfree();
 #endif
@@ -1461,13 +1442,14 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
     dVAR;
     register char **a;
     register char *s;
+    char *buf;
     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;
+    const Size_t cmdlen = strlen(incmd) + 1;
+    Newx(buf, cmdlen, char);
+    cmd = buf;
+    my_strlcpy(cmd, incmd, cmdlen);
 
     while (*cmd && isSPACE(*cmd))
        cmd++;
@@ -1479,19 +1461,11 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
         char flags[PERL_FLAGS_MAX];
        if (strnEQ(cmd,PL_cshname,PL_cshlen) &&
            strnEQ(cmd+PL_cshlen," -c",3)) {
-#ifdef HAS_STRLCPY
-          strlcpy(flags, "-c", PERL_FLAGS_MAX);
-#else
-         strcpy(flags,"-c");
-#endif
+          my_strlcpy(flags, "-c", PERL_FLAGS_MAX);
          s = cmd+PL_cshlen+3;
          if (*s == 'f') {
              s++;
-#ifdef HAS_STRLCPY
-              strlcat(flags, "f", PERL_FLAGS_MAX - 2);
-#else
-             strcat(flags,"f");
-#endif
+              my_strlcat(flags, "f", PERL_FLAGS_MAX - 2);
          }
          if (*s == ' ')
              s++;
@@ -1505,10 +1479,11 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
              if (s[-1] == '\'') {
                  *--s = '\0';
                  PERL_FPU_PRE_EXEC
-                 PerlProc_execl(PL_cshname, "csh", flags, ncmd, NULL);
+                 PerlProc_execl(PL_cshname, "csh", flags, ncmd, (char*)NULL);
                  PERL_FPU_POST_EXEC
                  *s = '\'';
-                 Safefree(cmd);
+                 S_exec_failed(aTHX_ PL_cshname, fd, do_report);
+                 Safefree(buf);
                  return FALSE;
              }
          }
@@ -1553,9 +1528,10 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
            }
          doshell:
            PERL_FPU_PRE_EXEC
-           PerlProc_execl(PL_sh_path, "sh", "-c", cmd, NULL);
+           PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char *)NULL);
            PERL_FPU_POST_EXEC
-           Safefree(cmd);
+           S_exec_failed(aTHX_ PL_sh_path, fd, do_report);
+           Safefree(buf);
            return FALSE;
        }
     }
@@ -1582,17 +1558,10 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
            do_execfree();
            goto doshell;
        }
-       if (ckWARN(WARN_EXEC))
-           Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
-               PL_Argv[0], Strerror(errno));
-       if (do_report) {
-           const int e = errno;
-           PerlLIO_write(fd, (const void*)&e, sizeof(int));
-           PerlLIO_close(fd);
-       }
+       S_exec_failed(aTHX_ PL_Argv[0], fd, do_report);
     }
     do_execfree();
-    Safefree(cmd);
+    Safefree(buf);
     return FALSE;
 }
 
@@ -1863,7 +1832,8 @@ nothing in the core.
                    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
 #ifdef HAS_FUTIMES
                        APPLY_TAINT_PROPER();
-                       if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))), utbufp))
+                       if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))),
+                            (struct timeval *) utbufp))
                            tot--;
 #else
                        Perl_die(aTHX_ PL_no_func, "futimes");
@@ -1881,7 +1851,7 @@ nothing in the core.
                    const char * const name = SvPV_nolen_const(*mark);
                    APPLY_TAINT_PROPER();
 #ifdef HAS_FUTIMES
-                   if (utimes(name, utbufp))
+                   if (utimes(name, (struct timeval *)utbufp))
 #else
                    if (PerlLIO_utime(name, utbufp))
 #endif
@@ -2280,7 +2250,8 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
     SETERRNO(0,0);
     if (shmctl(id, IPC_STAT, &shmds) == -1)
        return -1;
-    if (mpos < 0 || msize < 0 || (size_t)mpos + msize > shmds.shm_segsz) {
+    if (mpos < 0 || msize < 0
+       || (size_t)mpos + msize > (size_t)shmds.shm_segsz) {
        SETERRNO(EFAULT,SS_ACCVIO);             /* can't do as caller requested */
        return -1;
     }
@@ -2308,7 +2279,7 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
        STRLEN len;
 
        const char *mbuf = SvPV_const(mstr, len);
-       const I32 n = (len > msize) ? msize : len;
+       const I32 n = ((I32)len > msize) ? msize : (I32)len;
        Copy(mbuf, shm + mpos, n, char);
        if (n < msize)
            memzero(shm + mpos + n, msize - n);