X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/4b451737e0f77cc9e91b1336d04f21659d96b732..e1ee396065926b895c7d618e39afbf16cb549f31:/doio.c diff --git a/doio.c b/doio.c index 2a58da3..a631eeb 100644 --- a/doio.c +++ b/doio.c @@ -64,7 +64,6 @@ static IO * S_openn_setup(pTHX_ GV *gv, char *mode, PerlIO **saveifp, PerlIO **saveofp, int *savefd, char *savetype) { - dVAR; IO * const io = GvIOn(gv); PERL_ARGS_ASSERT_OPENN_SETUP; @@ -145,7 +144,6 @@ bool Perl_do_open_raw(pTHX_ GV *gv, const char *oname, STRLEN len, int rawmode, int rawperm) { - dVAR; PerlIO *saveifp; PerlIO *saveofp; int savefd; @@ -215,7 +213,6 @@ bool Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len, PerlIO *supplied_fp, SV **svp, U32 num_svs) { - dVAR; PerlIO *saveifp; PerlIO *saveofp; int savefd; @@ -394,7 +391,7 @@ Perl_do_open6(pTHX_ GV *gv, const char *oname, STRLEN len, num_svs = 0; } else if (isDIGIT(*type)) { - wanted_fd = atoi(type); + wanted_fd = grok_atou(type, NULL); } else { const IO* thatio; @@ -617,7 +614,7 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, if (!fp) { if (IoTYPE(io) == IoTYPE_RDONLY && ckWARN(WARN_NEWLINE) - && strchr(oname, '\n') + && should_warn_nl(oname) ) { @@ -646,9 +643,9 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, } fd = PerlIO_fileno(fp); - /* If there is no fd (e.g. PerlIO::scalar) assume it isn't a - * socket - this covers PerlIO::scalar - otherwise unless we "know" the - * type probe for socket-ness. + /* Do NOT do: "if (fd < 0) goto say_false;" here. If there is no + * fd assume it isn't a socket - this covers PerlIO::scalar - + * otherwise unless we "know" the type probe for socket-ness. */ if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD && fd >= 0) { if (PerlLIO_fstat(fd,&PL_statbuf) < 0) { @@ -696,7 +693,10 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, is assigned to (say) STDOUT - for now let dup2() fail and provide the error */ - if (PerlLIO_dup2(fd, savefd) < 0) { + if (fd < 0) { + SETERRNO(EBADF,RMS_IFI); + goto say_false; + } else if (PerlLIO_dup2(fd, savefd) < 0) { (void)PerlIO_close(fp); goto say_false; } @@ -732,13 +732,23 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, if (was_fdopen) { /* need to close fp without closing underlying fd */ int ofd = PerlIO_fileno(fp); - int dupfd = PerlLIO_dup(ofd); + int dupfd = ofd >= 0 ? PerlLIO_dup(ofd) : -1; #if defined(HAS_FCNTL) && defined(F_SETFD) /* Assume if we have F_SETFD we have F_GETFD */ - int coe = fcntl(ofd,F_GETFD); + int coe = ofd >= 0 ? fcntl(ofd, F_GETFD) : -1; + if (coe < 0) { + if (dupfd >= 0) + PerlLIO_close(dupfd); + goto say_false; + } #endif + if (ofd < 0 || dupfd < 0) { + if (dupfd >= 0) + PerlLIO_close(dupfd); + goto say_false; + } PerlIO_close(fp); - PerlLIO_dup2(dupfd,ofd); + PerlLIO_dup2(dupfd, ofd); #if defined(HAS_FCNTL) && defined(F_SETFD) /* The dup trick has lost close-on-exec on ofd */ fcntl(ofd,F_SETFD, coe); @@ -754,9 +764,10 @@ S_openn_cleanup(pTHX_ GV *gv, IO *io, PerlIO *fp, char *mode, const char *oname, } #if defined(HAS_FCNTL) && defined(F_SETFD) if (fd >= 0) { - dSAVE_ERRNO; - fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */ - RESTORE_ERRNO; + if (fcntl(fd, F_SETFD, fd > PL_maxsysfd) < 0) { + PerlLIO_close(fd); + goto say_false; + } } #endif IoIFP(io) = fp; @@ -790,14 +801,6 @@ say_false: PerlIO * Perl_nextargv(pTHX_ GV *gv) { - dVAR; - SV *sv; -#ifndef FLEXFILENAMES - int filedev; - int fileino; -#endif - Uid_t fileuid; - Gid_t filegid; IO * const io = GvIOp(gv); PERL_ARGS_ASSERT_NEXTARGV; @@ -827,14 +830,30 @@ Perl_nextargv(pTHX_ GV *gv) return NULL; while (av_tindex(GvAV(gv)) >= 0) { STRLEN oldlen; - sv = av_shift(GvAV(gv)); + SV *const sv = av_shift(GvAV(gv)); SAVEFREESV(sv); SvTAINTED_off(GvSVn(gv)); /* previous tainting irrelevant */ 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,NULL)) { - if (PL_inplace) { + if (LIKELY(!PL_inplace)) { + if (do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0)) { + return IoIFP(GvIOp(gv)); + } + } + else { + /* This very long block ends with return IoIFP(GvIOp(gv)); + Both this block and the block above fall through on open + failure to the warning code, and then the while loop above tries + the next entry. */ + if (do_open_raw(gv, PL_oldname, oldlen, O_RDONLY, 0)) { +#ifndef FLEXFILENAMES + int filedev; + int fileino; +#endif + Uid_t fileuid; + Gid_t filegid; + TAINT_PROPER("inplace open"); if (oldlen == 1 && *PL_oldname == '-') { setdefout(gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, @@ -900,7 +919,7 @@ Perl_nextargv(pTHX_ GV *gv) do_close(gv,FALSE); (void)PerlLIO_unlink(SvPVX_const(sv)); (void)PerlLIO_rename(PL_oldname,SvPVX_const(sv)); - do_open(gv,(char*)SvPVX_const(sv),SvCUR(sv),TRUE,O_RDONLY,0,NULL); + do_open_raw(gv, SvPVX_const(sv), SvCUR(sv), O_RDONLY, 0); #endif /* DOSISH */ #else (void)UNLINK(SvPVX_const(sv)); @@ -932,14 +951,14 @@ Perl_nextargv(pTHX_ GV *gv) sv_setpvn(sv,PL_oldname,oldlen); SETERRNO(0,0); /* in case sprintf set errno */ - if (!Perl_do_openn(aTHX_ PL_argvoutgv, (char*)SvPVX_const(sv), - SvCUR(sv), TRUE, + if (!Perl_do_open_raw(aTHX_ PL_argvoutgv, SvPVX_const(sv), + SvCUR(sv), #ifdef VMS - O_WRONLY|O_CREAT|O_TRUNC,0, + O_WRONLY|O_CREAT|O_TRUNC, 0 #else - O_WRONLY|O_CREAT|OPEN_EXCL,0600, + O_WRONLY|O_CREAT|OPEN_EXCL, 0600 #endif - NULL, NULL, 0)) { + )) { Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE), "Can't do inplace edit on %s: %s", PL_oldname, Strerror(errno) ); do_close(gv,FALSE); @@ -947,41 +966,40 @@ Perl_nextargv(pTHX_ GV *gv) } setdefout(PL_argvoutgv); PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv))); - (void)PerlLIO_fstat(PL_lastfd,&PL_statbuf); + if (PL_lastfd >= 0) { + (void)PerlLIO_fstat(PL_lastfd,&PL_statbuf); #ifdef HAS_FCHMOD - (void)fchmod(PL_lastfd,PL_filemode); + (void)fchmod(PL_lastfd,PL_filemode); #else - (void)PerlLIO_chmod(PL_oldname,PL_filemode); + (void)PerlLIO_chmod(PL_oldname,PL_filemode); #endif - if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) { - int rc = 0; + if (fileuid != PL_statbuf.st_uid || filegid != PL_statbuf.st_gid) { + /* XXX silently ignore failures */ #ifdef HAS_FCHOWN - rc = fchown(PL_lastfd,fileuid,filegid); + PERL_UNUSED_RESULT(fchown(PL_lastfd,fileuid,filegid)); #else #ifdef HAS_CHOWN - rc = PerlLIO_chown(PL_oldname,fileuid,filegid); + PERL_UNUSED_RESULT(PerlLIO_chown(PL_oldname,fileuid,filegid)); #endif #endif - /* XXX silently ignore failures */ - PERL_UNUSED_VAR(rc); - } - } - return IoIFP(GvIOp(gv)); - } - else { - if (ckWARN_d(WARN_INPLACE)) { - const int eno = errno; - if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0 - && !S_ISREG(PL_statbuf.st_mode)) - { - Perl_warner(aTHX_ packWARN(WARN_INPLACE), - "Can't do inplace edit: %s is not a regular file", - PL_oldname); + } } - else - Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s", - PL_oldname, Strerror(eno)); + return IoIFP(GvIOp(gv)); } + } /* successful do_open_raw(), PL_inplace non-NULL */ + + if (ckWARN_d(WARN_INPLACE)) { + const int eno = errno; + if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0 + && !S_ISREG(PL_statbuf.st_mode)) { + Perl_warner(aTHX_ packWARN(WARN_INPLACE), + "Can't do inplace edit: %s is not a regular file", + PL_oldname); + } + else { + Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s", + PL_oldname, Strerror(eno)); + } } } if (io && (IoFLAGS(io) & IOf_ARGV)) @@ -1005,7 +1023,6 @@ Perl_nextargv(pTHX_ GV *gv) bool Perl_do_close(pTHX_ GV *gv, bool not_implicit) { - dVAR; bool retval; IO *io; @@ -1037,7 +1054,6 @@ Perl_do_close(pTHX_ GV *gv, bool not_implicit) bool Perl_io_close(pTHX_ IO *io, bool not_implicit) { - dVAR; bool retval = FALSE; PERL_ARGS_ASSERT_IO_CLOSE; @@ -1078,7 +1094,6 @@ Perl_io_close(pTHX_ IO *io, bool not_implicit) bool Perl_do_eof(pTHX_ GV *gv) { - dVAR; IO * const io = GvIO(gv); PERL_ARGS_ASSERT_DO_EOF; @@ -1123,7 +1138,6 @@ Perl_do_eof(pTHX_ GV *gv) Off_t Perl_do_tell(pTHX_ GV *gv) { - dVAR; IO *const io = GvIO(gv); PerlIO *fp; @@ -1140,7 +1154,6 @@ Perl_do_tell(pTHX_ GV *gv) bool Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence) { - dVAR; IO *const io = GvIO(gv); PerlIO *fp; @@ -1155,14 +1168,17 @@ Perl_do_seek(pTHX_ GV *gv, Off_t pos, int whence) Off_t Perl_do_sysseek(pTHX_ GV *gv, Off_t pos, int whence) { - dVAR; IO *const io = GvIO(gv); PerlIO *fp; PERL_ARGS_ASSERT_DO_SYSSEEK; - if (io && (fp = IoIFP(io))) - return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence); + if (io && (fp = IoIFP(io))) { + int fd = PerlIO_fileno(fp); + if (fd >= 0) { + return PerlLIO_lseek(fd, pos, whence); + } + } report_evil_fh(gv); SETERRNO(EBADF,RMS_IFI); return (Off_t)-1; @@ -1172,6 +1188,7 @@ int Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len) { int mode = O_BINARY; + PERL_UNUSED_CONTEXT; if (s) { while (*s) { if (*s == ':') { @@ -1185,7 +1202,7 @@ Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len) len -= 4; break; } - /* FALL THROUGH */ + /* FALLTHROUGH */ case 'c': if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f' && (!s[5] || s[5] == ':' || isSPACE(s[5]))) @@ -1195,7 +1212,7 @@ Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len) len -= 5; break; } - /* FALL THROUGH */ + /* FALLTHROUGH */ default: goto fail_discipline; } @@ -1278,8 +1295,6 @@ my_chsize(int fd, Off_t length) bool Perl_do_print(pTHX_ SV *sv, PerlIO *fp) { - dVAR; - PERL_ARGS_ASSERT_DO_PRINT; /* assuming fp is checked earlier */ @@ -1351,7 +1366,6 @@ Perl_do_print(pTHX_ SV *sv, PerlIO *fp) I32 Perl_my_stat_flags(pTHX_ const U32 flags) { - dVAR; dSP; IO *io; GV* gv; @@ -1366,9 +1380,15 @@ Perl_my_stat_flags(pTHX_ const U32 flags) PL_laststype = OP_STAT; PL_statgv = gv ? gv : (GV *)io; sv_setpvs(PL_statname, ""); - if(io) { + if (io) { if (IoIFP(io)) { - return (PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache)); + int fd = PerlIO_fileno(IoIFP(io)); + if (fd < 0) { + /* E.g. PerlIO::scalar has no real fd. */ + return (PL_laststatval = -1); + } else { + return (PL_laststatval = PerlLIO_fstat(fd, &PL_statcache)); + } } else if (IoDIRP(io)) { return (PL_laststatval = PerlLIO_fstat(my_dirfd(IoDIRP(io)), &PL_statcache)); } @@ -1399,7 +1419,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags) s = SvPVX_const(PL_statname); /* s now NUL-terminated */ PL_laststype = OP_STAT; PL_laststatval = PerlLIO_stat(s, &PL_statcache); - if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(s, '\n')) { + if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(s)) { GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */ Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat"); GCC_DIAG_RESTORE; @@ -1412,7 +1432,6 @@ Perl_my_stat_flags(pTHX_ const U32 flags) I32 Perl_my_lstat_flags(pTHX_ const U32 flags) { - dVAR; static const char* const no_prev_lstat = "The stat preceding -l _ wasn't an lstat"; dSP; const char *file; @@ -1456,13 +1475,13 @@ Perl_my_lstat_flags(pTHX_ const U32 flags) /* diag_listed_as: Use of -l on filehandle%s */ Perl_warner(aTHX_ packWARN(WARN_IO), "Use of -l on filehandle %"HEKf, - GvENAME_HEK((const GV *) - (SvROK(sv) ? SvRV(sv) : sv))); + HEKfARG(GvENAME_HEK((const GV *) + (SvROK(sv) ? SvRV(sv) : sv)))); } file = SvPV_flags_const_nolen(sv, flags); sv_setpv(PL_statname,file); PL_laststatval = PerlLIO_lstat(file,&PL_statcache); - if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(file, '\n')) { + if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(file)) { GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */ Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat"); GCC_DIAG_RESTORE; @@ -1479,9 +1498,8 @@ S_exec_failed(pTHX_ const char *cmd, int fd, int do_report) Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s", cmd, Strerror(e)); if (do_report) { - int rc = PerlLIO_write(fd, (void*)&e, sizeof(int)); - /* silently ignore failures */ - PERL_UNUSED_VAR(rc); + /* XXX silently ignore failures */ + PERL_UNUSED_RESULT(PerlLIO_write(fd, (void*)&e, sizeof(int))); PerlLIO_close(fd); } } @@ -1529,7 +1547,6 @@ Perl_do_aexec5(pTHX_ SV *really, SV **mark, SV **sp, void Perl_do_execfree(pTHX) { - dVAR; Safefree(PL_Argv); PL_Argv = NULL; Safefree(PL_Cmd); @@ -1678,7 +1695,6 @@ Perl_do_exec3(pTHX_ const char *incmd, int fd, int do_report) I32 Perl_apply(pTHX_ I32 type, SV **mark, SV **sp) { - dVAR; I32 val; I32 tot = 0; const char *const what = PL_op_name[type]; @@ -1731,9 +1747,13 @@ Perl_apply(pTHX_ I32 type, SV **mark, SV **sp) if ((gv = MAYBE_DEREF_GV(*mark))) { if (GvIO(gv) && IoIFP(GvIOp(gv))) { #ifdef HAS_FCHMOD + int fd = PerlIO_fileno(IoIFP(GvIOn(gv))); APPLY_TAINT_PROPER(); - if (fchmod(PerlIO_fileno(IoIFP(GvIOn(gv))), val)) - tot--; + if (fd < 0) { + SETERRNO(EBADF,RMS_IFI); + tot--; + } else if (fchmod(fd, val)) + tot--; #else Perl_die(aTHX_ PL_no_func, "fchmod"); #endif @@ -1767,8 +1787,12 @@ Perl_apply(pTHX_ I32 type, SV **mark, SV **sp) if ((gv = MAYBE_DEREF_GV(*mark))) { if (GvIO(gv) && IoIFP(GvIOp(gv))) { #ifdef HAS_FCHOWN + int fd = PerlIO_fileno(IoIFP(GvIOn(gv))); APPLY_TAINT_PROPER(); - if (fchown(PerlIO_fileno(IoIFP(GvIOn(gv))), val, val2)) + if (fd < 0) { + SETERRNO(EBADF,RMS_IFI); + tot--; + } else if (fchown(fd, val, val2)) tot--; #else Perl_die(aTHX_ PL_no_func, "fchown"); @@ -1899,7 +1923,7 @@ nothing in the core. tot--; else if (S_ISDIR(PL_statbuf.st_mode)) { tot--; - SETERRNO(EISDIR, SS$_NOPRIV); + SETERRNO(EISDIR, SS_NOPRIV); } else { if (UNLINK(s)) @@ -1957,9 +1981,12 @@ nothing in the core. if ((gv = MAYBE_DEREF_GV(*mark))) { if (GvIO(gv) && IoIFP(GvIOp(gv))) { #ifdef HAS_FUTIMES + int fd = PerlIO_fileno(IoIFP(GvIOn(gv))); APPLY_TAINT_PROPER(); - if (futimes(PerlIO_fileno(IoIFP(GvIOn(gv))), - (struct timeval *) utbufp)) + if (fd < 0) { + SETERRNO(EBADF,RMS_IFI); + tot--; + } else if (futimes(fd, (struct timeval *) utbufp)) tot--; #else Perl_die(aTHX_ PL_no_func, "futimes"); @@ -2004,9 +2031,8 @@ Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp) * is in the list of groups returned from getgroups(). */ { - dVAR; - PERL_ARGS_ASSERT_CANDO; + PERL_UNUSED_CONTEXT; #ifdef DOSISH /* [Comments and code from Len Reed] @@ -2064,7 +2090,10 @@ Perl_cando(pTHX_ Mode_t mode, bool effective, const Stat_t *statbufp) static bool S_ingroup(pTHX_ Gid_t testgid, bool effective) { - dVAR; +#ifndef PERL_IMPLICIT_SYS + /* PERL_IMPLICIT_SYS like Win32: getegid() etc. require the context. */ + PERL_UNUSED_CONTEXT; +#endif if (testgid == (effective ? PerlProc_getegid() : PerlProc_getgid())) return TRUE; #ifdef HAS_GETGROUPS @@ -2074,15 +2103,17 @@ S_ingroup(pTHX_ Gid_t testgid, bool effective) bool rc = FALSE; anum = getgroups(0, gary); - Newx(gary, anum, Groups_t); - anum = getgroups(anum, gary); - while (--anum >= 0) - if (gary[anum] == testgid) { - rc = TRUE; - break; - } + if (anum > 0) { + Newx(gary, anum, Groups_t); + anum = getgroups(anum, gary); + while (--anum >= 0) + if (gary[anum] == testgid) { + rc = TRUE; + break; + } - Safefree(gary); + Safefree(gary); + } return rc; } #else @@ -2095,7 +2126,6 @@ S_ingroup(pTHX_ Gid_t testgid, bool effective) I32 Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp) { - dVAR; const key_t key = (key_t)SvNVx(*++mark); SV *nsv = optype == OP_MSGGET ? NULL : *++mark; const I32 flags = SvIVx(*++mark); @@ -2130,7 +2160,6 @@ Perl_do_ipcget(pTHX_ I32 optype, SV **mark, SV **sp) I32 Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp) { - dVAR; char *a; I32 ret = -1; const I32 id = SvIVx(*++mark); @@ -2264,7 +2293,6 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp) I32 Perl_do_msgsnd(pTHX_ SV **mark, SV **sp) { - dVAR; #ifdef HAS_MSG STRLEN len; const I32 id = SvIVx(*++mark); @@ -2293,7 +2321,6 @@ I32 Perl_do_msgrcv(pTHX_ SV **mark, SV **sp) { #ifdef HAS_MSG - dVAR; char *mbuf; long mtype; I32 msize, flags, ret; @@ -2334,7 +2361,6 @@ I32 Perl_do_semop(pTHX_ SV **mark, SV **sp) { #ifdef HAS_SEM - dVAR; STRLEN opsize; const I32 id = SvIVx(*++mark); SV * const opstr = *++mark; @@ -2380,7 +2406,6 @@ I32 Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp) { #ifdef HAS_SHM - dVAR; char *shm; struct shmid_ds shmds; const I32 id = SvIVx(*++mark); @@ -2454,7 +2479,6 @@ Moving it away shrinks pp_hot.c; shrinking pp_hot.c helps speed perl up. PerlIO * Perl_start_glob (pTHX_ SV *tmpglob, IO *io) { - dVAR; SV * const tmpcmd = newSV(0); PerlIO *fp; STRLEN len; @@ -2515,8 +2539,8 @@ Perl_vms_start_glob if (home && *home) SvSETMAGIC(*home); if (path && *path) SvSETMAGIC(*path); } - (void)do_open(PL_last_in_gv, (char*)SvPVX_const(tmpcmd), SvCUR(tmpcmd), - FALSE, O_RDONLY, 0, NULL); + (void)do_open6(PL_last_in_gv, SvPVX_const(tmpcmd), SvCUR(tmpcmd), + NULL, NULL, 0); fp = IoIFP(io); #endif /* !VMS */ LEAVE;