develooper Front page | perl.perl5.porters | Postings from July 2014

Re: [perl #119555] require should not clobber $! and $^E on success(impact on autouse and autodie)

Thread Previous | Thread Next
From:
Craig A. Berry
Date:
July 28, 2014 03:01
Subject:
Re: [perl #119555] require should not clobber $! and $^E on success(impact on autouse and autodie)
Message ID:
CA+vYcVzKAj8Poe0PrP5KN-DYgvmg6qRuiSK2+8sWkNq0J4-BGQ@mail.gmail.com
On Wed, Jul 23, 2014 at 4:00 AM, Christian Millour <cm.perl@abtela.com> wrote:

>
> I can't think of a compelling reason for require to reset $! (and corrupt
> $^E) when successful, instead of restoring their values on entry. And indeed
> it seems to me that dSAVE_ERRNO, SAVE_ERRNO and RESTORE_ERRNO exist in
> perl.h to deal with exactly such situations (and furthermore DTRT wrt. $^E).
> An analysis together with a tentative patch have been proposed here :
> https://rt.perl.org/Public/Bug/Display.html?id=116118#txn-1181050 , and no
> objection were raised.
>
> Could this tentative patch please be updated as needed and applied/smoked ?
> I can formalize a patch if needed but would rather have the original author
> (Craig) get the credit.
>
> Thanks for your time and consideration.

The problem is my patch doesn't actually do what you want.  It does
successfully restore any errno that is set in pp_require while rifling
through @INC trying to find the file being required (assuming the file
is eventually found and successfully opened).

But after it's opened, the file is sent to S_doeval to be compiled,
and somewhere in there errno gets cleared again.  I haven't figured
out exactly how or where yet.  There is a call to CLEAR_ERRSV(), which
has been there in some form since Perl 5.000.  That might be what's
clearing errno, or not; I don't know.  It doesn't look like it would,
but maybe there's magic on PL_errgv or something.

On the surface, it sounds reasonable that a successful require should
leave errno in the state it was in prior to the require.  But nothing
resembling a complete or well-though-out implementation has been
proposed, and any change in this area will involve touching sensitive
bits of the core that have been as they are for twenty years.  A
reformulated patch is attached, but at best it's a partial solution.

For future reference, here's what you get with my patch:

$ type foo.t
@INC = qw(Perl Rules ../lib);

$e = $! = 13; $se = $^E = 13;
print '# $! is ' . (0+$!) . ' $^E is ' . (0+$^E) . "\n";
# Should look in 'Perl', then 'Rules' (unsuccessfully), then '../lib'
require 'version.pm';
print '# $! is ' . (0+$!) . ' $^E is ' . (0+$^E) . "\n";
$ perl foo.t
# $! is 13 $^E is 13
# $! is 0 $^E is 0

So you can see that errno is still cleared in require even though I
restore it after finding version.pm.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About