/* doio.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, 2005, 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.
* chattering, into calmer and more level reaches."
*/
+/* This file contains functions that do the actual I/O on behalf of ops.
+ * For example, pp_print() calls the do_print() function in this file for
+ * each argument needing printing.
+ */
+
#include "EXTERN.h"
#define PERL_IN_DOIO_C
#include "perl.h"
# define OPEN_EXCL 0
#endif
+#define PERL_MODE_MAX 8
+#define PERL_FLAGS_MAX 10
+
#include <signal.h>
bool
bool was_fdopen = FALSE;
bool in_raw = 0, in_crlf = 0, out_raw = 0, out_crlf = 0;
char *type = NULL;
- char mode[8]; /* stdio file mode ("r\0", "rb\0", "r+b\0" etc.) */
+ char mode[PERL_MODE_MAX]; /* stdio file mode ("r\0", "rb\0", "r+b\0" etc.) */
SV *namesv;
Zero(mode,sizeof(mode),char);
errno = EPIPE;
goto say_false;
}
- if (strNE(name,"-") || num_svs)
+ if ((*name == '-' && name[1] == '\0') || num_svs)
TAINT_ENV();
TAINT_PROPER("piped open");
if (!num_svs && name[len-1] == '|') {
}
mode[0] = 'w';
writing = 1;
+#ifdef HAS_STRLCAT
+ if (out_raw)
+ strlcat(mode, "b", PERL_MODE_MAX);
+ 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
if (num_svs > 1) {
fp = PerlProc_popen_list(mode, num_svs, svp);
}
}
writing = 1;
+#ifdef HAS_STRLCAT
+ if (out_raw)
+ strlcat(mode, "b", PERL_MODE_MAX);
+ 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
if (*type == '&') {
duplicity:
dodup = PERLIO_DUP_FD;
/*SUPPRESS 530*/
for (type++; isSPACE(*type); type++) ;
mode[0] = 'r';
+#ifdef HAS_STRLCAT
+ if (in_raw)
+ strlcat(mode, "b", PERL_MODE_MAX);
+ 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
if (*type == '&') {
goto duplicity;
}
errno = EPIPE;
goto say_false;
}
- if (strNE(name,"-") || num_svs)
+ if (!(*name == '-' && name[1] == '\0') || num_svs)
TAINT_ENV();
TAINT_PROPER("piped open");
mode[0] = 'r';
+
+#ifdef HAS_STRLCAT
+ if (in_raw)
+ strlcat(mode, "b", PERL_MODE_MAX);
+ 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
+
if (num_svs > 1) {
fp = PerlProc_popen_list(mode,num_svs,svp);
}
/*SUPPRESS 530*/
for (; isSPACE(*name); name++) ;
mode[0] = 'r';
+
+#ifdef HAS_STRLCAT
+ if (in_raw)
+ strlcat(mode, "b", PERL_MODE_MAX);
+ else if (in_crlf)
+ strlcat(mode, "t", PERL_MODE_MAX);
+#else
if (in_raw)
strcat(mode, "b");
else if (in_crlf)
strcat(mode, "t");
- if (strEQ(name,"-")) {
+#endif
+
+ if (*name == '-' && name[1] == '\0') {
fp = PerlIO_stdin();
IoTYPE(io) = IoTYPE_STD;
}
if (PL_filemode & (S_ISUID|S_ISGID)) {
PerlIO_flush(IoIFP(GvIOn(PL_argvoutgv))); /* chmod must follow last write */
#ifdef HAS_FCHMOD
- (void)fchmod(PL_lastfd,PL_filemode);
+ if (PL_lastfd != -1)
+ (void)fchmod(PL_lastfd,PL_filemode);
#else
(void)PerlLIO_chmod(PL_oldname,PL_filemode);
#endif
}
+ PL_lastfd = -1;
PL_filemode = 0;
if (!GvAV(gv))
return Nullfp;
retval = TRUE;
else {
if (IoOFP(io) && IoOFP(io) != IoIFP(io)) { /* a socket */
- retval = (PerlIO_close(IoOFP(io)) != EOF);
+ bool prev_err = PerlIO_error(IoOFP(io));
+ retval = (PerlIO_close(IoOFP(io)) != EOF && !prev_err);
PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */
}
- else
- retval = (PerlIO_close(IoIFP(io)) != EOF);
+ else {
+ bool prev_err = PerlIO_error(IoIFP(io));
+ retval = (PerlIO_close(IoIFP(io)) != EOF && !prev_err);
+ }
}
IoOFP(io) = IoIFP(io) = Nullfp;
}
if (*s == ':') {
switch (s[1]) {
case 'r':
- if (len > 3 && strnEQ(s+1, "raw", 3)
+ if (s[2] == 'a' && s[3] == 'w'
&& (!s[4] || s[4] == ':' || isSPACE(s[4])))
{
mode = O_BINARY;
}
/* FALL THROUGH */
case 'c':
- if (len > 4 && strnEQ(s+1, "crlf", 4)
+ if (s[2] == 'r' && s[3] == 'l' && s[4] == 'f'
&& (!s[5] || s[5] == ':' || isSPACE(s[5])))
{
mode = O_TEXT;
#ifndef PERLIO_LAYERS
Perl_croak(aTHX_ "IO layers (like '%.*s') unavailable", end-s, s);
#else
+ len -= end-s;
s = end;
#endif
}
switch (SvTYPE(sv)) {
case SVt_NULL:
if (ckWARN(WARN_UNINITIALIZED))
- report_uninit();
+ report_uninit(sv);
return TRUE;
case SVt_IV:
if (SvIOK(sv)) {
return (PL_laststatval = -1);
}
}
+ else if (PL_op->op_private & OPpFT_STACKED) {
+ return PL_laststatval;
+ }
else {
SV* sv = POPs;
char *s;
}
}
+static char no_prev_lstat[] = "The stat preceding -l _ wasn't an lstat";
+
I32
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)) {
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;
#ifdef CSH
{
- char flags[10];
+ 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
s = cmd+PL_cshlen+3;
if (*s == 'f') {
s++;
+#ifdef HAS_STRLCPY
+ strlcat(flags, "f", PERL_FLAGS_MAX);
+#else
strcat(flags,"f");
+#endif
}
if (*s == ' ')
s++;