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