This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Use pvs macros instead of pvn where possible.
[perl5.git] / doio.c
diff --git a/doio.c b/doio.c
index 557c005..b0dd4f2 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
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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.
@@ -65,8 +65,8 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
 {
     dVAR;
     register IO * const io = GvIOn(gv);
-    PerlIO *saveifp = Nullfp;
-    PerlIO *saveofp = Nullfp;
+    PerlIO *saveifp = NULL;
+    PerlIO *saveofp = NULL;
     int savefd = -1;
     char savetype = IoTYPE_CLOSED;
     int writing = 0;
@@ -76,9 +76,11 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
     bool was_fdopen = FALSE;
     bool in_raw = 0, in_crlf = 0, out_raw = 0, out_crlf = 0;
     char *type  = NULL;
-    char mode[PERL_MODE_MAX];  /* stdio file mode ("r\0", "rb\0", "r+b\0" etc.) */
+    char mode[PERL_MODE_MAX];  /* file mode ("r\0", "rb\0", "ab\0" etc.) */
     SV *namesv;
 
+    PERL_ARGS_ASSERT_DO_OPENN;
+
     Zero(mode,sizeof(mode),char);
     PL_forkprocess = 1;                /* assume true if no fork */
 
@@ -125,7 +127,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                          "Warning: unable to close filehandle %s properly.\n",
                          GvENAME(gv));
        }
-       IoOFP(io) = IoIFP(io) = Nullfp;
+       IoOFP(io) = IoIFP(io) = NULL;
     }
 
     if (as_raw) {
@@ -176,10 +178,10 @@ 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(newSVpv(oname,0));
+       namesv = newSVpvn_flags(oname, len, SVs_TEMP);
        num_svs = 1;
        svp = &namesv;
-        type = Nullch;
+       type = NULL;
        fp = PerlIO_openn(aTHX_ type, mode, -1, rawmode, rawperm, NULL, num_svs, svp);
     }
     else {
@@ -188,14 +190,14 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
        STRLEN olen = len;
        char *tend;
        int dodup = 0;
-       PerlIO *that_fp = NULL;
 
        type = savepvn(oname, len);
        tend = type+len;
        SAVEFREEPV(type);
 
         /* Lose leading and trailing white space */
-        for (; isSPACE(*type); type++) ;
+       while (isSPACE(*type))
+           type++;
         while (tend > type && isSPACE(tend[-1]))
            *--tend = '\0';
 
@@ -210,7 +212,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                goto say_false;
            }
 #endif /* USE_STDIO */
-           name = SvOK(*svp) ? savesvpv (*svp) : savepvn ("", 0);
+           name = SvOK(*svp) ? savesvpv (*svp) : savepvs ("");
            SAVEFREEPV(name);
        }
        else {
@@ -234,7 +236,9 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                }
                type++;
            }
-           for (type++; isSPACE(*type); type++) ;
+           do {
+               type++;
+           } while (isSPACE(*type));
            if (!num_svs) {
                name = type;
                len = tend-type;
@@ -246,7 +250,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                errno = EPIPE;
                goto say_false;
            }
-           if ((*name == '-' && name[1] == '\0') || num_svs)
+           if (!(*name == '-' && name[1] == '\0') || num_svs)
                TAINT_ENV();
            TAINT_PROPER("piped open");
            if (!num_svs && name[len-1] == '|') {
@@ -256,17 +260,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);
+               mode[1] = 'b';
             else if (out_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX); 
-#else
-           if (out_raw)
-               strcat(mode, "b");
-           else if (out_crlf)
-               strcat(mode, "t");
-#endif
+               mode[1] = 't';
            if (num_svs > 1) {
                fp = PerlProc_popen_list(mode, num_svs, svp);
            }
@@ -294,17 +291,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);
+               mode[1] = 'b';
             else if (out_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX);
-#else
-           if (out_raw)
-               strcat(mode, "b");
-           else if (out_crlf)
-               strcat(mode, "t");
-#endif
+               mode[1] = 't';
            if (*type == '&') {
              duplicity:
                dodup = PERLIO_DUP_FD;
@@ -318,10 +308,12 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                    fp = supplied_fp;
                }
                else {
+                   PerlIO *that_fp = NULL;
                    if (num_svs > 1) {
                        Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
                    }
-                   for (; isSPACE(*type); type++) ;
+                   while (isSPACE(*type))
+                       type++;
                    if (num_svs && (SvIOK(*svp) || (SvPOK(*svp) && looks_like_number(*svp)))) {
                        fd = SvUV(*svp);
                        num_svs = 0;
@@ -335,8 +327,8 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                            thatio = sv_2io(*svp);
                        }
                        else {
-                           GV *thatgv;
-                           thatgv = gv_fetchpv(type,0,SVt_PVIO);
+                           GV * const thatgv = gv_fetchpvn_flags(type, tend - type,
+                                                      0, SVt_PVIO);
                            thatio = GvIO(thatgv);
                        }
                        if (!thatio) {
@@ -380,7 +372,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                            fd = -1;
                    }
                    if (!num_svs)
-                       type = Nullch;
+                       type = NULL;
                    if (that_fp) {
                        fp = PerlIO_fdupopen(aTHX_ that_fp, NULL, dodup);
                    }
@@ -397,7 +389,8 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                }
            } /* & */
            else {
-               for (; isSPACE(*type); type++) ;
+               while (isSPACE(*type))
+                   type++;
                if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
                    type++;
                    fp = PerlIO_stdout();
@@ -408,10 +401,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                }
                else  {
                    if (!num_svs) {
-                       namesv = sv_2mortal(newSVpvn(type,tend - type));
+                       namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
                        num_svs = 1;
                        svp = &namesv;
-                       type = Nullch;
+                       type = NULL;
                    }
                    fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
                }
@@ -420,19 +413,14 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
               goto unknown_open_mode;
        } /* IoTYPE_WRONLY */
        else if (*type == IoTYPE_RDONLY) {
-           for (type++; isSPACE(*type); type++) ;
+           do {
+               type++;
+           } while (isSPACE(*type));
            mode[0] = 'r';
-#ifdef HAS_STRLCAT
             if (in_raw)
-                strlcat(mode, "b", PERL_MODE_MAX);
+               mode[1] = 'b';
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+               mode[1] = 't';
            if (*type == '&') {
                goto duplicity;
            }
@@ -446,10 +434,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            else {
                if (!num_svs) {
-                   namesv = sv_2mortal(newSVpvn(type,tend - type));
+                   namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
                    num_svs = 1;
                    svp = &namesv;
-                   type = Nullch;
+                   type = NULL;
                }
                fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
            }
@@ -483,17 +471,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);
+               mode[1] = 'b';
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+               mode[1] = 't';
 
            if (num_svs > 1) {
                fp = PerlProc_popen_list(mode,num_svs,svp);
@@ -503,7 +484,8 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            IoTYPE(io) = IoTYPE_PIPE;
            if (num_svs) {
-               for (; isSPACE(*type); type++) ;
+               while (isSPACE(*type))
+                   type++;
                if (*type) {
                    if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
                        goto say_false;
@@ -520,17 +502,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);
+               mode[1] = 'b';
             else if (in_crlf)
-                strlcat(mode, "t", PERL_MODE_MAX);
-#else
-           if (in_raw)
-               strcat(mode, "b");
-           else if (in_crlf)
-               strcat(mode, "t");
-#endif
+               mode[1] = 't';
 
            if (*name == '-' && name[1] == '\0') {
                fp = PerlIO_stdin();
@@ -538,10 +513,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            }
            else {
                if (!num_svs) {
-                   namesv = sv_2mortal(newSVpvn(type,tend - type));
+                   namesv = newSVpvn_flags(type, tend - type, SVs_TEMP);
                    num_svs = 1;
                    svp = &namesv;
-                   type = Nullch;
+                   type = NULL;
                }
                fp = PerlIO_openn(aTHX_ type,mode,-1,0,0,NULL,num_svs,svp);
            }
@@ -703,7 +678,7 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
            *s = 'w';
            if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,svp))) {
                PerlIO_close(fp);
-               IoIFP(io) = Nullfp;
+               IoIFP(io) = NULL;
                goto say_false;
            }
        }
@@ -732,14 +707,16 @@ Perl_nextargv(pTHX_ register GV *gv)
     Gid_t filegid;
     IO * const io = GvIOp(gv);
 
+    PERL_ARGS_ASSERT_NEXTARGV;
+
     if (!PL_argvoutgv)
-       PL_argvoutgv = gv_fetchpv("ARGVOUT",TRUE,SVt_PVIO);
+       PL_argvoutgv = gv_fetchpvs("ARGVOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
     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();
-           av_push(PL_argvout_stack, SvREFCNT_inc(PL_defoutgv));
+           assert(PL_defoutgv);
+           Perl_av_create_and_push(aTHX_ &PL_argvout_stack,
+                                   SvREFCNT_inc_simple_NN(PL_defoutgv));
        }
     }
     if (PL_filemode & (S_ISUID|S_ISGID)) {
@@ -754,7 +731,7 @@ Perl_nextargv(pTHX_ register GV *gv)
     PL_lastfd = -1;
     PL_filemode = 0;
     if (!GvAV(gv))
-        return Nullfp;
+       return NULL;
     while (av_len(GvAV(gv)) >= 0) {
        STRLEN oldlen;
        sv = av_shift(GvAV(gv));
@@ -762,11 +739,12 @@ Perl_nextargv(pTHX_ register GV *gv)
        sv_setsv(GvSVn(gv),sv);
        SvSETMAGIC(GvSV(gv));
        PL_oldname = SvPVx(GvSV(gv), oldlen);
-       if (do_open(gv,PL_oldname,oldlen,PL_inplace!=0,O_RDONLY,0,Nullfp)) {
+       if (do_open(gv,PL_oldname,oldlen,PL_inplace!=0,O_RDONLY,0,NULL)) {
            if (PL_inplace) {
                TAINT_PROPER("inplace open");
                if (oldlen == 1 && *PL_oldname == '-') {
-                   setdefout(gv_fetchpv("STDOUT",TRUE,SVt_PVIO));
+                   setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL,
+                                         SVt_PVIO));
                    return IoIFP(GvIOp(gv));
                }
 #ifndef FLEXFILENAMES
@@ -788,7 +766,7 @@ Perl_nextargv(pTHX_ register GV *gv)
                    const char *star = strchr(PL_inplace, '*');
                    if (star) {
                        const char *begin = PL_inplace;
-                       sv_setpvn(sv, "", 0);
+                       sv_setpvs(sv, "");
                        do {
                            sv_catpvn(sv, begin, star - begin);
                            sv_catpvn(sv, PL_oldname, oldlen);
@@ -812,7 +790,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;
                    }
@@ -823,7 +801,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;
                    }
@@ -832,7 +810,7 @@ Perl_nextargv(pTHX_ register GV *gv)
                    (void)PerlLIO_unlink(SvPVX_const(sv));
                    (void)PerlLIO_rename(PL_oldname,SvPVX_const(sv));
                    do_open(gv,(char*)SvPVX_const(sv),SvCUR(sv),PL_inplace!=0,
-                           O_RDONLY,0,Nullfp);
+                           O_RDONLY,0,NULL);
 #endif /* DOSISH */
 #else
                    (void)UNLINK(SvPVX_const(sv));
@@ -840,7 +818,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;
                    }
@@ -869,11 +847,11 @@ Perl_nextargv(pTHX_ register GV *gv)
                SETERRNO(0,0);          /* in case sprintf set errno */
 #ifdef VMS
                if (!do_open(PL_argvoutgv,(char*)SvPVX_const(sv),SvCUR(sv),
-                            PL_inplace!=0,O_WRONLY|O_CREAT|O_TRUNC,0,Nullfp))
+                            PL_inplace!=0,O_WRONLY|O_CREAT|O_TRUNC,0,NULL))
 #else
                    if (!do_open(PL_argvoutgv,(char*)SvPVX_const(sv),SvCUR(sv),
                             PL_inplace!=0,O_WRONLY|O_CREAT|OPEN_EXCL,0666,
-                            Nullfp))
+                            NULL))
 #endif
                {
                    if (ckWARN_d(WARN_INPLACE)) 
@@ -928,14 +906,14 @@ Perl_nextargv(pTHX_ register GV *gv)
        if (io && (IoFLAGS(io) & IOf_ARGV)
            && PL_argvout_stack && AvFILLp(PL_argvout_stack) >= 0)
        {
-           GV *oldout = (GV*)av_pop(PL_argvout_stack);
+           GV * const oldout = (GV*)av_pop(PL_argvout_stack);
            setdefout(oldout);
            SvREFCNT_dec(oldout);
-           return Nullfp;
+           return NULL;
        }
-       setdefout(gv_fetchpv("STDOUT",TRUE,SVt_PVIO));
+       setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO));
     }
-    return Nullfp;
+    return NULL;
 }
 
 /* explicit renamed to avoid C++ conflict    -- kja */
@@ -948,7 +926,7 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit)
 
     if (!gv)
        gv = PL_argvgv;
-    if (!gv || SvTYPE(gv) != SVt_PVGV) {
+    if (!gv || !isGV_with_GP(gv)) {
        if (not_implicit)
            SETERRNO(EBADF,SS_IVCHAN);
        return FALSE;
@@ -978,6 +956,8 @@ Perl_io_close(pTHX_ IO *io, bool not_implicit)
     dVAR;
     bool retval = FALSE;
 
+    PERL_ARGS_ASSERT_IO_CLOSE;
+
     if (IoIFP(io)) {
        if (IoTYPE(io) == IoTYPE_PIPE) {
            const int status = PerlProc_pclose(IoIFP(io));
@@ -1002,7 +982,7 @@ Perl_io_close(pTHX_ IO *io, bool not_implicit)
                retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
            }
        }
-       IoOFP(io) = IoIFP(io) = Nullfp;
+       IoOFP(io) = IoIFP(io) = NULL;
     }
     else if (not_implicit) {
        SETERRNO(EBADF,SS_IVCHAN);
@@ -1017,6 +997,8 @@ Perl_do_eof(pTHX_ GV *gv)
     dVAR;
     register IO * const io = GvIO(gv);
 
+    PERL_ARGS_ASSERT_DO_EOF;
+
     if (!io)
        return TRUE;
     else if ((IoTYPE(io) == IoTYPE_WRONLY) && ckWARN(WARN_IO))
@@ -1061,6 +1043,8 @@ Perl_do_tell(pTHX_ GV *gv)
     register IO *io = NULL;
     register PerlIO *fp;
 
+    PERL_ARGS_ASSERT_DO_TELL;
+
     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) {
 #ifdef ULTRIX_STDIO_BOTCH
        if (PerlIO_eof(fp))
@@ -1101,6 +1085,8 @@ Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
     register IO *io = NULL;
     register PerlIO *fp;
 
+    PERL_ARGS_ASSERT_DO_SYSSEEK;
+
     if (gv && (io = GvIO(gv)) && (fp = IoIFP(io)))
        return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
     if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
@@ -1110,12 +1096,10 @@ Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence)
 }
 
 int
-Perl_mode_from_discipline(pTHX_ SV *discp)
+Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len)
 {
     int mode = O_BINARY;
-    if (discp) {
-       STRLEN len;
-       const char *s = SvPV_const(discp,len);
+    if (s) {
        while (*s) {
            if (*s == ':') {
                switch (s[1]) {
@@ -1173,7 +1157,6 @@ my_chsize(int fd, Off_t length)
        /* code courtesy of William Kucharski */
 #define HAS_CHSIZE
 
-    struct flock fl;
     Stat_t filebuf;
 
     if (PerlLIO_fstat(fd, &filebuf) < 0)
@@ -1193,7 +1176,7 @@ my_chsize(int fd, Off_t length)
     }
     else {
        /* truncate length */
-
+       struct flock fl;
        fl.l_whence = 0;
        fl.l_len = 0;
        fl.l_start = length;
@@ -1223,52 +1206,62 @@ bool
 Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
 {
     dVAR;
-    register const char *tmps;
-    STRLEN len;
+
+    PERL_ARGS_ASSERT_DO_PRINT;
 
     /* 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)) {
-           SvGETMAGIC(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.  */
+       const char *tmps = SvPV_const(sv, len);
+       U8 *tmpbuf = NULL;
+       bool happy = TRUE;
+
        if (PerlIO_isutf8(fp)) {
-           if (!SvUTF8(sv))
-               sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
-                                     SV_GMAGIC|SV_UTF8_NO_ENCODING);
+           if (!SvUTF8(sv)) {
+               /* We don't modify the original scalar.  */
+               tmpbuf = bytes_to_utf8((const U8*) tmps, &len);
+               tmps = (char *) tmpbuf;
+           }
        }
        else if (DO_UTF8(sv)) {
-           if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
-               && ckWARN_d(WARN_UTF8))
-           {
-               Perl_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
+           STRLEN tmplen = len;
+           bool utf8 = TRUE;
+           U8 * const result = bytes_from_utf8((const U8*) tmps, &tmplen, &utf8);
+           if (!utf8) {
+               tmpbuf = result;
+               tmps = (char *) tmpbuf;
+               len = tmplen;
+           }
+           else {
+               assert((char *)result == tmps);
+               if (ckWARN_d(WARN_UTF8)) {
+                   Perl_warner(aTHX_ packWARN(WARN_UTF8),
+                               "Wide character in print");
+               }
            }
        }
-       tmps = SvPV_const(sv, len);
-       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))
-       return FALSE;
-    return !PerlIO_error(fp);
 }
 
 I32
@@ -1283,22 +1276,28 @@ 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 = Nullgv;
-           sv_setpvn(PL_statname,"", 0);
-           return (PL_laststatval = -1);
-       }
+        do_fstat_have_io:
+        PL_laststype = OP_STAT;
+        PL_statgv = gv;
+        sv_setpvs(PL_statname, "");
+        if(io) {
+           if (IoIFP(io)) {
+               return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache));
+            } else if (IoDIRP(io)) {
+                return (PL_laststatval = PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache));
+            } 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;
@@ -1308,17 +1307,22 @@ Perl_my_stat(pTHX)
        const char *s;
        STRLEN len;
        PUTBACK;
-       if (SvTYPE(sv) == SVt_PVGV) {
+       if (isGV_with_GP(sv)) {
            gv = (GV*)sv;
            goto do_fstat;
        }
-       else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
+       else if (SvROK(sv) && isGV_with_GP(SvRV(sv))) {
            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 = Nullgv;
+       PL_statgv = NULL;
        sv_setpvn(PL_statname, s, len);
        s = SvPVX_const(PL_statname);           /* s now NUL-terminated */
        PL_laststype = OP_STAT;
@@ -1337,6 +1341,7 @@ Perl_my_lstat(pTHX)
     static const char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
     dSP;
     SV *sv;
+    const char *file;
     if (PL_op->op_flags & OPf_REF) {
        EXTEND(SP,1);
        if (cGVOP_gv == PL_defgv) {
@@ -1355,39 +1360,54 @@ Perl_my_lstat(pTHX)
        Perl_croak(aTHX_ no_prev_lstat);
 
     PL_laststype = OP_LSTAT;
-    PL_statgv = Nullgv;
+    PL_statgv = NULL;
     sv = POPs;
     PUTBACK;
-    if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
+    if (SvROK(sv) && isGV_with_GP(SvRV(sv)) && ckWARN(WARN_IO)) {
        Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %s",
                GvENAME((GV*) SvRV(sv)));
        return (PL_laststatval = -1);
     }
-    /* XXX Do really need to be calling SvPV() all these times? */
-    sv_setpv(PL_statname,SvPV_nolen_const(sv));
-    PL_laststatval = PerlLIO_lstat(SvPV_nolen_const(sv),&PL_statcache);
-    if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(sv), '\n'))
+    file = SvPV_nolen_const(sv);
+    sv_setpv(PL_statname,file);
+    PL_laststatval = PerlLIO_lstat(file,&PL_statcache);
+    if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(file, '\n'))
        Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
     return PL_laststatval;
 }
 
+static void
+S_exec_failed(pTHX_ const char *cmd, int fd, int do_report)
+{
+    const int e = errno;
+    PERL_ARGS_ASSERT_EXEC_FAILED;
+    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)
 {
     dVAR;
-#if defined(MACOS_TRADITIONAL) || defined(__SYMBIAN32__)
+    PERL_ARGS_ASSERT_DO_AEXEC5;
+#if defined(MACOS_TRADITIONAL) || defined(__SYMBIAN32__) || defined(__LIBCATAMOUNT__)
     Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
 #else
     if (sp > mark) {
-       char **a;
+       const char **a;
        const char *tmps = NULL;
-       Newx(PL_Argv, sp - mark + 1, char*);
+       Newx(PL_Argv, sp - mark + 1, const char*);
        a = PL_Argv;
 
        while (++mark <= sp) {
            if (*mark)
-               *a++ = (char*)SvPV_nolen_const(*mark);
+               *a++ = SvPV_nolen_const(*mark);
            else
                *a++ = "";
        }
@@ -1403,15 +1423,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
@@ -1423,9 +1435,9 @@ Perl_do_execfree(pTHX)
 {
     dVAR;
     Safefree(PL_Argv);
-    PL_Argv = Null(char **);
+    PL_Argv = NULL;
     Safefree(PL_Cmd);
-    PL_Cmd = Nullch;
+    PL_Cmd = NULL;
 }
 
 #ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
@@ -1434,15 +1446,18 @@ bool
 Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
 {
     dVAR;
-    register char **a;
+    register const 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;
+
+    PERL_ARGS_ASSERT_DO_EXEC3;
+
+    Newx(buf, cmdlen, char);
+    cmd = buf;
+    memcpy(cmd, incmd, cmdlen);
 
     while (*cmd && isSPACE(*cmd))
        cmd++;
@@ -1454,19 +1469,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);
-#else
-             strcat(flags,"f");
-#endif
+              my_strlcat(flags, "f", PERL_FLAGS_MAX - 2);
          }
          if (*s == ' ')
              s++;
@@ -1480,10 +1487,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, (char*)0);
+                 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;
              }
          }
@@ -1499,7 +1507,9 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report)
     if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
        goto doshell;
 
-    for (s = cmd; *s && isALNUM(*s); s++) ;    /* catch VAR=val gizmo */
+    s = cmd;
+    while (isALNUM(*s))
+       s++;    /* catch VAR=val gizmo */
     if (*s == '=')
        goto doshell;
 
@@ -1526,44 +1536,40 @@ 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, (char*)0);
+           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;
        }
     }
 
-    Newx(PL_Argv, (s - cmd) / 2 + 2, char*);
+    Newx(PL_Argv, (s - cmd) / 2 + 2, const char*);
     PL_Cmd = savepvn(cmd, s-cmd);
     a = PL_Argv;
     for (s = PL_Cmd; *s;) {
-       while (*s && isSPACE(*s)) s++;
+       while (isSPACE(*s))
+           s++;
        if (*s)
            *(a++) = s;
-       while (*s && !isSPACE(*s)) s++;
+       while (*s && !isSPACE(*s))
+           s++;
        if (*s)
            *s++ = '\0';
     }
     *a = NULL;
     if (PL_Argv[0]) {
        PERL_FPU_PRE_EXEC
-       PerlProc_execvp(PL_Argv[0],PL_Argv);
+       PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
        PERL_FPU_POST_EXEC
        if (errno == ENOEXEC) {         /* for system V NIH syndrome */
            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;
 }
 
@@ -1579,6 +1585,8 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
     const char *s;
     SV ** const oldmark = mark;
 
+    PERL_ARGS_ASSERT_APPLY;
+
     /* 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.  */
@@ -1611,12 +1619,12 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
     case OP_CHMOD:
        APPLY_TAINT_PROPER();
        if (++mark <= sp) {
-           val = SvIVx(*mark);
+           val = SvIV(*mark);
            APPLY_TAINT_PROPER();
            tot = sp - mark;
            while (++mark <= sp) {
                 GV* gv;
-                if (SvTYPE(*mark) == SVt_PVGV) {
+                if (isGV_with_GP(*mark)) {
                     gv = (GV*)*mark;
                do_fchmod:
                    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
@@ -1632,7 +1640,7 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
                        tot--;
                    }
                }
-               else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+               else if (SvROK(*mark) && isGV_with_GP(SvRV(*mark))) {
                    gv = (GV*)SvRV(*mark);
                    goto do_fchmod;
                }
@@ -1656,7 +1664,7 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
            tot = sp - mark;
            while (++mark <= sp) {
                 GV* gv;
-                if (SvTYPE(*mark) == SVt_PVGV) {
+                if (isGV_with_GP(*mark)) {
                     gv = (GV*)*mark;
                do_fchown:
                    if (GvIO(gv) && IoIFP(GvIOp(gv))) {
@@ -1672,7 +1680,7 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
                        tot--;
                    }
                }
-               else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+               else if (SvROK(*mark) && isGV_with_GP(SvRV(*mark))) {
                    gv = (GV*)SvRV(*mark);
                    goto do_fchown;
                }
@@ -1705,7 +1713,7 @@ nothing in the core.
                Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
        }
        else
-           val = SvIVx(*mark);
+           val = SvIV(*mark);
        APPLY_TAINT_PROPER();
        tot = sp - mark;
 #ifdef VMS
@@ -1718,7 +1726,7 @@ nothing in the core.
             * CRTL's emulation of Unix-style signals and kill()
             */
            while (++mark <= sp) {
-               I32 proc = SvIVx(*mark);
+               I32 proc = SvIV(*mark);
                register unsigned long int __vmssts;
                APPLY_TAINT_PROPER();
                if (!((__vmssts = sys$delprc(&proc,0)) & 1)) {
@@ -1742,7 +1750,7 @@ nothing in the core.
        if (val < 0) {
            val = -val;
            while (++mark <= sp) {
-               const I32 proc = SvIVx(*mark);
+               const I32 proc = SvIV(*mark);
                APPLY_TAINT_PROPER();
 #ifdef HAS_KILLPG
                if (PerlProc_killpg(proc,val))  /* BSD */
@@ -1754,7 +1762,7 @@ nothing in the core.
        }
        else {
            while (++mark <= sp) {
-               const I32 proc = SvIVx(*mark);
+               const I32 proc = SvIV(*mark);
                APPLY_TAINT_PROPER();
                if (PerlProc_kill(proc, val))
                    tot--;
@@ -1812,29 +1820,30 @@ nothing in the core.
            else {
                 Zero(&utbuf, sizeof utbuf, char);
 #ifdef HAS_FUTIMES
-               utbuf[0].tv_sec = (long)SvIVx(accessed);  /* time accessed */
+               utbuf[0].tv_sec = (long)SvIV(accessed);  /* time accessed */
                utbuf[0].tv_usec = 0;
-               utbuf[1].tv_sec = (long)SvIVx(modified);  /* time modified */
+               utbuf[1].tv_sec = (long)SvIV(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 */
+                utbuf.actime = (Time_t)SvNV(accessed);  /* time accessed */
+                utbuf.modtime = (Time_t)SvNV(modified); /* time modified */
 #else
-                utbuf.actime = (Time_t)SvIVx(accessed);  /* time accessed */
-                utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
+                utbuf.actime = (Time_t)SvIV(accessed);  /* time accessed */
+                utbuf.modtime = (Time_t)SvIV(modified); /* time modified */
 #endif
             }
            APPLY_TAINT_PROPER();
            tot = sp - mark;
            while (++mark <= sp) {
                 GV* gv;
-                if (SvTYPE(*mark) == SVt_PVGV) {
+                if (isGV_with_GP(*mark)) {
                     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))
+                       if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))),
+                            (struct timeval *) utbufp))
                            tot--;
 #else
                        Perl_die(aTHX_ PL_no_func, "futimes");
@@ -1844,7 +1853,7 @@ nothing in the core.
                        tot--;
                    }
                }
-               else if (SvROK(*mark) && SvTYPE(SvRV(*mark)) == SVt_PVGV) {
+               else if (SvROK(*mark) && isGV_with_GP(SvRV(*mark))) {
                    gv = (GV*)SvRV(*mark);
                    goto do_futimes;
                }
@@ -1852,7 +1861,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
@@ -1880,6 +1889,9 @@ Perl_cando(pTHX_ Mode_t mode, bool effective, register const Stat_t *statbufp)
  */
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CANDO;
+
 #ifdef DOSISH
     /* [Comments and code from Len Reed]
      * MS-DOS "user" is similar to UNIX's "superuser," but can't write
@@ -1972,7 +1984,9 @@ Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp)
     const key_t key = (key_t)SvNVx(*++mark);
     const I32 n = (optype == OP_MSGGET) ? 0 : SvIVx(*++mark);
     const I32 flags = SvIVx(*++mark);
-    (void)sp;
+
+    PERL_ARGS_ASSERT_DO_IPCGET;
+    PERL_UNUSED_ARG(sp);
 
     SETERRNO(0,0);
     switch (optype)
@@ -2004,12 +2018,15 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
     char *a;
     I32 ret = -1;
     const I32 id  = SvIVx(*++mark);
+#ifdef Semctl
     const I32 n   = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
+#endif
     const I32 cmd = SvIVx(*++mark);
     SV * const astr = *++mark;
     STRLEN infosize = 0;
     I32 getinfo = (cmd == IPC_STAT);
 
+    PERL_ARGS_ASSERT_DO_IPCCTL;
     PERL_UNUSED_ARG(sp);
 
     switch (optype)
@@ -2132,6 +2149,7 @@ Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
     const char * const mbuf = SvPV_const(mstr, len);
     const I32 msize = len - sizeof(long);
 
+    PERL_ARGS_ASSERT_DO_MSGSND;
     PERL_UNUSED_ARG(sp);
 
     if (msize < 0)
@@ -2139,6 +2157,8 @@ Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
     SETERRNO(0,0);
     return msgsnd(id, (struct msgbuf *)mbuf, msize, flags);
 #else
+    PERL_UNUSED_ARG(sp);
+    PERL_UNUSED_ARG(mark);
     Perl_croak(aTHX_ "msgsnd not implemented");
 #endif
 }
@@ -2153,11 +2173,13 @@ Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
     I32 msize, flags, ret;
     const I32 id = SvIVx(*++mark);
     SV * const mstr = *++mark;
+
+    PERL_ARGS_ASSERT_DO_MSGRCV;
     PERL_UNUSED_ARG(sp);
 
     /* suppress warning when reading into undef var --jhi */
     if (! SvOK(mstr))
-       sv_setpvn(mstr, "", 0);
+       sv_setpvs(mstr, "");
     msize = SvIVx(*++mark);
     mtype = (long)SvIVx(*++mark);
     flags = SvIVx(*++mark);
@@ -2176,6 +2198,8 @@ Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
     }
     return ret;
 #else
+    PERL_UNUSED_ARG(sp);
+    PERL_UNUSED_ARG(mark);
     Perl_croak(aTHX_ "msgrcv not implemented");
 #endif
 }
@@ -2189,6 +2213,8 @@ Perl_do_semop(pTHX_ SV **mark, SV **sp)
     const I32 id = SvIVx(*++mark);
     SV * const opstr = *++mark;
     const char * const opbuf = SvPV_const(opstr, opsize);
+
+    PERL_ARGS_ASSERT_DO_SEMOP;
     PERL_UNUSED_ARG(sp);
 
     if (opsize < 3 * SHORTSIZE
@@ -2243,25 +2269,28 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
     SV * const mstr = *++mark;
     const I32 mpos = SvIVx(*++mark);
     const I32 msize = SvIVx(*++mark);
+
+    PERL_ARGS_ASSERT_DO_SHMIO;
     PERL_UNUSED_ARG(sp);
 
     SETERRNO(0,0);
     if (shmctl(id, IPC_STAT, &shmds) == -1)
        return -1;
-    if (mpos < 0 || msize < 0 || 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;
     }
-    shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
+    shm = (char *)shmat(id, NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
     if (shm == (char *)-1)     /* I hate System V IPC, I really do */
        return -1;
     if (optype == OP_SHMREAD) {
-       const char *mbuf;
+       char *mbuf;
        /* suppress warning when reading into undef var (tchrist 3/Mar/00) */
        if (! SvOK(mstr))
-           sv_setpvn(mstr, "", 0);
+           sv_setpvs(mstr, "");
        SvPV_force_nolen(mstr);
-       mbuf = SvGROW(mstr, msize+1);
+       mbuf = SvGROW(mstr, (STRLEN)msize+1);
 
        Copy(shm + mpos, mbuf, msize, char);
        SvCUR_set(mstr, msize);
@@ -2273,12 +2302,10 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
 #endif
     }
     else {
-       I32 n;
        STRLEN len;
 
        const char *mbuf = SvPV_const(mstr, len);
-       if ((n = len) > msize)
-           n = msize;
+       const I32 n = ((I32)len > msize) ? msize : (I32)len;
        Copy(mbuf, shm + mpos, n, char);
        if (n < msize)
            memzero(shm + mpos + n, msize - n);
@@ -2308,95 +2335,23 @@ PerlIO *
 Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
 {
     dVAR;
-    SV * const tmpcmd = NEWSV(55, 0);
+    SV * const tmpcmd = newSV(0);
     PerlIO *fp;
+
+    PERL_ARGS_ASSERT_START_GLOB;
+
     ENTER;
     SAVEFREESV(tmpcmd);
 #ifdef VMS /* expand the wildcards right here, rather than opening a pipe, */
            /* since spawning off a process is a real performance hit */
-    {
-#include <descrip.h>
-#include <lib$routines.h>
-#include <nam.h>
-#include <rmsdef.h>
-       char rslt[NAM$C_MAXRSS+1+sizeof(unsigned short int)] = {'\0','\0'};
-       char vmsspec[NAM$C_MAXRSS+1];
-       char * const rstr = rslt + sizeof(unsigned short int);
-       char *begin, *end, *cp;
-       $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;");
-       PerlIO *tmpfp;
-       STRLEN i;
-       struct dsc$descriptor_s wilddsc
-           = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
-       struct dsc$descriptor_vs rsdsc
-           = {sizeof rslt, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, rslt};
-       unsigned long int cxt = 0, sts = 0, ok = 1, hasdir = 0, hasver = 0, isunix = 0;
-
-       /* We could find out if there's an explicit dev/dir or version
-          by peeking into lib$find_file's internal context at
-          ((struct NAM *)((struct FAB *)cxt)->fab$l_nam)->nam$l_fnb
-          but that's unsupported, so I don't want to do it now and
-          have it bite someone in the future. */
-       cp = SvPV(tmpglob,i);
-       for (; i; i--) {
-           if (cp[i] == ';') hasver = 1;
-           if (cp[i] == '.') {
-               if (sts) hasver = 1;
-               else sts = 1;
-           }
-           if (cp[i] == '/') {
-               hasdir = isunix = 1;
-               break;
-           }
-           if (cp[i] == ']' || cp[i] == '>' || cp[i] == ':') {
-               hasdir = 1;
-               break;
-           }
-       }
-       if ((tmpfp = PerlIO_tmpfile()) != NULL) {
-           Stat_t st;
-           if (!PerlLIO_stat(SvPVX_const(tmpglob),&st) && S_ISDIR(st.st_mode))
-               ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
-           else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
-           if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
-           for (cp=wilddsc.dsc$a_pointer; ok && cp && *cp; cp++)
-               if (*cp == '?') *cp = '%';  /* VMS style single-char wildcard */
-           while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
-                                              &dfltdsc,NULL,NULL,NULL))&1)) {
-               /* 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) {
-                   if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1);
-                   begin = rstr;
-               }
-               else {
-                   begin = end;
-                   while (*(--begin) != ']' && *begin != '>') ;
-                   ++begin;
-               }
-               ok = (PerlIO_puts(tmpfp,begin) != EOF);
-           }
-           if (cxt) (void)lib$find_file_end(&cxt);
-           if (ok && sts != RMS$_NMF &&
-               sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
-           if (!ok) {
-               if (!(sts & 1)) {
-                   SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
-               }
-               PerlIO_close(tmpfp);
-               fp = NULL;
-           }
-           else {
-               PerlIO_rewind(tmpfp);
-               IoTYPE(io) = IoTYPE_RDONLY;
-               IoIFP(io) = fp = tmpfp;
-               IoFLAGS(io) &= ~IOf_UNTAINT;  /* maybe redundant */
-           }
-       }
-    }
+
+PerlIO * 
+Perl_vms_start_glob
+   (pTHX_ SV *tmpglob,
+    IO *io);
+
+    fp = Perl_vms_start_glob(aTHX_ tmpglob, io);
+
 #else /* !VMS */
 #ifdef MACOS_TRADITIONAL
     sv_setpv(tmpcmd, "glob ");
@@ -2436,7 +2391,7 @@ Perl_start_glob (pTHX_ SV *tmpglob, IO *io)
 #endif /* !DOSISH */
 #endif /* MACOS_TRADITIONAL */
     (void)do_open(PL_last_in_gv, (char*)SvPVX_const(tmpcmd), SvCUR(tmpcmd),
-                 FALSE, O_RDONLY, 0, Nullfp);
+                 FALSE, O_RDONLY, 0, NULL);
     fp = IoIFP(io);
 #endif /* !VMS */
     LEAVE;