This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Enhance test cleanliness by a very small factor.
[perl5.git] / doio.c
diff --git a/doio.c b/doio.c
index 1135a62..f0b036a 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -48,9 +48,7 @@
 #  define OPEN_EXCL 0
 #endif
 
-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
 #include <signal.h>
-#endif
 
 bool
 Perl_do_open(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
@@ -94,7 +92,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
 
     /* Collect default raw/crlf info from the op */
     if (PL_op && PL_op->op_type == OP_OPEN) {
-       /* set up disciplines */
+       /* set up IO layers */
        U8 flags = PL_op->op_private;
        in_raw = (flags & OPpOPEN_IN_RAW);
        in_crlf = (flags & OPpOPEN_IN_CRLF);
@@ -179,7 +177,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
                 (ismodifying & (O_CREAT|appendtrunc)))
                  TAINT_PROPER("sysopen");
        }
-       mode[ix++] = '#'; /* Marker to openn to use numeric "sysopen" */
+       mode[ix++] = IoTYPE_NUMERIC; /* Marker to openn to use numeric "sysopen" */
 
 #if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)
        rawmode |= O_LARGEFILE; /* Transparently largefiley. */
@@ -212,7 +210,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
            *--tend = '\0';
 
        if (num_svs) {
-           /* New style explict name, type is just mode and discipline/layer info */
+           /* New style explicit name, type is just mode and layer info */
            STRLEN l = 0;
 #ifdef USE_STDIO
            if (SvROK(*svp) && !strchr(name,'&')) {
@@ -236,7 +234,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
        if ((*type == IoTYPE_RDWR) && /* scary */
            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
            ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
-        TAINT_PROPER("open");
+           TAINT_PROPER("open");
            mode[1] = *type++;
            writing = 1;
        }
@@ -244,7 +242,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
        if (*type == IoTYPE_PIPE) {
            if (num_svs) {
                if (type[1] != IoTYPE_STD) {
-                 unknown_desr:
+                 unknown_open_mode:
                    Perl_croak(aTHX_ "Unknown open() mode '%.*s'", (int)olen, oname);
                }
                type++;
@@ -289,7 +287,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
                    }
                }
            }
-       }
+       } /* IoTYPE_PIPE */
        else if (*type == IoTYPE_WRONLY) {
            TAINT_PROPER("open");
            type++;
@@ -422,7 +420,9 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
                    fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
                }
            } /* !& */
-       }
+           if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
+              goto unknown_open_mode;
+       } /* IoTYPE_WRONLY */
        else if (*type == IoTYPE_RDONLY) {
            /*SUPPRESS 530*/
            for (type++; isSPACE(*type); type++) ;
@@ -453,8 +453,11 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
                }
                fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
            }
-       }
-       else if ((num_svs && type[0] == IoTYPE_STD && type[1] == IoTYPE_PIPE) ||
+           if (!fp && type && *type && *type != ':' && !isIDFIRST(*type))
+              goto unknown_open_mode;
+       } /* IoTYPE_RDONLY */
+       else if ((num_svs && /* '-|...' or '...|' */
+                 type[0] == IoTYPE_STD && type[1] == IoTYPE_PIPE) ||
                 (!num_svs && tend > type+1 && tend[-1] == IoTYPE_PIPE)) {
            if (num_svs) {
                type += 2;   /* skip over '-|' */
@@ -499,9 +502,9 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
                }
            }
        }
-       else {
+       else { /* layer(Args) */
            if (num_svs)
-               goto unknown_desr;
+               goto unknown_open_mode;
            name = type;
            IoTYPE(io) = IoTYPE_RDONLY;
            /*SUPPRESS 530*/
@@ -674,8 +677,8 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
        if (IoTYPE(io) == IoTYPE_SOCKET
            || (IoTYPE(io) == IoTYPE_WRONLY && fd >= 0 && S_ISCHR(PL_statbuf.st_mode)) ) {
            char *s = mode;
-           if (*s == 'I' || *s == '#')
-            s++;
+           if (*s == IoTYPE_IMPLICIT || *s == IoTYPE_NUMERIC)
+             s++;
            *s = 'w';
            if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,svp))) {
                PerlIO_close(fp);
@@ -932,8 +935,8 @@ Perl_do_pipe(pTHX_ SV *sv, GV *rgv, GV *wgv)
 
     if (PerlProc_pipe(fd) < 0)
        goto badexit;
-    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
-    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
+    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;
@@ -1165,7 +1168,7 @@ fail_discipline:
                if (!end)
                    end = s+len;
 #ifndef PERLIO_LAYERS
-               Perl_croak(aTHX_ "Unknown discipline '%.*s'", end-s, s);
+               Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
 #else
                s = end;
 #endif
@@ -1333,6 +1336,9 @@ Perl_my_stat(pTHX)
            return (PL_laststatval = -1);
        }
     }
+    else if (PL_op->op_private & OPpFT_STACKED) {
+       return PL_laststatval;
+    }
     else {
        SV* sv = POPs;
        char *s;
@@ -1359,6 +1365,8 @@ Perl_my_stat(pTHX)
     }
 }
 
+static char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
+
 I32
 Perl_my_lstat(pTHX)
 {
@@ -1369,7 +1377,7 @@ Perl_my_lstat(pTHX)
        EXTEND(SP,1);
        if (cGVOP_gv == PL_defgv) {
            if (PL_laststype != OP_LSTAT)
-               Perl_croak(aTHX_ "The stat preceding -l _ wasn't an lstat");
+               Perl_croak(aTHX_ no_prev_lstat);
            return PL_laststatval;
        }
        if (ckWARN(WARN_IO)) {
@@ -1378,6 +1386,9 @@ Perl_my_lstat(pTHX)
            return (PL_laststatval = -1);
        }
     }
+    else if (ckWARN(WARN_IO) && PL_laststype != OP_LSTAT
+           && (PL_op->op_private & OPpFT_STACKED))
+       Perl_croak(aTHX_ no_prev_lstat);
 
     PL_laststype = OP_LSTAT;
     PL_statgv = Nullgv;
@@ -1395,11 +1406,13 @@ 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,
@@ -1427,10 +1440,12 @@ Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
        if ((!really && *PL_Argv[0] != '/') ||
            (really && *tmps != '/'))           /* will execvp use PATH? */
            TAINT_ENV();                /* testing IFS here is overkill, probably */
+       PERL_FPU_PRE_EXEC
        if (really && *tmps)
            PerlProc_execvp(tmps,EXEC_ARGV_CAST(PL_Argv));
        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));
@@ -1500,7 +1515,9 @@ Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
                  *--s = '\0';
              if (s[-1] == '\'') {
                  *--s = '\0';
+                 PERL_FPU_PRE_EXEC
                  PerlProc_execl(PL_cshname,"csh", flags, ncmd, (char*)0);
+                 PERL_FPU_POST_EXEC
                  *s = '\'';
                  return FALSE;
              }
@@ -1537,13 +1554,15 @@ Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
 
                while (*t && isSPACE(*t))
                    ++t;
-               if (!*t && (dup2(1,2) != -1)) {
+               if (!*t && (PerlLIO_dup2(1,2) != -1)) {
                    s[-2] = '\0';
                    break;
                }
            }
          doshell:
+           PERL_FPU_PRE_EXEC
            PerlProc_execl(PL_sh_path, "sh", "-c", cmd, (char*)0);
+           PERL_FPU_POST_EXEC
            return FALSE;
        }
     }
@@ -1561,7 +1580,9 @@ Perl_do_exec3(pTHX_ char *cmd, int fd, int do_report)
     }
     *a = Nullch;
     if (PL_Argv[0]) {
+       PERL_FPU_PRE_EXEC
        PerlProc_execvp(PL_Argv[0],PL_Argv);
+       PERL_FPU_POST_EXEC
        if (errno == ENOEXEC) {         /* for system V NIH syndrome */
            do_execfree();
            goto doshell;
@@ -2275,8 +2296,9 @@ Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
                if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
            while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
                                               &dfltdsc,NULL,NULL,NULL))&1)) {
-               end = rstr + (unsigned long int) *rslt;
-               if (!hasver) while (*end != ';') end--;
+               /* with varying string, 1st word of buffer contains result length */
+               end = rstr + *((unsigned short int*)rslt);
+               if (!hasver) while (*end != ';' && end > rstr) end--;
                *(end++) = '\n';  *end = '\0';
                for (cp = rstr; *cp; cp++) *cp = _tolower(*cp);
                if (hasdir) {