[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP COBOL
User Manual


Previous Contents Index

13.4.5.1 Library Return Status and Condition Value Symbols (OpenVMS)

Library return status and condition value symbols have the following general form:


fac$_abcmnoxyz

where:

fac is a 2- or 3-letter facility symbol (LIB, MTH, STR, OTS, BAS, COB, FOR, SS).
abc are the first 3 letters of the first word of the associated message.
mno are the first 3 letters of the next word.
xyz are the first 3 letters of the third word, if any.

Articles and prepositions are not considered significant words in this format. If a significant word is only two letters long, an underscore character is used to fill out the third space. The OpenVMS normal or success code is used to indicate successful completion. Some examples of this code are as follows:

RETURN Status Meaning
LIB$_INSVIRMEM Insufficient virtual memory
FOR$_NO_SUCDEV No such device
MTH$_FLOOVEMAT Floating overflow in Math Library procedure
BAS$_SUBOUTRAN Subscript out of range

13.4.6 Locating the Result (OpenVMS)

Once you have defined the arguments, called the procedure, and checked the condition value, you are ready to locate the result. To find out where the result is returned, look at the description of the system routine you are calling.

For example, in the following call to MTH$ACOS the result is written into the variable COS:


01 ARG-CODE PIC S9(9) COMP VALUE 1.
01 COS                COMP1 VALUE 0.
        .
        .
        .
    CALL "MTH$ACOS" USING BY REFERENCE ARG-CODE GIVING COS.

This result is described in the OpenVMS documentation on system services and Run-Time Library routines, under the description of the system routine.

13.5 Establishing and Removing User Condition Handlers (OpenVMS)

To establish a user condition handler, call the LIB$ESTABLISH routine.

The form of the call is as follows:


CALL LIB$ESTABLISH USING BY VALUE new-handler GIVING old-handler

new-handler

Specifies the name of the routine to be set up as a condition handler.

old-handler

Receives the address of the previously established condition handler.

The GIVING phrase is optional.

LIB$ESTABLISH moves the address of the condition-handling routine into the appropriate process context and returns the address of a previously established condition handler.

The handler itself could be a user-written routine, or a library routine. The following example shows how a call to establish a user-written handler might be coded:


01 HANDLER      PIC S9(9) COMP VALUE EXTERNAL HANDLER_ROUT.
01 OLD-HANDLER  PIC S9(9) COMP.
   .
   .
   .
   CALL "LIB$ESTABLISH" USING BY VALUE HANDLER GIVING OLD-HANDLER.

In the preceding example, HANDLER_ROUT is the name of a program that is established as the condition handler for the program unit containing these source statements. A program unit can remove an established condition handler in two ways:

  • Issue another LIB$ESTABLISH call which specifies a different handler.
  • Issue the LIB$REVERT call.

The LIB$REVERT call has no arguments:


CALL "LIB$REVERT".

This call removes the condition handler established in the current program unit.

Note that the LIB$ESTABLISH and LIB$REVERT routines only affect user condition handlers, not the default HP COBOL condition handler. When an exception occurs, the user condition handler, if one exists, is executed first, followed by the HP COBOL condition handler, if the user condition handler could not handle the exception.

When a program unit returns to its caller, the condition handler associated with that program unit is automatically removed (the program unit's stack frame, which contains the condition handler address, is removed from the stack).

Example 13-1 illustrates a user written condition handling routine that determines the reason for a system service failure. The example handler handles only one type of exception, system service failures. All other exceptions are resignalled, allowing them to be handled by the system default handlers. This handler is useful because the system traceback handler indicates only that a system service failure occurred, not which specific error caused the failure.

LIB$ESTABLISH is used by the main program, SSCOND, to establish the user written condition handler, SSHAND. System service failure mode is enabled so that errors in system service calls will initiate a search for a condition handler.

The condition handler is written as a subprogram that returns a result. The result indicates whether or not the condition handler handled the exception. Note that space must be allocated in the LINKAGE SECTION for the signal and mechanism arrays. The mechanism array always contains five elements, but the signal array varies according to the number of additional arguments.

When an exception occurs, the user condition handler is invoked first. The handler checks the error condition to determine if it is one that it can handle (the LIB$MATCH_COND routine would be useful here if the routine wanted to check for one of a collection of conditions). If the exception is not handled by this condition handler, then the default COBOL condition handler is invoked. If the default COBOL condition handler does not handle the exception, then the exception is handled by the operating system.

Example 13-1 User-Written Condition Handler

IDENTIFICATION DIVISION.
PROGRAM-ID.     SSCOND.
DATA DIVISION.
WORKING-STORAGE SECTION.

01      SSHANDA          PIC S9(9) COMP  VALUE EXTERNAL SSHAND.
PROCEDURE DIVISION.
BEGIN.
*
*       Establish condition handler
        CALL "LIB$ESTABLISH" USING BY VALUE SSHANDA.
*
*       Enable system service failure mode
        CALL "SYS$SETSFM" USING BY VALUE 1.
*
*       Generate a bad system service call
        CALL "SYS$QIOW" USING BY VALUE 0 0 0 0
                                       0 0 0 0
                                       0 0 0 0.
        STOP RUN.
END PROGRAM SSCOND.

IDENTIFICATION DIVISION.
*
PROGRAM-ID.     SSHAND.
*
*       This routine is to be used as a condition handler
*       for system service failures.
*
*       If this routine does not remedy the exception condition, it will
*       return with a value of SS$_RESIGNAL. If the routine does remedy
*       the exception condition, then it should return with a value of
*       SS$_CONTINUE.
*
DATA DIVISION.
WORKING-STORAGE SECTION.
01      SS_HAND         PIC S9(9) COMP.
01      SS$_SSFAIL      PIC S9(9) COMP  VALUE EXTERNAL SS$_SSFAIL.
01      SS$_RESIGNAL    PIC S9(9) COMP  VALUE EXTERNAL SS$_RESIGNAL.
01      MSGLEN          PIC S9(4) COMP.
01      MSGID           PIC S9(9) COMP.
01      ERRMSG          PIC X(80).
01      STAT            PIC S9(9) COMP.

LINKAGE SECTION.
01      SIGNAL_ARRAY.
        03      SIGNAL_ARGS     PIC 9(9) COMP.
        03      SIGNAL          OCCURS 4 TO 10 TIMES
                                DEPENDING ON SIGNAL_ARGS.
                05 SIGNAL_VALUE PIC S9(9) COMP.
01      MECHANISM_ARRAY.
        03      MECH_ARGS       OCCURS 5 TIMES.
                05 MECH         PIC 9(9) COMP.

PROCEDURE DIVISION USING SIGNAL_ARRAY MECHANISM_ARRAY
                   GIVING SS_HAND.
BEGIN.
*
*       Initialize the return result
*
        MOVE SS$_RESIGNAL TO SS_HAND.

        IF SIGNAL_VALUE(1) NOT EQUAL SS$_SSFAIL
        THEN
                MOVE SS$_RESIGNAL TO SS_HAND
        ELSE
*
*               Disable system service failure mode
*
                CALL "SYS$SETSFM" USING BY VALUE 0

                MOVE SIGNAL(2) TO MSGID
                CALL "SYS$GETMSG" USING BY VALUE MSGID
                                        BY REFERENCE MSGLEN
                                        BY DESCRIPTOR ERRMSG
                                        BY VALUE 0 0
                                   GIVING STAT
                IF STAT IS FAILURE
                THEN
                        CALL "LIB$STOP" USING BY VALUE STAT
                END-IF

                DISPLAY "System service call failed with error:"
                DISPLAY ERRMSG(1:MSGLEN)

*
*               This is where the handler would perform
*               corrective measures
*                        .
*                        .
*                        .
*               MOVE SS$_CONTINUE TO SS_HAND
*
        END-IF.
        EXIT PROGRAM.
END PROGRAM SSHAND.

To run this example program:


$ COBOL SSCOND
$ LINK  SSCOND
$ RUN   SSCOND


System service call failed with error:
%SYSTEM-F-IVCHAN, invalid I/O channel
%SYSTEM-F-SSFAIL, system service failure exception, status=0000013C,
     PC=8005FA40, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
 Image Name   Module Name     Routine Name    Line Number  rel PC      abs PC
                                                        0 8005FA40    8005FA40
 SSCOND       SSCOND          SSCOND                   21 000000CC    000300CC
 SSCOND                                                 0 00020470    00030470
                                                        0 870C8170    870C8170
                                                        0 849708F0    849708F0


Previous Next Contents Index