summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn E. Malmberg <wb8tyw@qsl.net>2008-11-08 18:46:03 -0600
committerCraig A. Berry <craigberry@mac.com>2008-11-10 12:49:23 +0000
commit1a3aec58bbfe991c5f6d394fa59ab18b857bba6c (patch)
treea543401c400fbea94059b32d7f16f07e0c66e92b
parentb306dcb39875d351d64f81a4a6469b778b8f7c42 (diff)
downloadperl-1a3aec58bbfe991c5f6d394fa59ab18b857bba6c.tar.gz
[patch@34779] Get posix exit mode working/tested on VMS
From: "John E. Malmberg" <wb8tyw@qsl.net> Message-id: <4916872B.5040500@qsl.net> p4raw-id: //depot/perl@34790
-rw-r--r--perl.h16
-rw-r--r--t/run/exit.t32
-rw-r--r--vms/vms.c25
3 files changed, 55 insertions, 18 deletions
diff --git a/perl.h b/perl.h
index 526155b5b7..d08a4a6a21 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 2b2b99d0bf..f59584cd8f 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 e11ed59a15..e674a8a446 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(); */