New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
print doesn't overwrite $! #8919
Comments
From perlbug@der-pepe.deCreated by perlbug@der-pepe.deThis is a bug report for perl from perlbug@der-pepe.de, ----------------------------------------------------------------- open STDOUT, '>/dev/full' or die $!; This script should print "No space left on device" three times (because this is No space left on device at bug.pl line 4. It seems that once "open" sets $! to "No such file or directory", "print" (The script only runs on Unix variants because of the /dev/full thing.) Perl Info
|
From perlbug@der-pepe.deI've tried strace-ing this, and I found that buffering somehow gets write(1, "x", 1) = -1 ENOSPC (No space left on device) Even if I include $|=1 in the loop just before "print", the "xx" is not printed |
From @TuxOn Thu, 31 May 2007 18:39:08 -0700, "perlbug@der-pepe.de (via RT)"
from perldoc perlvar: the key here is *only immediately after the failure*. The last *system*
-- |
The RT System itself - Status changed from 'new' to 'open' |
From @demerphqOn 6/1/07, H.Merijn Brand <h.m.brand@xs4all.nl> wrote:
Since stdout is autoflushing each call to print should result in a yves -- |
From mail@der-pepe.de
This bug is still in perl 5.8.8 and 5.10.0 and blead. I think I have fixed this bug. After giving this careful thought, I The problem is: pp_print calls do_print. If that is successful *and* the file-handle is This has another implication: When you get an error from print and then I've also added tests for both the $! thing and the empty-string thing. The tests don't use /dev/full as in the original report because I don't Regards, |
From @gisleOn Aug 18, 2008, at 18:40, Christoph Bussenius via RT wrote:
Is there any significance to the 'open my $f' statement here?
I don't think the patch is acceptable. If print fails the error open(my $fh, ">", $file) || die "Can't open With your patch the first print could fail and then the second could --Gisle
|
From lists@der-pepe.deOn Tue, Aug 19, 2008 at 09:45:24AM +0200, Gisle Aas wrote:
Yes, it sets $! to ENOENT (No such file or directory), to demonstrate
(This was my original report for bug #43097).
Hm, I see your point. I'll think about it, thanks. Christoph |
From lists@der-pepe.de
I've added a new patch below. Instead of clearing the error flag, it On Tue, Aug 19, 2008 at 09:45:24AM +0200, Gisle Aas wrote:
This piece of code is still a bit problematic in my opinion. In close's I think the only way to get this to work properly is to save errno along Regards, Inline Patch--- perl-5.10.0/doio.c 2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0-debug/doio.c 2008-09-08 12:32:57.325273275 +0200
@@ -1247,7 +1247,7 @@
if (len && (PerlIO_write(fp,tmps,len) == 0))
happy = FALSE;
Safefree(tmpbuf);
- return happy ? !PerlIO_error(fp) : FALSE;
+ return happy;
}
}
--- perl-5.10.0/t/io/print.t 2007-12-18 11:47:08.000000000 +0100
+++ perl-5.10.0-debug/t/io/print.t 2008-08-18 17:49:05.093301791 +0200
@@ -6,10 +6,10 @@
}
use strict 'vars';
-eval 'use Errno';
+eval 'use Errno; use IO::Handle';
die $@ if $@ and !$ENV{PERL_CORE_MINITEST};
-print "1..21\n";
+print "1..24\n";
my $foo = 'STDOUT';
print $foo "ok 1\n";
@@ -65,3 +65,31 @@
map print(+()), ('')x68;
print "ok 21\n";
}
+
+# Create a closed pipe to test print's error reporting
+# See bug #43097
+if (exists $IO::Handle::{autoflush}) {
+ if (pipe my $rpipe, my $wpipe) {
+ eval { $SIG{PIPE} = 'IGNORE'; };
+ close $rpipe or die $!;
+ $wpipe->autoflush(1);
+
+ # printing with autoflush to a closed pipe must fail
+ print $wpipe "xy" and print "not ";
+ print "ok 22\n";
+
+ open my $h, '< /nonexistent' and die '/nonexistent exists';
+
+ print $wpipe "xy";
+ print 'not ' if $!{ENOENT};
+ print "ok 23\n";
+
+ # Printing an empty string must not fail
+ print $wpipe '' or print 'not ';
+ print "ok 24\n";
+ } else {
+ print "ok $_ # skipped: cannot pipe ($!)\n" for 22..24;
+ }
+} else {
+ print "ok $_ # skipped: no autoflush\n" for 22..24;
+} |
From @tonycozOn Mon Sep 08 04:07:40 2008, lists@der-pepe.de wrote:
I believe this change is dangerous under the following circumstances: - no autoflush to a full filesystem This produces output with some content missing. A patch that saves errno per file handle would be less dangerous, but I Tony |
Migrated from rt.perl.org#43097 (status was 'open')
Searchable as RT43097$
The text was updated successfully, but these errors were encountered: