summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perldiag.pod16
-rw-r--r--pod/perlfunc.pod50
-rw-r--r--pp_sys.c9
-rw-r--r--t/io/binmode.t14
-rwxr-xr-xt/io/print.t27
-rwxr-xr-xt/io/read.t27
-rw-r--r--t/lib/warnings/pp_sys9
7 files changed, 113 insertions, 39 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 20d9d91b3f..e59eee3b8b 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -3093,6 +3093,14 @@ are outside the range which can be represented by integers internally.
One possible workaround is to force Perl to use magical string increment
by prepending "0" to your numbers.
+=item read() on closed filehandle %s
+
+(W closed) You tried to read from a closed filehandle.
+
+=item read() on unopened filehandle %s
+
+(W unopened) You tried to read from a filehandle that was never opened.
+
=item readline() on closed filehandle %s
(W closed) The filehandle you're reading from got itself closed sometime
@@ -3567,6 +3575,14 @@ or "my $var" or "our $var".
(F) The final summary message when a C<perl -c> succeeds.
+=item sysread() on closed filehandle %s
+
+(W closed) You tried to read from a closed filehandle.
+
+=item sysread() on unopened filehandle %s
+
+(W unopened) You tried to read from a filehandle that was never opened.
+
=item System V %s is not implemented on this machine
(F) You tried to do something with a function beginning with "sem",
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index d1d6469fc5..8a745efdce 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -453,7 +453,7 @@ Arranges for FILEHANDLE to be read or written in "binary" or "text"
mode on systems where the run-time libraries distinguish between
binary and text files. If FILEHANDLE is an expression, the value is
taken as the name of the filehandle. Returns true on success,
-C<undef> on failure.
+otherwise it returns C<undef> and sets C<$!> (errno).
If LAYER is omitted or specified as C<:raw> the filehandle is made
suitable for passing binary data. This includes turning off possible CRLF
@@ -1805,11 +1805,11 @@ C<formline> always returns true. See L<perlform> for other examples.
=item getc
Returns the next character from the input file attached to FILEHANDLE,
-or the undefined value at end of file, or if there was an error.
-If FILEHANDLE is omitted, reads from STDIN. This is not particularly
-efficient. However, it cannot be used by itself to fetch single
-characters without waiting for the user to hit enter. For that, try
-something more like:
+or the undefined value at end of file, or if there was an error (in
+the latter case C<$!> is set). If FILEHANDLE is omitted, reads from
+STDIN. This is not particularly efficient. However, it cannot be
+used by itself to fetch single characters without waiting for the user
+to hit enter. For that, try something more like:
if ($BSD_STYLE) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
@@ -3767,13 +3767,13 @@ with the wrong number of RANDBITS.)
Attempts to read LENGTH I<characters> of data into variable SCALAR
from the specified FILEHANDLE. Returns the number of characters
-actually read, C<0> at end of file, or undef if there was an error.
-SCALAR will be grown or shrunk to the length actually read. If SCALAR
-needs growing, the new bytes will be zero bytes. An OFFSET may be
-specified to place the read data into some other place in SCALAR than
-the beginning. The call is actually implemented in terms of either
-Perl's or system's fread() call. To get a true read(2) system call,
-see C<sysread>.
+actually read, C<0> at end of file, or undef if there was an error (in
+the latter case C<$!> is also set). SCALAR will be grown or shrunk to
+the length actually read. If SCALAR needs growing, the new bytes will
+be zero bytes. An OFFSET may be specified to place the read data into
+some other place in SCALAR than the beginning. The call is actually
+implemented in terms of either Perl's or system's fread() call. To
+get a true read(2) system call, see C<sysread>.
Note the I<characters>: depending on the status of the filehandle,
either (8-bit) bytes or characters are read. By default all
@@ -5519,14 +5519,15 @@ See L<perlopentut> for a kinder, gentler explanation of opening files.
=item sysread FILEHANDLE,SCALAR,LENGTH
-Attempts to read LENGTH I<characters> of data into variable SCALAR from
-the specified FILEHANDLE, using the system call read(2). It bypasses
-buffered IO, so mixing this with other kinds of reads, C<print>,
-C<write>, C<seek>, C<tell>, or C<eof> can cause confusion because
-stdio usually buffers data. Returns the number of characters actually
-read, C<0> at end of file, or undef if there was an error. SCALAR
-will be grown or shrunk so that the last byte actually read is the
-last byte of the scalar after the read.
+Attempts to read LENGTH I<characters> of data into variable SCALAR
+from the specified FILEHANDLE, using the system call read(2). It
+bypasses buffered IO, so mixing this with other kinds of reads,
+C<print>, C<write>, C<seek>, C<tell>, or C<eof> can cause confusion
+because stdio usually buffers data. Returns the number of characters
+actually read, C<0> at end of file, or undef if there was an error (in
+the latter case C<$!> is also set). SCALAR will be grown or shrunk so
+that the last byte actually read is the last byte of the scalar after
+the read.
Note the I<characters>: depending on the status of the filehandle,
either (8-bit) bytes or characters are read. By default all
@@ -5644,9 +5645,10 @@ is not specified, writes whole SCALAR. It bypasses buffered IO, so
mixing this with reads (other than C<sysread())>, C<print>, C<write>,
C<seek>, C<tell>, or C<eof> may cause confusion because stdio usually
buffers data. Returns the number of characters actually written, or
-C<undef> if there was an error. If the LENGTH is greater than the
-available data in the SCALAR after the OFFSET, only as much data as is
-available will be written.
+C<undef> if there was an error (in this case the errno variable C<$!>
+is also set). If the LENGTH is greater than the available data in the
+SCALAR after the OFFSET, only as much data as is available will be
+written.
An OFFSET may be specified to write the data from some part of the
string other than the beginning. A negative OFFSET specifies writing
diff --git a/pp_sys.c b/pp_sys.c
index 2d27d86355..2939e90551 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -734,6 +734,7 @@ PP(pp_binmode)
if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) {
if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
report_evil_fh(gv, io, PL_op->op_type);
+ SETERRNO(EBADF,RMS_IFI);
RETPUSHUNDEF;
}
@@ -1177,6 +1178,7 @@ PP(pp_getc)
if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)
&& (!io || (!IoIFP(io) && IoTYPE(io) != IoTYPE_WRONLY)))
report_evil_fh(gv, io, PL_op->op_type);
+ SETERRNO(EBADF,RMS_IFI);
RETPUSHUNDEF;
}
TAINT;
@@ -1571,8 +1573,12 @@ PP(pp_sysread)
else
offset = 0;
io = GvIO(gv);
- if (!io || !IoIFP(io))
+ if (!io || !IoIFP(io)) {
+ if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
+ report_evil_fh(gv, io, PL_op->op_type);
+ SETERRNO(EBADF,RMS_IFI);
goto say_undef;
+ }
if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
buffer = SvPVutf8_force(bufsv, blen);
/* UTF8 may not have been set if they are all low bytes */
@@ -1813,6 +1819,7 @@ PP(pp_send)
retval = -1;
if (ckWARN(WARN_CLOSED))
report_evil_fh(gv, io, PL_op->op_type);
+ SETERRNO(EBADF,RMS_IFI);
goto say_undef;
}
diff --git a/t/io/binmode.t b/t/io/binmode.t
index 3775290bf5..f50d0f7fa8 100644
--- a/t/io/binmode.t
+++ b/t/io/binmode.t
@@ -3,12 +3,13 @@
BEGIN {
chdir 't' if -d 't';
@INC = qw(. ../lib);
+ require './test.pl';
}
use Config;
+use Errno;
-require "test.pl";
-plan(tests => 8);
+plan(tests => 9);
ok( binmode(STDERR), 'STDERR made binary' );
if (find PerlIO::Layer 'perlio') {
@@ -28,3 +29,12 @@ if (find PerlIO::Layer 'perlio') {
}
ok( binmode(STDOUT, ":raw"), ' raw' );
ok( binmode(STDOUT, ":crlf"), ' and crlf' );
+
+SKIP: {
+ skip "no EBADF", 1 if (!exists &Errno::EBADF);
+
+ no warnings 'io';
+ $! = 0;
+ binmode(B);
+ ok($! == &Errno::EBADF);
+}
diff --git a/t/io/print.t b/t/io/print.t
index 0578ee6a29..f33aa666a3 100755
--- a/t/io/print.t
+++ b/t/io/print.t
@@ -1,8 +1,16 @@
#!./perl
-print "1..18\n";
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+use strict 'vars';
+use Errno;
+
+print "1..19\n";
-$foo = 'STDOUT';
+my $foo = 'STDOUT';
print $foo "ok 1\n";
print "ok 2\n","ok 3\n","ok 4\n";
@@ -14,7 +22,7 @@ print foo "ok 6\n";
printf "ok %d\n",7;
printf("ok %d\n",8);
-@a = ("ok %d%c",9,ord("\n"));
+my @a = ("ok %d%c",9,ord("\n"));
printf @a;
$a[1] = 10;
@@ -25,10 +33,19 @@ $\ = "\n";
print "ok","11";
-@x = ("ok","12\nok","13\nok");
-@y = ("15\nok","16");
+my @x = ("ok","12\nok","13\nok");
+my @y = ("15\nok","16");
print @x,"14\nok",@y;
{
local $\ = "ok 17\n# null =>[\000]\nok 18\n";
print "";
}
+
+if (!exists &Errno::EBADF) {
+ print "ok 19 # skipped: no EBADF\n";
+} else {
+ $! = 0;
+ print NONEXISTENT "foo";
+ print "not " if ($! != &Errno::EBADF);
+ print "ok 19\n";
+}
diff --git a/t/io/read.t b/t/io/read.t
index b27fde17c7..ea2672dedb 100755
--- a/t/io/read.t
+++ b/t/io/read.t
@@ -2,13 +2,22 @@
# $RCSfile$
-print "1..1\n";
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ require './test.pl';
+}
+
+use strict;
+use Errno;
+
+plan tests => 2;
open(A,"+>a");
print A "_";
seek(A,0,0);
-$b = "abcd";
+my $b = "abcd";
$b = "";
read(A,$b,1,4);
@@ -17,10 +26,14 @@ close(A);
unlink("a");
-if ($b eq "\000\000\000\000_") {
- print "ok 1\n";
-} else { # Probably "\000bcd_"
- print "not ok 1\n";
-}
+is($b,"\000\000\000\000_"); # otherwise probably "\000bcd_"
unlink 'a';
+
+SKIP: {
+ skip "no EBADF", 1 if (!exists &Errno::EBADF);
+
+ $! = 0;
+ read(B,$b,1);
+ ok($! == &Errno::EBADF);
+}
diff --git a/t/lib/warnings/pp_sys b/t/lib/warnings/pp_sys
index be8bb6244c..881e81e624 100644
--- a/t/lib/warnings/pp_sys
+++ b/t/lib/warnings/pp_sys
@@ -389,9 +389,18 @@ my $a = sysread(F, $a,10) ;
no warnings 'io' ;
my $a = sysread(F, $a,10) ;
close F ;
+use warnings 'io' ;
+sysread(F, $a, 10);
+read(F, $a, 10);
+sysread(NONEXISTENT, $a, 10);
+read(NONEXISTENT, $a, 10);
unlink $file ;
EXPECT
Filehandle F opened only for output at - line 12.
+sysread() on closed filehandle F at - line 17.
+read() on closed filehandle F at - line 18.
+sysread() on unopened filehandle NONEXISTENT at - line 19.
+read() on unopened filehandle NONEXISTENT at - line 20.
########
# pp_sys.c [pp_binmode]
use warnings 'unopened' ;