Operating System - OpenVMS
1752749 Members
4797 Online
108789 Solutions
New Discussion

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

 
SOLVED
Go to solution
Homer Shoemaker
Frequent Advisor

How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

OpenVMS 8.4, HP COBOL 2.9, rx2660,

 

I think I know that the parameter returned is an address, and that the COBOL type is USAGE POINTER.

 

How do I get at the data stored at that address using that variable from within my COBOL program? 

 

I want to take different actions in my COBOL program based on the status code returned from the spawned DCL command procedure.  Here is an example. 

 

All below is also in the attacment because it is easier to read. 

  

Here is the DCL program that I want to run just to get an error status:
***********************************************************************
D2660 HOMER-> type testpgm.com
$ SET VERIFY
$ ON ERROR THEN GOTO EXIT
$ DIR AL;SKDJF;JKL.AL;DKJF
$EXIT:
$ EXIT


Here is the screen output when I run that program from a DCL prompt:
********************************************************************
D2660 HOMER-> @TESTPGM
$ SET VERIFY
$ ON ERROR THEN GOTO EXIT
$ DIR AL;SKDJF;JKL.AL;DKJF
%DCL-W-PARMDEL, invalid parameter delimiter - check use of special characters
 \;JKL\
$EXIT:
$ EXIT


Here is the status that I want to retrieve from inside my COBOL program:
************************************************************************
D2660 HOMER-> SH SYMBOL $STATUS
  $STATUS == "%X10038110"


Here is the output file created by LIB$SPAWN:
*********************************************
D2660 HOMER-> type testpgm.txt
$ ON ERROR THEN GOTO EXIT
$ DIR AL;SKDJF;JKL.AL;DKJF
%DCL-W-PARMDEL, invalid parameter delimiter - check use of special characters
 \;JKL\
$EXIT:
$ EXIT

 
Here is my COBOL program: 
*************************
IDENTIFICATION DIVISION.
PROGRAM-ID. FXTESTSPAWN.
AUTHOR.  H. Shoemaker.
DATE-WRITTEN. 12-JAN-2012

ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.


01 DCLPGM                     PIC X(12).
01 OUTPUT-FILE-NAME           PIC X(16).

01 DCLPGM-COMPLETION-STATUS USAGE POINTER.

01 RET-STATUS                 PIC S9(9) COMP.
01 DISP-RET-STATUS            PIC Z(4)9.

01 SS$_NORMAL                 PIC S9(5) COMP VALUE EXTERNAL SS$_NORMAL.

PROCEDURE DIVISION.
000-BEGIN.
   
    DISPLAY SPACE LINE 1 COLUMN 1 ERASE SCREEN.
   
    MOVE "@TESTPGM.COM"                 TO DCLPGM.
    MOVE "TESTPGM.TXT"                  TO OUTPUT-FILE-NAME.
   
    CALL "LIB$SPAWN" USING
                     BY DESCRIPTOR DCLPGM
                     OMITTED
                     BY DESCRIPTOR OUTPUT-FILE-NAME
                     OMITTED
                     OMITTED
                     OMITTED
                     BY VALUE DCLPGM-COMPLETION-STATUS
                     OMITTED
                     OMITTED
                     OMITTED
                     OMITTED
                     OMITTED
                     GIVING RET-STATUS.
                    
       
    DISPLAY "This is the return status       :"    LINE 10 COLUMN  1.
    DISPLAY DISP-RET-STATUS                        LINE 10 COLUMN 40.
   
    EVALUATE RET-STATUS
       WHEN SS$_NORMAL     DISPLAY "NORMAL"        LINE 10 COLUMN 50
       WHEN OTHER          DISPLAY "OTHER"         LINE 10 COLUMN 50
    END-EVALUATE.
   
    STOP RUN.

 

7 REPLIES 7
Hoff
Honored Contributor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

The program completion status is returned by address, not by value.

 

By value only works for passing stuff in.  Not out.

 

The LIBRTL manual lists this argument as an address by value, which is confusing nomenclature.

Homer Shoemaker
Frequent Advisor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

 
Hi Hoff,
 
I appreciate your response.

 

But I am still not sure about the steps to take to acess the completion
status of the dcl program from within a COBOL program.

 

If the passing mechanism that I used is incorrect, which passing mechanism
do I use? The default, BY REFERENCE?

 

Even so, I still get zero when I examine the variable DCLPGM-COMPLETION-STATUS.

 
I am probably not going about this the right way.

Any more help would also be appreciated.

 

Hoff
Honored Contributor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

It would appear you are unfamiliar with the calling standard.

 

Quick review...

 

...You can only get the status back when the variable is passed by reference.

 

...Reference means a virtual address is involved.  Usually to a variable, but can also potentially be to code.

 

...Passing by reference means you pass the address of where the called code will write the data.

 

...A virtual address where the called code will write the completion value, in this case.

 

Unfortunately, the COBOL compiler available on OpenVMS doesn't do this sort of thing very well, so you're limited to passing by reference, or calling into a language that does provide pointers and related.  (The COBOL 2002 standard is much more capable here, but the OpenVMS compiler is older and doesn't have this support. Languages such as Macro32, C, Bliss and a few other languages can and do support pointers, and can be used to create "jackets" that make things easier for COBOL programs.)

 

Calling out from COBOL is not obvious, so take the time to review the COBOL documentation, and then Google for COBOL examples of $getjpi/$getsyi/$getdvi, etc.   Here is one of the hits from Google.

 

Additionally, if you have a COBOL support contract with HP, then contact the HP support center and see if they can provide you with copies of the old source code examples for COBOL; COBOL examples of calling various RTL services and system services.  These examples were once available online via the old Compaq AskQ web site, but access has since disappeared.

Hein van den Heuvel
Honored Contributor
Solution

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

Hi Homer,

You are thinking too complex.
Or as Hoff put it, the documentation while very correct, is also very confusion to 'beginners'.
There are subtle semantics at play, but if you just pass the variable by reference as normal it will work just fine.
When passing by reference, the value of the address of the variable will be passed to the callee.

Mind you Cobol _does_ have a ability to do what the documention appears to spell out

 

:
01 DCLPGM-COMPLETION-STATUS PIC S9(9) COMP.
01 DCLPGM-COMPLETION-STATUS-PT usage pointer.
:
SET DCLPGM-COMPLETION-STATUS-PT TO REFERENCE DCLPGM-COMPLETION-STATUS.
:
CALL .... by value DCLPGM-COMPLETION-STATUS-pt
:
DISPLAY DCLPGM-COMPLETION-STATUS WITH CONVERSION LINE 11 COLUMN 30.
IF DCLPGM-COMPLETION-STATUS

 


But there is no need! Just call as always with variable and be happy.
Ouput and complete program below.

hth,
Hein


------ TEST_1 ---- good command
$ show time
$ exit 1234567
------ TEST_1 ---- Output file
14-JAN-2012 11:19:56
------ TEST_1 ---- screen output

This is the SPAWN  status            1                NORMAL
This is the PROGRAM status         1234567     GOOD

 

------ TEST_2 ---- bad command

$ show time
$ exit 1234
------ TEST_2 ---- Output file
14-JAN-2012 11:17:42
%SYSTEM-E-INHCHME, inhibited CHMExecutive trap
------ TEST_2 ---- screen output

This is the SPAWN status       1          NORMAL
This is the PROGRAM status   1234     BAD

 

IDENTIFICATION DIVISION.
PROGRAM-ID. FXTESTSPAWN.
AUTHOR.  H. Shoemaker.
DATE-WRITTEN. 12-JAN-2012
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

01 DCLPGM                     PIC X(12).
01 OUTPUT-FILE-NAME           PIC X(16).
01 DCLPGM-COMPLETION-STATUS   PIC S9(9) COMP.
01 RET-STATUS                 PIC S9(9) COMP.
01 DISP-RET-STATUS            PIC Z(4)9.
01 SS$_NORMAL                 PIC S9(5) COMP VALUE EXTERNAL SS$_NORMAL.
PROCEDURE DIVISION.
000-BEGIN.
   
    DISPLAY SPACE LINE 1 COLUMN 1 ERASE SCREEN.
   
    MOVE "@TESTPGM.COM"                 TO DCLPGM.
    MOVE "TESTPGM.TXT"                  TO OUTPUT-FILE-NAME.
   
    CALL "LIB$SPAWN" USING
                     BY DESCRIPTOR DCLPGM
                     OMITTED
                     BY DESCRIPTOR OUTPUT-FILE-NAME
                     OMITTED
                     OMITTED
                     OMITTED
                     by reference DCLPGM-COMPLETION-STATUS
                     OMITTED
                     OMITTED
                     OMITTED
                     OMITTED
                     OMITTED
                     GIVING RET-STATUS.
                    
       
    DISPLAY "This is the SPAWN  status       :"    LINE 10 COLUMN  1.
    DISPLAY RET-STATUS WITH CONVERSION             LINE 10 COLUMN 30.
    EVALUATE RET-STATUS
       WHEN SS$_NORMAL     DISPLAY "NORMAL"        LINE 10 COLUMN 50
       WHEN OTHER          DISPLAY "OTHER"         LINE 10 COLUMN 50
    END-EVALUATE.

    DISPLAY "This is the PROGRAM status       :"    LINE 11 COLUMN  1.
    DISPLAY DCLPGM-COMPLETION-STATUS WITH CONVERSION LINE 11 COLUMN 30.
    IF DCLPGM-COMPLETION-STATUS 
       IS SUCCESS          DISPLAY "GOOD"          LINE 11 COLUMN 50
       ELSE                DISPLAY "BAD"           LINE 11 COLUMN 50
    END-IF.
   

    STOP RUN.

 

 

 

Homer Shoemaker
Frequent Advisor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

Excellent!  Thank you both.

 

Hein,

 

I already tested the second, less complex  solution, and it does exactly what I want it to.   Since it is Saturday, and  I am typing this on my laptop while sitting at the hotel bar and waiting the football game to come on, I will raise a glass to you.  I owe you a beer, probably a few beers, next time I see you.

 

Homer

 

 

 

 

John Gillings
Honored Contributor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

Homer,

 

   Just to explain the peculiar nomenclature of this parameter in the documentation. Like many others you were confused by the description of "address by value", when the completion status is really just a longword by reference.

 

For practical purposes "address by immediate value" just means exactly the same thing as "by reference". The reason for the distinction is reference parameters are expected to be written synchronously, during the execution of the called routine. In the case of LIB$SPAWN, you can use the NOWAIT option to return control potentially before the subprocess has completed, in which case the status value will be written after the routine has returned.

 

In an attempt to highlight this feature of the argument it's described as address by immediate value,  because the routine itself really just stores away the address. When the asynchronous event occurs (in this case the subprocess completion), the address is used to write the completion status. This can be a problem, if, for example, the parameter were a stack based temporary variable, since you're overwriting what is now a random memory location.

 

In practice, most folk just get confused (this post being just another example). Perhaps it would have been better to describe the argument as "longword by reference written asynchronously".

 

(there's also an inconsistency here in the documentation, as the IOSBs of the asych system services behave in exactly the same way, but they're all described as "by reference").

A crucible of informative mistakes
Homer Shoemaker
Frequent Advisor

Re: How do I access the dcl program completion status after a call to LIB$SPAWN from HP COBOL?

Thank you, Sir.

 

I do appreciate the explanation.