Kednos PL/I for OpenVMS Systems
User Manual


Previous Contents Index

If the field PLI_FILE_DISPLAY.DEVICE.SPL is true, then the members of the minor structure DEVICE contain information about the device that is spooled. Members of minor structure PLI_FILE_DISPLAY.SPOOLING_DEVICE contain information about the intermediate, or spooling, device.

All fields within these structures are BIT(1) values.

Table 9-4 Device Information Returned by DISPLAY
Member Name Meaning
ALL Device is or is not allocated.
AVL Device is or is not online and available.
CCL Device has or does not have carriage control.
DIR Device is or is not directory structured.
DMT Device is or is not marked for dismounting.
ELG Device is or is not enabled for error logging.
FOD Device is or is not file-oriented.
FOR Device is or is not a foreign device.
GEN Device is or is not a generic device.
IDV Device is or is not capable of input.
MBX Device is or is not a mailbox.
MNT Device is or is not mounted.
NET Device is or is not a network device.
ODV Device is or is not capable of output.
RCK Device performs read checking.
REC Device is or is not a record-oriented device (terminal or line printer, for example).
RND Device is or is not random access in nature.
RTM Device is or is not a real-time device.
SDI Device has a master directory only.
SHR Device is or is not shareable.
SPL Device is or is not spooled.
SQD Device is or is not sequential block-oriented (magnetic tape).
SWL Device is or is not currently software write-locked.
TRM Device is or is not a terminal.
WCK Device performs write checking.

9.2 EXTEND Built-In Subroutine

The EXTEND built-in subroutine increases the amount of space allocated to a disk file. Its calling sequence is as follows:

CALL EXTEND (file-reference,integer-expression); 

file-reference

Specifies the name of a file variable or constant associated with the file that is to be extended. If the file is not currently opened, the EXTEND subroutine opens the file with the OUTPUT attribute in order to extend it.

integer-expression

Is a fixed binary expression in the range 0 to 4,294,967,295, specifying the number of 512-byte disk blocks to be added to the file. If 0 is specified, PL/I uses the default extension quantity for the file.

To specify a value larger than 2,147,483,647 (the largest value that can be contained in a fixed binary integer in PL/I), you must express the number as a negative value; RMS interprets the number as an unsigned integer.

Use the EXTEND built-in subroutine to explicitly extend a file during processing. Normally, RMS extends a file automatically, using a current extension size value, whenever an output operation causes a file to exceed its allocated space. The default value that RMS uses to extend a file is set by the ENVIRONMENT option EXTENSION_SIZE.

You can improve the performance of a program that is going to add a large number of records to a file by making an explicit call to EXTEND before adding records to the file. If the call to EXTEND occurs before records are added, then RMS does not need to extend the file during the actual I/O operations.

9.3 FLUSH Built-In Subroutine

The FLUSH built-in subroutine writes all RMS buffers that have been modified and preserves all of the file attributes of the file. This subroutine provides the ability to checkpoint a file during its processing and ensure its integrity. Its calling sequence is as follows:

CALL FLUSH (file-reference); 

file-reference

Specifies the name of the file variable or file constant associated with the file whose buffers are to be flushed. If the file is not currently opened, the FLUSH subroutine performs no operation.

Use the FLUSH subroutine to explicitly request RMS to write all internal file buffers back to the file. This subroutine is called implicitly by the REWIND and NEXT_VOLUME built-in subroutines.

9.4 FREE Built-In Subroutine

The FREE built-in subroutine unlocks all the locked records in a specified file. Its calling sequence is as follows:

CALL FREE (file-reference); 

file-reference

Specifies the name of the file variable or file constant associated with the file whose records are to be unlocked.

9.5 NEXT_VOLUME Built-In Subroutine

The NEXT_VOLUME built-in subroutine performs the positioning and labeling functions necessary when the next volume is required during I/O to a magnetic tape file that spans more than one physical tape volume. Its calling sequence is as follows:

CALL NEXT_VOLUME (file-reference); 

file-reference

Specifies the name of the file constant or file variable associated with the tape volume set that is being processed. If the file is not currently open, the NEXT_VOLUME subroutine implicitly opens the file with the attributes specified in the declaration of the file.

When a multivolume tape file is being read or written, volume switching is normally transparent to the PL/I program. RMS and the magnetic tape Ancillary Control Program (ACP) perform all the steps necessary to ensure that the next required volume is physically mounted, initialized, and verified.

However, when a program must advance to the next volume before reaching the end of the current volume on input, or before the end of the tape is reached on output, it can call the NEXT_VOLUME built-in subroutine. This subroutine performs all the necessary volume checking when a multivolume tape file is being read. When a file is being written, the subroutine writes the appropriate information on the output tapes.

For more detailed explanations of volume switching, see the OpenVMS Record Management Services Reference Manual and the OpenVMS DCL Dictionary.

9.6 RELEASE Built-In Subroutine

The RELEASE built-in subroutine unlocks a specified record in a file. Its calling sequence is as follows:

CALL RELEASE (file-reference,variable-reference); 

file-reference

Specifies the name of the file variable or file constant associated with the file on which the operation is to be performed. This file must have been opened with the RECORD_ID_ACCESS option of the ENVIRONMENT attribute.

variable-reference

Specifies the record identification of the record to be unlocked. It must be declared (2) FIXED BINARY, and it must be connected.

9.7 REWIND Built-In Subroutine

The REWIND built-in subroutine positions a file so that the next record to be read will be the first record in the file or index. Its calling sequence is as follows:

CALL REWIND (file-reference); 

file-reference

Specifies the name of the file constant or file variable associated with the file to be rewound. If the file is not currently open, the REWIND subroutine implicitly opens the file with the attributes specified in the declaration of the file.

Use this subroutine to begin processing a file at its logical beginning. This subroutine is valid for disk files of all organizations and for sequential files on tape volumes. The position of the file following the call to the REWIND subroutine is as follows:

You can also use the REWIND built-in subroutine to reposition a stream file after an end-of-file condition. Normally, if end-of-file (Ctrl/z on a terminal) is entered during an input operation on a stream input file, the PL/I program must close the input file and reopen it before any more data can be read. However, an ENDFILE ON-unit can be written as follows:


ON ENDFILE(STREAMFIL) CALL REWIND(STREAMFIL); 

This ON-unit calls the REWIND built-in subroutine each time an end-of-file condition is encountered for the file constant STREAMFIL. The REWIND built-in subroutine repositions the stream file at its beginning so that the program can continue reading input.

9.8 SPACEBLOCK Built-In Subroutine

The SPACEBLOCK built-in subroutine positions a file forward or backward a specified number of blocks. This subroutine can be used to process unlabeled magnetic tapes, as well as sequential disk files that are being processed with block I/O. Its calling sequence is as follows:

CALL SPACEBLOCK (file-reference,integer-expression); 

file-reference

Specifies the name of the file constant or file variable that is to be spaced. If the file is open, it must have been opened with the BLOCK_IO option. If the file is not open, the SPACEBLOCK subroutine opens the file with the BLOCK_IO option.

integer-expression

Is a fixed binary expression specifying the number of blocks to be spaced forward or backward. If the expression is negative, the file is spaced backward the specified number of blocks. If the expression is positive, the tape is spaced forward the specified number of blocks.


Chapter 10
Error Handling

In PL/I errors are signaled through ON conditions and handled by groups of statements called ON-units. An ON condition is any one of several named conditions that interrupt program execution. When an ON condition occurs, or is signaled, the corresponding ON-unit is executed.

This chapter discusses the following topics:

See the Kednos PL/I for OpenVMS Systems Reference Manual for descriptions of the ON, REVERT, and SIGNAL statements and ON conditions.

10.1 RESIGNAL Built-In Subroutine

The RESIGNAL built-in subroutine is used in an ON-unit to pass a signaled condition, so that the run-time system will attempt to locate another ON-unit to handle the condition.

RESIGNAL works by setting up the internal mechanism for passing the signal. It does not by itself cause an exit from the ON-unit that calls it. Instead, it returns to the next statement in the ON-unit. Resignaling does not occur until execution of the ON-unit is completed.

The format of a statement calling the RESIGNAL built-in subroutine is as follows:

CALL RESIGNAL(); 

When an ON-unit has determined that it cannot or should not respond to a condition, RESIGNAL permits the ON-unit to pass the signal along.

This subroutine is not part of the standard PL/I language. It is provided specifically for use in the OpenVMS operating system environment.

10.2 ON-Unit Actions

During its execution, an ON-unit can take any of the following courses of action:

These courses of action are described individually in the following subsections.

10.2.1 Handling the Condition

A condition is assumed to be handled in PL/I when the ON-unit established for the condition completes execution without performing one of the following actions:

When the condition is handled, PL/I continues execution of the program at the point of interruption. Normal completion of any ON-unit (except ERROR signaled as the default action) results in return of control either to the statement that caused the condition or to the statement immediately following the statement that caused the condition. However, the effects of normal return from ERROR, FIXEDOVERFLOW, OVERFLOW, UNDERFLOW, and ZERODIVIDE are generally unpredictable. Exceptions are cases of ERROR that are specifically documented to allow normal return, and ON-units that execute as a result of a SIGNAL statement. In the case of UNDERFLOW, return from the default PL/I condition handler continues execution unpredictably, with an undefined value as the result of the operation that caused the condition (the value is set to zero only if the UNDERFLOW option is not enabled).

10.2.2 Resignaling the Condition

In PL/I, an ON-unit can choose not to handle a condition and can request that, rather than returning control to the point of interruption, PL/I continue to search for another ON-unit to handle the condition. It does this by calling the RESIGNAL built-in subroutine as follows:


CALL RESIGNAL(); 

The RESIGNAL built-in subroutine has no arguments.

When an ON-unit calls RESIGNAL, PL/I resumes its search of the call stack starting at the call frame beneath the frame in which it located the current ON-unit. Example 10-1 and Figure 10-1 illustrate the effect of the RESIGNAL built-in subroutine. The callout numbers in the example indicate the order of execution.

Procedure B establishes an ANYCONDITION ON-unit that handles specific values. When the ON-unit is executed as a result of a signal in either procedure B or C, it tests the current value of ONCODE to see whether it is a value of interest. If not, procedure B calls RESIGNAL.

Example 10-1 Resignaling the Condition

A: PROCEDURE OPTIONS (MAIN);(1)
ON FIXEDOVERFLOW BEGIN; 
 
(6)
 
END; 
   .
   .
   .
CALL B; 
 
B: PROCEDURE (X,Y);(2)
ON ANYCONDDITION BEGIN; 
IF (ONCODE()=SIGNAL_FOUND)! (5)
   (ONCODE()=SIGNAL_DONE) THEN 
   BEGIN; 
 
   END;/"begin block for IF statement"/ 
   ELSE CALL RESIGNAL(); 
END;/"ON-unit"/ 
CALL C; 
 
C: PROCEDURE;(3)
 
    (4)
 
   RETURN; 
   END; 

Figure 10-1 Resignaling a Condition


When the FIXEDOVERFLOW condition is signaled in procedure C, B calls RESIGNAL and PL/I continues its search of the call stack. It locates the ON-unit for handling the FIXEDOVERFLOW condition in procedure A and executes it.

Note that the default condition handling performed by PL/I uses the resignaling capability to continue signals that are not handled within the program. PL/I default condition handling is described in Section 10.4.

10.2.3 Unwinding the Call Stack

An ON-unit in a PL/I procedure can execute a nonlocal GOTO statement that transfers control to a previous block. In this case, PL/I releases call frames, beginning with the call frame created for the ON-unit, until it reaches the block containing the label specified in the GOTO statement.

The removal of call frames from the call stack is called an unwind. Example 10-2 and Figure 10-2 illustrate a situation in which an unwind occurs. The callout numbers in the example indicate the order of execution.

Procedure A establishes an ERROR ON-unit represented by the box drawn with broken lines in Figure 10-2. The ERROR ON-unit established in procedure A receives control when the ERROR condition is signaled in procedure C. This ON-unit executes the GOTO PRINT_MSG statement. The label PRINT_MSG is in procedure A. Thus, the call stack is unwound and the call frames for the ON-unit, procedure C, and procedure B, in that order, are removed from the stack, and execution continues at the label PRINT_MSG.

Example 10-2 Unwinding the Call Stack

A: PROCEDURE OPTIONS (MAIN);(1)
       ON ERROR GOTO PRINT_MSG; 
 
       (4)
 
       CALL B; 
   PRINT_MSG; 
 
   (5)
 
   END; 
 
B: PROCEDURE;(2)
 
   CALL C; 
 
   RETURN; 
   END; 
 
C: PROCEDURE;(3)
 
   RETURN; 
   END; 

Figure 10-2 Unwinding the Call Stack


When an unwind occurs in the OpenVMS environment, each call frame in the calling sequence is examined to determine if a condition ON-unit exists for that frame. If so, the ON-unit is called with the condition value SS$_UNWIND, and the ON-unit has the chance to perform block- or procedure-specific cleanup operations.

10.2.4 Stopping the Program

An ON-unit can specify that the program is to be terminated by executing a STOP statement. For example:


ON UNDEFINEDFILE(INFILE) BEGIN; 
 
    PUT EDIT('File',ONFILE(),'undefined. Error',ONCODE()) 
              (A,X,A,X,A,X,F(10)); 
    STOP; 
    END; 

The STOP statement performs the following actions:

Thus, when a FINISH ON-unit that has been executed as a result of a STOP statement handles the condition, control returns to the STOP statement, which then terminates the image.

If no FINISH or ANYCONDITION ON-unit exists, the program is terminated.

Note that when a FINISH or ANYCONDITION ON-unit executes a STOP statement, the program enters an infinite loop.

10.3 Relationship of OpenVMS Condition Handlers to PL/I ON-Units

In the OpenVMS environment, an exception condition is a hardware- or software-detected condition that synchronously interrupts the execution of an image. A condition handler is a procedure that exists specifically to respond to one or more such conditions; each procedure in the program can establish a condition handler. It is usually the responsibility of each handler to determine the specific condition that was signaled, and to decide whether or not to handle it.

Most high-level languages establish condition handlers by calling the VAX Run-Time Library procedure LIB$ESTABLISH. The PL/I language, however, has in the ON-unit a condition handler defined to handle a specific condition. By using the keyword condition names defined by PL/I and the extensions provided by PL/I, you can write ON-units to handle any possible condition specific to OpenVMS. Each procedure can establish separate ON-units for each of several possible conditions that the procedure wishes to handle.

You should never use LIB$ESTABLISH to establish a condition handler in a PL/I call frame.


Previous Next Contents Index