From 1a3aec58bbfe991c5f6d394fa59ab18b857bba6c Mon Sep 17 00:00:00 2001 From: "John E. Malmberg" Date: Sat, 8 Nov 2008 18:46:03 -0600 Subject: [PATCH] [patch@34779] Get posix exit mode working/tested on VMS From: "John E. Malmberg" Message-id: <4916872B.5040500@qsl.net> p4raw-id: //depot/perl@34790 --- perl.h | 16 ++++++++++------ t/run/exit.t | 32 ++++++++++++++++++++++++++++---- vms/vms.c | 25 +++++++++++++++++-------- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/perl.h b/perl.h index 526155b..d08a4a6 100644 --- a/perl.h +++ b/perl.h @@ -2941,9 +2941,9 @@ typedef pthread_key_t perl_key; PL_statusvalue_vms == SS$_NORMAL; \ else \ if (MY_POSIX_EXIT) \ - PL_statusvalue_vms = \ - (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \ - (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \ + PL_statusvalue_vms = \ + (C_FAC_POSIX | (evalue << 3 ) | \ + ((evalue == 1) ? (STS$K_ERROR | STS$M_INHIB_MSG) : 1)); \ else \ PL_statusvalue_vms = SS$_ABORT; \ } else { /* forgive them Perl, for they have sinned */ \ @@ -2969,6 +2969,9 @@ typedef pthread_key_t perl_key; * actual exit code will can be retrieved by the calling program or * shell. * + * A POSIX exit code is from 0 to 255. If the exit code is higher + * than this, it needs to be assumed that it is a VMS exit code and + * passed through. */ # define STATUS_EXIT_SET(n) \ @@ -2976,9 +2979,10 @@ typedef pthread_key_t perl_key; I32 evalue = (I32)n; \ PL_statusvalue = evalue; \ if (MY_POSIX_EXIT) \ - PL_statusvalue_vms = \ - (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \ - (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \ + if (evalue > 255) PL_statusvalue_vms = evalue; else { \ + PL_statusvalue_vms = \ + (C_FAC_POSIX | (evalue << 3 ) | \ + ((evalue == 1) ? (STS$K_ERROR | STS$M_INHIB_MSG) : 1));} \ else \ PL_statusvalue_vms = evalue ? evalue : SS$_NORMAL; \ set_vaxc_errno(PL_statusvalue_vms); \ diff --git a/t/run/exit.t b/t/run/exit.t index 2b2b99d..f59584c 100644 --- a/t/run/exit.t +++ b/t/run/exit.t @@ -20,6 +20,24 @@ BEGIN { $numtests = ($^O eq 'VMS') ? 16 : ($^O eq 'MacOS') ? 0 : 17; } + +my $vms_exit_mode = 0; + +if ($^O eq 'VMS') { + if (eval 'require VMS::Feature') { + $vms_exit_mode = !(VMS::Feature::current("posix_exit")); + } else { + my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} =~ /^[ET1]/i; + my $posix_ex = $ENV{'PERL_VMS_POSIX_EXIT'} =~ /^[ET1]/i; + if (($unix_rpt || $posix_ex) ) { + $vms_exit_mode = 0; + } else { + $vms_exit_mode = 1; + } + } + $numtests = 29 unless $vms_exit_mode; +} + require "test.pl"; plan(tests => $numtests); @@ -34,7 +52,7 @@ is( $exit >> 8, 0, 'Normal exit' ); is( $exit, $?, 'Normal exit $?' ); is( ${^CHILD_ERROR_NATIVE}, $native_success, 'Normal exit ${^CHILD_ERROR_NATIVE}' ); -if ($^O ne 'VMS') { +if (!$vms_exit_mode) { my $posix_ok = eval { require POSIX; }; my $wait_macros_ok = defined &POSIX::WIFEXITED; eval { POSIX::WIFEXITED() }; @@ -52,7 +70,11 @@ if ($^O ne 'VMS') { } SKIP: { - skip("Skip signals and core dump tests on Win32", 7) if $^O eq 'MSWin32'; + skip("Skip signals and core dump tests on Win32 and VMS", 7) + if ($^O eq 'MSWin32' || $^O eq 'VMS'); + + #TODO VMS will backtrace on this test and exits with code of 0 + #instead of 15. $exit = run('kill 15, $$; sleep(1);'); @@ -69,7 +91,9 @@ if ($^O ne 'VMS') { } } -} else { +} + +if ($^O eq 'VMS') { # On VMS, successful returns from system() are reported 0, VMS errors that # can not be translated to UNIX are reported as EVMSERR, which has a value @@ -139,7 +163,7 @@ $exit = run("END { \$? = $exit_arg }"); # status codes to SS$_ABORT on exit, but passes through unmodified UNIX # status codes that exit() is called with by scripts. -$exit_arg = (44 & 7) if $^O eq 'VMS'; +$exit_arg = (44 & 7) if $vms_exit_mode; is( $exit >> 8, $exit_arg, 'Changing $? in END block' ); } diff --git a/vms/vms.c b/vms/vms.c index e11ed59..e674a8a 100644 --- a/vms/vms.c +++ b/vms/vms.c @@ -353,6 +353,7 @@ static int vms_process_case_tolerant = 1; int vms_vtf7_filenames = 0; int gnv_unix_shell = 0; static int vms_unlink_all_versions = 0; +static int vms_posix_exit = 0; /* bug workarounds if needed */ int decc_bug_readdir_efs1 = 0; @@ -13080,9 +13081,7 @@ Perl_sys_intern_init(pTHX) VMSISH_HUSHED = 0; - /* fix me later to track running under GNV */ - /* this allows some limited testing */ - MY_POSIX_EXIT = decc_filename_unix_report; + MY_POSIX_EXIT = vms_posix_exit; x = (float)ix; MY_INV_RAND_MAX = 1./x; @@ -13556,7 +13555,6 @@ static int set_features gnv_unix_shell = 0; status = sys_trnlnm("GNV$UNIX_SHELL", val_str, sizeof(val_str)); if ($VMS_STATUS_SUCCESS(status)) { - if ((val_str[0] == 'E') || (val_str[0] == '1') || (val_str[0] == 'T')) { gnv_unix_shell = 1; set_feature_default("DECC$EFS_CASE_PRESERVE", 1); set_feature_default("DECC$EFS_CHARSET", 1); @@ -13565,9 +13563,7 @@ static int set_features set_feature_default("DECC$READDIR_DROPDOTNOTYPE", 1); set_feature_default("DECC$DISABLE_POSIX_ROOT", 0); vms_unlink_all_versions = 1; - } - else - gnv_unix_shell = 0; + vms_posix_exit = 1; } #endif @@ -13638,8 +13634,10 @@ static int set_features s = decc$feature_get_index("DECC$FILENAME_UNIX_REPORT"); if (s >= 0) { decc_filename_unix_report = decc$feature_get_value(s, 1); - if (decc_filename_unix_report > 0) + if (decc_filename_unix_report > 0) { decc_filename_unix_report = 1; + vms_posix_exit = 1; + } else decc_filename_unix_report = 0; } @@ -13767,6 +13765,17 @@ static int set_features #endif + /* USE POSIX/DCL Exit codes - Recommended, but needs to default to */ + /* for strict backward compatibilty */ + status = sys_trnlnm + ("PERL_VMS_POSIX_EXIT", val_str, sizeof(val_str)); + if ($VMS_STATUS_SUCCESS(status)) { + if ((val_str[0] == 'E') || (val_str[0] == '1') || (val_str[0] == 'T')) + vms_posix_exit = 1; + else + vms_posix_exit = 0; + } + /* CRTL can be initialized past this point, but not before. */ /* DECC$CRTL_INIT(); */ -- 2.7.4