/* doio.c
*
- * Copyright (c) 1991-2001, Larry Wall
+ * Copyright (c) 1991-2002, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
if (as_raw) {
/* sysopen style args, i.e. integer mode and permissions */
STRLEN ix = 0;
- if (num_svs != 0) {
- Perl_croak(aTHX_ "panic: sysopen with multiple args");
- }
- if (rawmode & (O_WRONLY|O_RDWR|O_CREAT
+ int appendtrunc =
+ 0
#ifdef O_APPEND /* Not fully portable. */
- |O_APPEND
+ |O_APPEND
#endif
#ifdef O_TRUNC /* Not fully portable. */
- |O_TRUNC
+ |O_TRUNC
#endif
- ))
- TAINT_PROPER("sysopen");
+ ;
+ int modifyingmode =
+ O_WRONLY|O_RDWR|O_CREAT|appendtrunc;
+ int ismodifying;
+
+ if (num_svs != 0) {
+ Perl_croak(aTHX_ "panic: sysopen with multiple args");
+ }
+ /* It's not always
+
+ O_RDONLY 0
+ O_WRONLY 1
+ O_RDWR 2
+
+ It might be (in OS/390 and Mac OS Classic it is)
+
+ O_WRONLY 1
+ O_RDONLY 2
+ O_RDWR 3
+
+ This means that simple & with O_RDWR would look
+ like O_RDONLY is present. Therefore we have to
+ be more careful.
+ */
+ if ((ismodifying = (rawmode & modifyingmode))) {
+ if ((ismodifying & O_WRONLY) == O_WRONLY ||
+ (ismodifying & O_RDWR) == O_RDWR ||
+ (ismodifying & (O_CREAT|appendtrunc)))
+ TAINT_PROPER("sysopen");
+ }
mode[ix++] = '#'; /* Marker to openn to use numeric "sysopen" */
#if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)
}
}
if (savefd != fd) {
- Pid_t pid;
- SV *sv;
/* Still a small can-of-worms here if (say) PerlIO::Scalar
is assigned to (say) STDOUT - for now let dup2() fail
and provide the error
}
#ifdef VMS
if (savefd != PerlIO_fileno(PerlIO_stdin())) {
- char newname[FILENAME_MAX+1];
- if (PerlIO_getname(fp, newname)) {
- if (fd == PerlIO_fileno(PerlIO_stdout())) Perl_vmssetuserlnm(aTHX_ "SYS$OUTPUT", newname);
- if (fd == PerlIO_fileno(PerlIO_stderr())) Perl_vmssetuserlnm(aTHX_ "SYS$ERROR", newname);
- }
+ char newname[FILENAME_MAX+1];
+ if (PerlIO_getname(fp, newname)) {
+ if (fd == PerlIO_fileno(PerlIO_stdout()))
+ Perl_vmssetuserlnm(aTHX_ "SYS$OUTPUT", newname);
+ if (fd == PerlIO_fileno(PerlIO_stderr()))
+ Perl_vmssetuserlnm(aTHX_ "SYS$ERROR", newname);
+ }
}
#endif
- LOCK_FDPID_MUTEX;
- sv = *av_fetch(PL_fdpid,fd,TRUE);
- (void)SvUPGRADE(sv, SVt_IV);
- pid = SvIVX(sv);
- SvIVX(sv) = 0;
- sv = *av_fetch(PL_fdpid,savefd,TRUE);
- UNLOCK_FDPID_MUTEX;
- (void)SvUPGRADE(sv, SVt_IV);
- SvIVX(sv) = pid;
- if (!was_fdopen) {
- PerlIO_close(fp);
+
+#if !defined(WIN32)
+ /* PL_fdpid isn't used on Windows, so avoid this useless work.
+ * XXX Probably the same for a lot of other places. */
+ {
+ Pid_t pid;
+ SV *sv;
+
+ LOCK_FDPID_MUTEX;
+ sv = *av_fetch(PL_fdpid,fd,TRUE);
+ (void)SvUPGRADE(sv, SVt_IV);
+ pid = SvIVX(sv);
+ SvIVX(sv) = 0;
+ sv = *av_fetch(PL_fdpid,savefd,TRUE);
+ (void)SvUPGRADE(sv, SVt_IV);
+ SvIVX(sv) = pid;
+ UNLOCK_FDPID_MUTEX;
+ }
+#endif
+
+ if (was_fdopen) {
+ /* need to close fp without closing underlying fd */
+ int ofd = PerlIO_fileno(fp);
+ int dupfd = PerlLIO_dup(ofd);
+ PerlIO_close(fp);
+ PerlLIO_dup2(dupfd,ofd);
+ PerlLIO_close(dupfd);
}
+ else
+ PerlIO_close(fp);
}
fp = saveifp;
PerlIO_clearerr(fp);
PerlIO_set_cnt(IoIFP(io),-1);
}
if (PL_op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */
- if (!nextargv(PL_argvgv)) /* get another fp handy */
+ if (gv != PL_argvgv || !nextargv(gv)) /* get another fp handy */
return TRUE;
}
else
}
else if (DO_UTF8(sv)) {
if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
- && ckWARN(WARN_UTF8))
+ && ckWARN_d(WARN_UTF8))
{
Perl_warner(aTHX_ WARN_UTF8, "Wide character in print");
}
Perl_croak(aTHX_ "The stat preceding -l _ wasn't an lstat");
return PL_laststatval;
}
- Perl_croak(aTHX_ "You can't use -l on a filehandle");
+ if (ckWARN(WARN_IO)) {
+ Perl_warner(aTHX_ WARN_IO, "Use of -l on filehandle %s",
+ GvENAME(cGVOP_gv));
+ return (PL_laststatval = -1);
+ }
}
PL_laststype = OP_LSTAT;
PL_statgv = Nullgv;
sv = POPs;
PUTBACK;
+ if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV && ckWARN(WARN_IO)) {
+ Perl_warner(aTHX_ WARN_IO, "Use of -l on filehandle %s",
+ GvENAME((GV*) SvRV(sv)));
+ return (PL_laststatval = -1);
+ }
sv_setpv(PL_statname,SvPV(sv, n_a));
PL_laststatval = PerlLIO_lstat(SvPV(sv, n_a),&PL_statcache);
if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && strchr(SvPV(sv, n_a), '\n'))
#endif /* SYSV IPC */
/*
+=head1 IO Functions
+
=for apidoc start_glob
Function called by C<do_readline> to spawn a glob (or do the glob inside