On Jul 15, 2014, at 2:57 AM, john.d...@compinia.de wrote:

> On 15.07.2014 03:24, Jeremy Begg wrote:
>> Hi John,
>> 
>>> we came across this curious behaviour. Here enclosed please find a
>>> reproducer.
>> 
>> I see the same behaviour -- and also on Perl 5.10.0, so it's not new.
>> Looks like inappropriate propagation of the last VMS error code.
>> 
> I have just joined this distribution list, so what do you reckon are the 
> chances that this can be and will be resolved in the near future?Obviously 
> for a customer script we have to suppress this misleading output, by other 
> means.

I don't think there is a way to fix it.  What's happening is the combination of 
two automatic behaviors:

1.) A failed lookup in %ENV sets errno / vaxc$errno in our getenv 
implementation (specifically Perl_vmstrenv in [.vms]vms.c).  This is normal and 
as it should be.

2.) die() (specifically Perl_my_failure_exit in perl.c) retrieves the most 
recent value of vaxc$errno and uses it as the VMS exit status.  This is also 
normal behavior.

The following is from the documentation for the die function and describes how 
exit codes work on Unix:

========
as $! is the value of C's "errno", which can be set by
any system call, this means that the value of the exit code used
by "die" can be non-predictable, so should not be relied upon,
other than to be non-zero.
========

The main difference on VMS is that you get (by default) a native 32-bit 
condition value rather than just a non-zero number, and die ends up using 
SS$_ABORT by default if vaxc$errno is not set.  So what you're seeing is really 
the documented behavior of die.

Another way of looking at this is that your program dies without having 
encountered an error, so it picks up whatever previous error happens to be 
lying around.  Just as in C errno is only valid immediately after a failed 
system call, the VMS exit code retrieved by die is also only valid immediately 
after a failed system call. 

One way to solve your problem is to just clear errno ($! in Perl) and 
vaxc$errno ($^E in Perl) before calling die:

=======
print $ENV{X}, "\n";

# Clear these so die isn't confused.
$! = 0;
$^E = 0;

my $whatever = shift @ARGV or die "missing argument";
exit 0; 
=======

However, it seems to me clearer to code exactly what you want rather than rely 
on the behavior of die, which really isn't what you want:

=======
use constant SS_INSFARG => 276;

print $ENV{X}, "\n";

my $whatever = shift @ARGV;
exit SS_INSFARG unless $whatever;

exit 0;
=======


________________________________________
Craig A. Berry
mailto:craigbe...@mac.com

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser

Reply via email to