/* doio.c
*
- * Copyright (c) 1991-2001, Larry Wall
+ * Copyright (c) 1991-2003, 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)
STRLEN olen = len;
char *tend;
int dodup = 0;
+ PerlIO *that_fp = NULL;
type = savepvn(name, len);
tend = type+len;
if (num_svs) {
/* New style explict name, type is just mode and discipline/layer info */
STRLEN l = 0;
+#ifdef USE_STDIO
+ if (SvROK(*svp) && !strchr(name,'&')) {
+ if (ckWARN(WARN_IO))
+ Perl_warner(aTHX_ packWARN(WARN_IO),
+ "Can't open a reference");
+ SETERRNO(EINVAL, LIB_INVARG);
+ goto say_false;
+ }
+#endif /* USE_STDIO */
name = SvOK(*svp) ? SvPV(*svp, l) : "";
len = (I32)l;
name = savepvn(name, len);
if (*name == '\0') {
/* command is missing 19990114 */
if (ckWARN(WARN_PIPE))
- Perl_warner(aTHX_ WARN_PIPE, "Missing command in piped open");
+ Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
errno = EPIPE;
goto say_false;
}
if (!num_svs && name[len-1] == '|') {
name[--len] = '\0' ;
if (ckWARN(WARN_PIPE))
- Perl_warner(aTHX_ WARN_PIPE, "Can't open bidirectional pipe");
+ Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't open bidirectional pipe");
}
mode[0] = 'w';
writing = 1;
else {
fp = PerlProc_popen(name,mode);
}
+ if (num_svs) {
+ if (*type) {
+ if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
+ goto say_false;
+ }
+ }
+ }
}
else if (*type == IoTYPE_WRONLY) {
TAINT_PROPER("open");
if (*type == '&') {
duplicity:
- dodup = 1;
+ dodup = PERLIO_DUP_FD;
type++;
if (*type == '=') {
dodup = 0;
if (num_svs > 1) {
Perl_croak(aTHX_ "More than one argument to '%c&' open",IoTYPE(io));
}
- if (num_svs && SvIOK(*svp)) {
+ /*SUPPRESS 530*/
+ for (; isSPACE(*type); type++) ;
+ if (num_svs && (SvIOK(*svp) || (SvPOK(*svp) && looks_like_number(*svp)))) {
fd = SvUV(*svp);
+ num_svs = 0;
}
else if (isDIGIT(*type)) {
- /*SUPPRESS 530*/
- for (; isSPACE(*type); type++) ;
fd = atoi(type);
}
else {
}
else {
GV *thatgv;
- /*SUPPRESS 530*/
- for (; isSPACE(*type); type++) ;
thatgv = gv_fetchpv(type,FALSE,SVt_PVIO);
thatio = GvIO(thatgv);
}
if (!thatio) {
#ifdef EINVAL
- SETERRNO(EINVAL,SS$_IVCHAN);
+ SETERRNO(EINVAL,SS_IVCHAN);
#endif
goto say_false;
}
- if (IoIFP(thatio)) {
- PerlIO *fp = IoIFP(thatio);
+ if ((that_fp = IoIFP(thatio))) {
/* Flush stdio buffer before dup. --mjd
* Unfortunately SEEK_CURing 0 seems to
* be optimized away on most platforms;
/* sfio fails to clear error on next
sfwrite, contrary to documentation.
-- Nick Clark */
- if (PerlIO_seek(fp, 0, SEEK_CUR) == -1)
- PerlIO_clearerr(fp);
+ if (PerlIO_seek(that_fp, 0, SEEK_CUR) == -1)
+ PerlIO_clearerr(that_fp);
#endif
/* On the other hand, do all platforms
* take gracefully to flushing a read-only
* filehandle? Perhaps we should do
* fsetpos(src)+fgetpos(dst)? --nik */
- PerlIO_flush(fp);
- fd = PerlIO_fileno(fp);
+ PerlIO_flush(that_fp);
+ fd = PerlIO_fileno(that_fp);
/* When dup()ing STDIN, STDOUT or STDERR
* explicitly set appropriate access mode */
- if (IoIFP(thatio) == PerlIO_stdout()
- || IoIFP(thatio) == PerlIO_stderr())
+ if (that_fp == PerlIO_stdout()
+ || that_fp == PerlIO_stderr())
IoTYPE(io) = IoTYPE_WRONLY;
- else if (IoIFP(thatio) == PerlIO_stdin())
+ else if (that_fp == PerlIO_stdin())
IoTYPE(io) = IoTYPE_RDONLY;
/* When dup()ing a socket, say result is
* one as well */
else
fd = -1;
}
- if (dodup)
- fd = PerlLIO_dup(fd);
- else
- was_fdopen = TRUE;
if (!num_svs)
type = Nullch;
- if (!(fp = PerlIO_openn(aTHX_ type,mode,fd,0,0,NULL,num_svs,svp))) {
+ if (that_fp) {
+ fp = PerlIO_fdupopen(aTHX_ that_fp, NULL, dodup);
+ }
+ else {
if (dodup)
- PerlLIO_close(fd);
+ fd = PerlLIO_dup(fd);
+ else
+ was_fdopen = TRUE;
+ if (!(fp = PerlIO_openn(aTHX_ type,mode,fd,0,0,NULL,num_svs,svp))) {
+ if (dodup)
+ PerlLIO_close(fd);
+ }
}
}
} /* & */
else {
- if (num_svs > 1) {
- Perl_croak(aTHX_ "More than one argument to '>' open");
- }
/*SUPPRESS 530*/
for (; isSPACE(*type); type++) ;
if (*type == IoTYPE_STD && (!type[1] || isSPACE(type[1]) || type[1] == ':')) {
type++;
fp = PerlIO_stdout();
IoTYPE(io) = IoTYPE_STD;
+ if (num_svs > 1) {
+ Perl_croak(aTHX_ "More than one argument to '>%c' open",IoTYPE_STD);
+ }
}
else {
if (!num_svs) {
} /* !& */
}
else if (*type == IoTYPE_RDONLY) {
- if (num_svs > 1) {
- Perl_croak(aTHX_ "More than one argument to '<' open");
- }
/*SUPPRESS 530*/
for (type++; isSPACE(*type); type++) ;
mode[0] = 'r';
type++;
fp = PerlIO_stdin();
IoTYPE(io) = IoTYPE_STD;
+ if (num_svs > 1) {
+ Perl_croak(aTHX_ "More than one argument to '<%c' open",IoTYPE_STD);
+ }
}
else {
if (!num_svs) {
if (*name == '\0') {
/* command is missing 19990114 */
if (ckWARN(WARN_PIPE))
- Perl_warner(aTHX_ WARN_PIPE, "Missing command in piped open");
+ Perl_warner(aTHX_ packWARN(WARN_PIPE), "Missing command in piped open");
errno = EPIPE;
goto say_false;
}
fp = PerlProc_popen(name,mode);
}
IoTYPE(io) = IoTYPE_PIPE;
+ if (num_svs) {
+ for (; isSPACE(*type); type++) ;
+ if (*type) {
+ if (PerlIO_apply_layers(aTHX_ fp, mode, type) != 0) {
+ goto say_false;
+ }
+ }
+ }
}
else {
if (num_svs)
}
if (!fp) {
if (ckWARN(WARN_NEWLINE) && IoTYPE(io) == IoTYPE_RDONLY && strchr(name, '\n'))
- Perl_warner(aTHX_ WARN_NEWLINE, PL_warn_nl, "open");
+ Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
goto say_false;
}
if (ckWARN(WARN_IO)) {
if ((IoTYPE(io) == IoTYPE_RDONLY) &&
(fp == PerlIO_stdout() || fp == PerlIO_stderr())) {
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle STD%s opened only for input",
- (fp == PerlIO_stdout()) ? "OUT" : "ERR");
+ Perl_warner(aTHX_ packWARN(WARN_IO),
+ "Filehandle STD%s reopened as %s only for input",
+ ((fp == PerlIO_stdout()) ? "OUT" : "ERR"),
+ GvENAME(gv));
}
else if ((IoTYPE(io) == IoTYPE_WRONLY) && fp == PerlIO_stdin()) {
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle STDIN opened only for output");
+ Perl_warner(aTHX_ packWARN(WARN_IO),
+ "Filehandle STDIN reopened as %s only for output",
+ GvENAME(gv));
}
}
- if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD &&
- /* FIXME: This next term is a hack to avoid fileno on PerlIO::Scalar */
- !(num_svs && SvROK(*svp))) {
- if (PerlLIO_fstat(PerlIO_fileno(fp),&PL_statbuf) < 0) {
- (void)PerlIO_close(fp);
+ 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.
+ */
+ if (IoTYPE(io) && IoTYPE(io) != IoTYPE_PIPE && IoTYPE(io) != IoTYPE_STD && fd >= 0) {
+ if (PerlLIO_fstat(fd,&PL_statbuf) < 0) {
+ /* If PerlIO claims to have fd we had better be able to fstat() it. */
+ (void) PerlIO_close(fp);
goto say_false;
}
#ifndef PERL_MICRO
&& IoTYPE(io) != IoTYPE_WRONLY /* Dups of STD* filehandles already have */
&& IoTYPE(io) != IoTYPE_RDONLY /* type so they aren't marked as sockets */
) { /* on OS's that return 0 on fstat()ed pipe */
- char tmpbuf[256];
- Sock_size_t buflen = sizeof tmpbuf;
- if (PerlSock_getsockname(PerlIO_fileno(fp), (struct sockaddr *)tmpbuf,
- &buflen) >= 0
- || errno != ENOTSOCK)
- IoTYPE(io) = IoTYPE_SOCKET; /* some OS's return 0 on fstat()ed socket */
- /* but some return 0 for streams too, sigh */
+ char tmpbuf[256];
+ Sock_size_t buflen = sizeof tmpbuf;
+ if (PerlSock_getsockname(fd, (struct sockaddr *)tmpbuf, &buflen) >= 0
+ || errno != ENOTSOCK)
+ IoTYPE(io) = IoTYPE_SOCKET; /* some OS's return 0 on fstat()ed socket */
+ /* but some return 0 for streams too, sigh */
}
+#endif /* HAS_SOCKET */
#endif /* !PERL_MICRO */
-#endif
}
+
+ /* Eeek - FIXME !!!
+ * If this is a standard handle we discard all the layer stuff
+ * and just dup the fd into whatever was on the handle before !
+ */
+
if (saveifp) { /* must use old fp? */
/* If fd is less that PL_maxsysfd i.e. STDIN..STDERR
then dup the new fileno down
*/
- fd = PerlIO_fileno(fp);
if (saveofp) {
PerlIO_flush(saveofp); /* emulate PerlIO_close() */
if (saveofp != saveifp) { /* was a socket? */
}
}
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
+ */
if (PerlLIO_dup2(fd, savefd) < 0) {
(void)PerlIO_close(fp);
goto say_false;
}
#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)
+
+#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);
+ fd = PerlIO_fileno(fp);
}
#if defined(HAS_FCNTL) && defined(F_SETFD)
- {
+ if (fd >= 0) {
int save_errno = errno;
- fd = PerlIO_fileno(fp);
fcntl(fd,F_SETFD,fd > PL_maxsysfd); /* can change errno */
errno = save_errno;
}
IoFLAGS(io) &= ~IOf_NOLINE;
if (writing) {
if (IoTYPE(io) == IoTYPE_SOCKET
- || (IoTYPE(io) == IoTYPE_WRONLY && S_ISCHR(PL_statbuf.st_mode)) ) {
- mode[0] = 'w';
- if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,mode,PerlIO_fileno(fp),0,0,NULL,num_svs,svp))) {
+ || (IoTYPE(io) == IoTYPE_WRONLY && fd >= 0 && S_ISCHR(PL_statbuf.st_mode)) ) {
+ char *s = mode;
+ if (*s == 'I' || *s == '#')
+ s++;
+ *s = 'w';
+ if (!(IoOFP(io) = PerlIO_openn(aTHX_ type,s,fd,0,0,NULL,0,svp))) {
PerlIO_close(fp);
IoIFP(io) = Nullfp;
goto say_false;
#endif
}
PL_filemode = 0;
+ if (!GvAV(gv))
+ return Nullfp;
while (av_len(GvAV(gv)) >= 0) {
STRLEN oldlen;
sv = av_shift(GvAV(gv));
filegid = PL_statbuf.st_gid;
if (!S_ISREG(PL_filemode)) {
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE,
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
"Can't do inplace edit: %s is not a regular file",
PL_oldname );
do_close(gv,FALSE);
sv_catpv(sv,PL_inplace);
}
#ifndef FLEXFILENAMES
- if (PerlLIO_stat(SvPVX(sv),&PL_statbuf) >= 0
- && PL_statbuf.st_dev == filedev
- && PL_statbuf.st_ino == fileino
+ if ((PerlLIO_stat(SvPVX(sv),&PL_statbuf) >= 0
+ && PL_statbuf.st_dev == filedev
+ && PL_statbuf.st_ino == fileino)
#ifdef DJGPP
- || (_djstat_fail_bits & _STFAIL_TRUENAME)!=0
+ || ((_djstat_fail_bits & _STFAIL_TRUENAME)!=0)
#endif
)
{
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE,
- "Can't do inplace edit: %s would not be unique",
- SvPVX(sv));
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
+ "Can't do inplace edit: %"SVf" would not be unique",
+ sv);
do_close(gv,FALSE);
continue;
}
#endif
#ifdef HAS_RENAME
-#if !defined(DOSISH) && !defined(__CYGWIN__)
+#if !defined(DOSISH) && !defined(__CYGWIN__) && !defined(EPOC)
if (PerlLIO_rename(PL_oldname,SvPVX(sv)) < 0) {
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE,
- "Can't rename %s to %s: %s, skipping file",
- PL_oldname, SvPVX(sv), Strerror(errno) );
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
+ "Can't rename %s to %"SVf": %s, skipping file",
+ PL_oldname, sv, Strerror(errno) );
do_close(gv,FALSE);
continue;
}
(void)UNLINK(SvPVX(sv));
if (link(PL_oldname,SvPVX(sv)) < 0) {
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE,
- "Can't rename %s to %s: %s, skipping file",
- PL_oldname, SvPVX(sv), Strerror(errno) );
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
+ "Can't rename %s to %"SVf": %s, skipping file",
+ PL_oldname, sv, Strerror(errno) );
do_close(gv,FALSE);
continue;
}
# ifndef VMS /* Don't delete; use automatic file versioning */
if (UNLINK(PL_oldname) < 0) {
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE,
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
"Can't remove %s: %s, skipping file",
PL_oldname, Strerror(errno) );
do_close(gv,FALSE);
#endif
{
if (ckWARN_d(WARN_INPLACE))
- Perl_warner(aTHX_ WARN_INPLACE, "Can't do inplace edit on %s: %s",
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't do inplace edit on %s: %s",
PL_oldname, Strerror(errno) );
do_close(gv,FALSE);
continue;
if (PerlLIO_stat(PL_oldname, &PL_statbuf) >= 0
&& !S_ISREG(PL_statbuf.st_mode))
{
- Perl_warner(aTHX_ WARN_INPLACE,
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE),
"Can't do inplace edit: %s is not a regular file",
PL_oldname);
}
else
- Perl_warner(aTHX_ WARN_INPLACE, "Can't open %s: %s",
+ Perl_warner(aTHX_ packWARN(WARN_INPLACE), "Can't open %s: %s",
PL_oldname, Strerror(eno));
}
}
if (PerlProc_pipe(fd) < 0)
goto badexit;
- IoIFP(rstio) = PerlIO_fdopen(fd[0], "r");
- IoOFP(wstio) = PerlIO_fdopen(fd[1], "w");
+ IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
+ IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
+ IoOFP(rstio) = IoIFP(rstio);
IoIFP(wstio) = IoOFP(wstio);
IoTYPE(rstio) = IoTYPE_RDONLY;
IoTYPE(wstio) = IoTYPE_WRONLY;
gv = PL_argvgv;
if (!gv || SvTYPE(gv) != SVt_PVGV) {
if (not_implicit)
- SETERRNO(EBADF,SS$_IVCHAN);
+ SETERRNO(EBADF,SS_IVCHAN);
return FALSE;
}
io = GvIO(gv);
if (not_implicit) {
if (ckWARN(WARN_UNOPENED)) /* no check for closed here */
report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
+ SETERRNO(EBADF,SS_IVCHAN);
}
return FALSE;
}
IoOFP(io) = IoIFP(io) = Nullfp;
}
else if (not_implicit) {
- SETERRNO(EBADF,SS$_IVCHAN);
+ SETERRNO(EBADF,SS_IVCHAN);
}
return retval;
if (!io)
return TRUE;
else if (ckWARN(WARN_IO) && (IoTYPE(io) == IoTYPE_WRONLY))
- {
- /* integrate to report_evil_fh()? */
- char *name = NULL;
- if (isGV(gv)) {
- SV* sv = sv_newmortal();
- gv_efullname4(sv, gv, Nullch, FALSE);
- name = SvPV_nolen(sv);
- }
- if (name && *name)
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle %s opened only for output", name);
- else
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle opened only for output");
- }
+ report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY);
while (IoIFP(io)) {
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
}
if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,RMS$_IFI);
+ SETERRNO(EBADF,RMS_IFI);
return (Off_t)-1;
}
}
if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,RMS$_IFI);
+ SETERRNO(EBADF,RMS_IFI);
return FALSE;
}
return PerlLIO_lseek(PerlIO_fileno(fp), pos, whence);
if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,RMS$_IFI);
+ SETERRNO(EBADF,RMS_IFI);
return (Off_t)-1;
}
/* The old body of this is now in non-LAYER part of perlio.c
* This is a stub for any XS code which might have been calling it.
*/
- char *name = (O_BINARY != O_TEXT && !(mode & O_BINARY)) ? ":crlf" : ":raw";
+ char *name = ":raw";
+#ifdef PERLIO_USING_CRLF
+ if (!(mode & O_BINARY))
+ name = ":crlf";
+#endif
return PerlIO_binmode(aTHX_ fp, iotype, mode, name);
}
Off_t length; /* length to set file to */
{
struct flock fl;
- struct stat filebuf;
+ Stat_t filebuf;
if (PerlLIO_fstat(fd, &filebuf) < 0)
return -1;
default:
if (PerlIO_isutf8(fp)) {
if (!SvUTF8(sv))
- sv_utf8_upgrade(sv = sv_mortalcopy(sv));
+ sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
+ SV_GMAGIC|SV_UTF8_NO_ENCODING);
}
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_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
}
}
tmps = SvPV(sv, len);
else {
SV* sv = POPs;
char *s;
- STRLEN n_a;
+ STRLEN len;
PUTBACK;
if (SvTYPE(sv) == SVt_PVGV) {
gv = (GV*)sv;
goto do_fstat;
}
- s = SvPV(sv, n_a);
+ s = SvPV(sv, len);
PL_statgv = Nullgv;
- sv_setpv(PL_statname, s);
+ sv_setpvn(PL_statname, s, len);
+ s = SvPVX(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'))
- Perl_warner(aTHX_ WARN_NEWLINE, PL_warn_nl, "stat");
+ Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
return PL_laststatval;
}
}
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_ packWARN(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_ packWARN(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'))
- Perl_warner(aTHX_ WARN_NEWLINE, PL_warn_nl, "lstat");
+ Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
return PL_laststatval;
}
else
PerlProc_execvp(PL_Argv[0],EXEC_ARGV_CAST(PL_Argv));
if (ckWARN(WARN_EXEC))
- Perl_warner(aTHX_ WARN_EXEC, "Can't exec \"%s\": %s",
+ Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
(really ? tmps : PL_Argv[0]), Strerror(errno));
if (do_report) {
int e = errno;
int e = errno;
if (ckWARN(WARN_EXEC))
- Perl_warner(aTHX_ WARN_EXEC, "Can't exec \"%s\": %s",
+ Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't exec \"%s\": %s",
PL_Argv[0], Strerror(errno));
if (do_report) {
PerlLIO_write(fd, (void*)&e, sizeof(int));
if (mark == sp)
break;
s = SvPVx(*++mark, n_a);
- if (isUPPER(*s)) {
+ if (isALPHA(*s)) {
if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
s += 3;
- if (!(val = whichsig(s)))
+ if ((val = whichsig(s)) < 0)
Perl_croak(aTHX_ "Unrecognized signal name \"%s\"",s);
}
else
SV* modified = *++mark;
void * utbufp = &utbuf;
- /* be like C, and if both times are undefined, let the C
- library figure out what to do. This usually means
- "current time" */
+ /* Be like C, and if both times are undefined, let the C
+ * library figure out what to do. This usually means
+ * "current time". */
if ( accessed == &PL_sv_undef && modified == &PL_sv_undef )
- utbufp = NULL;
-
- Zero(&utbuf, sizeof utbuf, char);
+ utbufp = NULL;
+ else {
+ Zero(&utbuf, sizeof utbuf, char);
#ifdef BIG_TIME
- utbuf.actime = (Time_t)SvNVx(accessed); /* time accessed */
- utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
+ utbuf.actime = (Time_t)SvNVx(accessed); /* time accessed */
+ utbuf.modtime = (Time_t)SvNVx(modified); /* time modified */
#else
- utbuf.actime = (Time_t)SvIVx(accessed); /* time accessed */
- utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
+ utbuf.actime = (Time_t)SvIVx(accessed); /* time accessed */
+ utbuf.modtime = (Time_t)SvIVx(modified); /* time modified */
#endif
- APPLY_TAINT_PROPER();
+ }
+ APPLY_TAINT_PROPER();
tot = sp - mark;
while (++mark <= sp) {
char *name = SvPVx(*mark, n_a);
opbuf = SvPV(opstr, opsize);
if (opsize < 3 * SHORTSIZE
|| (opsize % (3 * SHORTSIZE))) {
- SETERRNO(EINVAL,LIB$_INVARG);
+ SETERRNO(EINVAL,LIB_INVARG);
return -1;
}
SETERRNO(0,0);
if (shmctl(id, IPC_STAT, &shmds) == -1)
return -1;
if (mpos < 0 || msize < 0 || mpos + msize > shmds.shm_segsz) {
- SETERRNO(EFAULT,SS$_ACCVIO); /* can't do as caller requested */
+ SETERRNO(EFAULT,SS_ACCVIO); /* can't do as caller requested */
return -1;
}
shm = (char *)shmat(id, (char*)NULL, (optype == OP_SHMREAD) ? SHM_RDONLY : 0);
#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
}
if (cxt) (void)lib$find_file_end(&cxt);
if (ok && sts != RMS$_NMF &&
- sts != RMS$_DNF && sts != RMS$_FNF) ok = 0;
+ sts != RMS$_DNF && sts != RMS_FNF) ok = 0;
if (!ok) {
if (!(sts & 1)) {
SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);