diff options
-rw-r--r-- | pod/perldiag.pod | 16 | ||||
-rw-r--r-- | pod/perlfunc.pod | 50 | ||||
-rw-r--r-- | pp_sys.c | 9 | ||||
-rw-r--r-- | t/io/binmode.t | 14 | ||||
-rwxr-xr-x | t/io/print.t | 27 | ||||
-rwxr-xr-x | t/io/read.t | 27 | ||||
-rw-r--r-- | t/lib/warnings/pp_sys | 9 |
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 @@ -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' ; |