From 8cfc23c6775ed7c029b778e2e5d704cdb9be8315 Mon Sep 17 00:00:00 2001
From: John Malmberg <wb8tyw@qsl.net>
Date: Sun, 14 Sep 2014 02:39:36 -0500
Subject: [PATCH] Bug 42447: More VMS exit handling fixes

More VMS exit handling fixes missed in the previous pass.

* job.c: (reap_children) The VMS specific code was setting status to 0
  instead of setting it to the proper exit status.
* vmsjob.c: (vmsHandleChildTerm): First fixed the exit code and then
  discovered that it was duplicating the now fixed code in job.c
  resulting in duplicate error messages.  Conditionally compiled this
  code out for now.  Will look at this later, probably when implementing
  parallelism.
---
 job.c     |   20 ++++++++++++++++++++
 vmsjobs.c |   17 ++++++++---------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/job.c b/job.c
index bf4de32..f278f78 100644
--- a/job.c
+++ b/job.c
@@ -59,12 +59,21 @@ int batch_mode_shell = 0;
 #elif defined (VMS)
 
 # include <descrip.h>
+# include <stsdef.h>
 const char *default_shell = "";
 int batch_mode_shell = 0;
 
 #define strsignal vms_strsignal
 char * vms_strsignal(int status);
 
+#ifndef C_FACILITY_NO
+#define C_FACILITY_NO 0x350000
+#endif
+#ifndef VMS_POSIX_EXIT_MASK
+#define VMS_POSIX_EXIT_MASK (C_FACILITY_NO | 0xA000)
+#endif
+
+
 #elif defined (__riscos__)
 
 const char *default_shell = "";
@@ -665,8 +674,19 @@ reap_children (int block, int err)
           if (any_local)
             {
 #ifdef VMS
+              /* Todo: This needs more untangling multi-process support */
+              /* Just do single child process support now */
               vmsWaitForChildren (&status);
               pid = c->pid;
+
+              /* VMS failure status can not be fully translated */
+              status = $VMS_STATUS_SUCCESS(c->cstatus) ? 0 : (1 << 8);
+
+              /* A Posix failure can be exactly translated */
+              if ((c->cstatus & VMS_POSIX_EXIT_MASK) == VMS_POSIX_EXIT_MASK)
+                {
+                  status = (c->cstatus >> 3 & 255) << 8;
+                }
 #else
 #ifdef WAIT_NOHANG
               if (!block)
diff --git a/vmsjobs.c b/vmsjobs.c
index b189ccd..844f65d 100644
--- a/vmsjobs.c
+++ b/vmsjobs.c
@@ -25,9 +25,6 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stsdef.h>
 #include <ssdef.h>
 void decc$exit(int status);
-#ifndef C_FACILITY_NO
-#define C_FACILITY_NO 0x350000
-#endif
 
 /* Lowest legal non-success VMS exit code is 8 */
 /* GNU make only defines codes 0, 1, 2 */
@@ -37,9 +34,6 @@ void decc$exit(int status);
 #define MAX_EXPECTED_EXIT_CODE 7
 #endif
 
-#ifndef VMS_POSIX_EXIT_MASK
-#define VMS_POSIX_EXIT_MASK (C_FACILITY_NO | 0xA000)
-#endif
 
 #if __CRTL_VER >= 70302000 && !defined(__VAX)
 #define MAX_DCL_LINE_LENGTH 4095
@@ -47,7 +41,6 @@ void decc$exit(int status);
 #define MAX_DCL_LINE_LENGTH 1023
 #endif
 
-
 char *vmsify (char *name, int type);
 
 static int vms_jobsefnmask = 0;
@@ -227,6 +220,7 @@ vmsHandleChildTerm(struct child *child)
         /* Convert VMS success status to 0 for UNIX code to be happy */
         child->vms_launch_status = 0;
     }
+#if 0
   if (child_failed && !c->noerror && !ignore_errors_flag)
     {
       /* The commands failed.  Write an error message,
@@ -268,11 +262,13 @@ vmsHandleChildTerm(struct child *child)
         }
 #endif /* RECURSIVEJOBS */
     }
+#endif
 
   /* Set the state flag to say the commands have finished.  */
   c->file->command_state = cs_finished;
   notice_finished_file (c->file);
 
+#if 0
 #if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */
   /* Remove the child from the chain and free it.  */
   if (lastc == 0)
@@ -287,8 +283,11 @@ vmsHandleChildTerm(struct child *child)
     --job_slots_used;
 
   /* If the job failed, and the -k flag was not given, die.  */
-  if (child_failed && !keep_going_flag)
-    die (exit_code);
+  if (child_failed && !c->dontcare && !keep_going_flag &&
+      /* fatal_error_signal will die with the right signal.  */
+      !handling_fatal_signal)
+    die (MAKE_FAILURE);
+#endif
 
   (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask));
 
-- 
1.7.9

