This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Have close() set $! and $^E
authorFather Chrysostomos <sprout@cpan.org>
Thu, 18 Sep 2014 04:42:52 +0000 (21:42 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 3 Nov 2014 02:23:43 +0000 (18:23 -0800)
commitf4725fad1a6349bcfadca13ee4398f61799a29d0
treecb6f3c1c72090e3a51cf3ffbcc46656f90b1d18c
parent2561bebf29571d3984d60b857a0b6a1d7b96523d
Have close() set $! and $^E

This is what we used to get when close reported an error after a print
failure (‘Disk Image’ is a small disk image I made):

$ ./miniperl -Ilib -e 'open fh, ">/Volumes/Disk Image/foo"; print fh "x"x1000, "\n" for 1..50; unlink "ntoeuhnteo"; warn $!; close fh or die "error closing: $!"'
No such file or directory at -e line 1.
error closing: No such file or directory at -e line 1.

Notice how the value of $! as set by unlink is still present after
close fails.  So that means after close returns false, you can’t
depend on $! to have the reason for the failure, because it might come
from an unrelated system call.  Remove the ‘unlink’ statement and you
get ‘No space left on device’.

As of this commit, the output is more helpful:

$ ./miniperl -Ilib -e 'open fh, ">/Volumes/Disk Image/foo"; print fh "x"x1000, "\n" for 1..50; unlink "ntoeuhnteo"; warn $!; close fh or die "error closing: $!"'
No such file or directory at -e line 1.
error closing: No space left on device at -e line 1.

Three commits ago, I/O errors started recording the error number in
the handle itself.  Now ‘close’ restores $! and $^E to the values they
were when the I/O error associated with the closed handle occurred.

This is related to ticket #57512.
doio.c