Updated: 11 December 1998 |
OpenVMS Programming Interfaces: Calling a System
Routine
Previous | Contents | Index |
Each language provides some mechanism for testing the return status. Often you need only check the low-order bit, such as by a test for TRUE (success or informational return) or FALSE (error or warning return). Condition values that are returned by system services can provide information in addition to whether the service completed successfully. The condition value that usually indicates success is SS$_NORMAL, but others are defined. For example, the condition value SS$_BUFFEROVF, which is returned when a character string returned by a service is longer than the buffer provided to receive it, is a success code. This condition value, however, gives the program additional information.
Warning returns and some error returns indicate that the service performed some, but not all, of the requested function.
The possible condition values that each service can return are described with the individual service descriptions in the OpenVMS System Services Reference Manual. When you write calls to system services, read the descriptions of the return condition values to determine whether you want the program to check for particular return conditions.
To check the entire value for a specific return condition, each language provides a way for your program to determine the values associated with specific symbolically defined codes. You should always use these symbolic names when you write tests for specific conditions.
For information about how to test for these codes, see the user's guide
for your programming language.
4.4.5 Special Condition Values Using Symbolic Codes
Individual services have symbolic codes for special return conditions, argument list offsets, identifiers, and flags associated with these services. For example, the Create Process (SYS$CREPRC) system service (which is used to create a subprocess or a detached process) has symbolic codes associated with the various privileges and quotas you can grant to the created process.
The SYS$LIBRARY:SYS$LIB_C.TLB file contains the C header files for OpenVMS Alpha C data structures and definitions. For more information about SYS$LIBRARY:SYS$LIB_C.TLB, refer to Chapter 5.
The default system macro library, STARLET.MLB, contains the macro definitions for most system symbols. When you assemble a source program that calls any of these macros, the assembler automatically searches STARLET.MLB for the macro definitions. Each symbol name has a numeric value.
If your language has a method of obtaining values for these symbols, this method is explained in the user's guide.
If your language does not have such a method, you can do the following:
For example, to use the Get Job/Process Information ($GETJPI) system service to find out the accumulated CPU time (in 10-millisecond ticks) for a specified process, you must obtain the value associated with the item identifier JPI$_CPUTIM. You can do this in the following way:
.TITLE JPIDEF "Obtain values for $JPIDEF" $JPIDEF GLOBAL ; These MUST be UPPERCASE .END |
$ MACRO JPIDEF $ LINK/NOEXE/MAP/FULL JPIDEF %LINK-W-USRTFR, image NL:[].EXE; has no user transfer address |
$ MACRO/MIGRATION JPIDEF $ LINK/NOEXE/MAP/FULL JPIDEF %LINK-W-USRTFR, image NL:[].EXE; has no user transfer address |
To check for successful completion after a system service call, the program can test the low-order bit of R0 and branch to an error-checking routine if this bit is not set, as follows:
BLBC R0,errlabel ; Error if low bit clear |
Programs should not test for success by comparing the return status to SS$_NORMAL. A future release of OpenVMS may add new, alternate success codes to an existing service, causing programs that test for SS$_NORMAL to fail.
The error-checking routine may check for specific values or for specific severity levels. For example, the following VAX MACRO instruction checks for an illegal event flag number error condition:
CMPL #SS$_ILLEFC,R0 ; Is event flag number illegal? |
Note that return condition values are always longword values; however,
all system services always return the same value in the high-order word
of all condition values returned in R0.
4.4.7 System Messages Generated by Condition Values
When you execute a program with the DCL command RUN, the command interpreter uses the contents of R0 to issue a descriptive message if the program completes with an unsuccessful status.
The following VAX MACRO code fragment shows a simple error-checking procedure in a main program:
$READEF_S - EFN=#64, - STATE=TEST BSBW ERROR . . . ERROR: BLBC R0,10$ ; Check register 0 RSB ; Success, return 10$: RET ; Exit with R0 status |
After a system service call, the BSBW instruction branches to the subroutine ERROR. The subroutine checks the low-order bit in register 0 and, if the bit is clear, branches to a RET instruction that causes the program to exit with the status of R0 preserved. Otherwise, the subroutine issues an RSB instruction to return to the main program.
If the event flag cluster requested in this call to $READEF is not currently available to the process, the program exits and the command interpreter displays the following message:
%SYSTEM-F-UNASEFC, unassociated event flag cluster |
The keyword UNASEFC in the message corresponds to the condition value SS$_UNASEFC.
The following three severe errors generated by the calls, not the services, can be returned from calls to system services.
Error | Meaning |
---|---|
SS$_ACCVIO |
The argument list cannot be read by the caller (using the $
name_G macro), and the service is not called.
This meaning of SS$_ACCVIO is different from its meaning for individual services. When SS$_ACCVIO is returned from individual services, the service is called, but one or more arguments to the service cannot be read or written by the caller. |
SS$_INSFARG | Not enough arguments were supplied to the service. |
SS$_ILLSER | An illegal system service was called. |
4.5 Program Examples with System Service Calls
This section provides code examples that illustrate the use of a system
service call in the following programming languages:
Example 4-2 System Service Call in Ada |
---|
with SYSTEM, TEXT_IO, STARLET, CONDITION_HANDLING; (1) procedure ORION is -- Declare variables to hold equivalence name and length -- EQUIV_NAME: STRING (1..255); (2) pragma VOLATILE (EQUIV_NAME); NAME_LENGTH: SYSTEM.UNSIGNED_WORD; pragma VOLATILE (NAME_LENGTH); -- Declare itemlist and fill in entries. -- ITEM_LIST: STARLET.ITEM_LIST_3_TYPE (1..2) := (3) (1 => (ITEM_CODE => STARLET.LNM_STRING, (4) BUF_LEN => EQUIV_NAME'LENGTH, BUF_ADDRESS => EQUIV_NAME'ADDRESS, RET_ADDRESS => NAME_LENGTH'ADDRESS), 2 => (ITEM_CODE => 0, BUF_LEN => 0, BUF_ADDRESS => SYSTEM.ADDRESS_ZERO, RET_ADDRESS => SYSTEM.ADDRESS_ZERO)); STATUS: CONDITION_HANDLING.COND_VALUE_TYPE; (5) begin -- Translate the logical name -- STARLET.TRNLNM ( (6) STATUS => STATUS, TABNAM => "LNM$FILE_DEV", LOGNAM => "CYGNUS", ITMLST => ITEM_LIST); -- Display name if success, else signal error -- if not CONDITION_HANDLING.SUCCESS (STATUS) then (7) CONDITION_HANDLING.SIGNAL (STATUS); else TEXT_IO.PUT ("CYGNUS translates to """); TEXT_IO.PUT (EQUIV_NAME (1..INTEGER(NAME_LENGTH))); TEXT_IO.PUT_LINE (""""); end if; end ORION; |
Ada Notes
Example 4-3 System Service Call in BASIC |
---|
10 SUB ORION (1) ! Subprogram ORION OPTION TYPE=EXPLICIT ! Require declaration of all ! symbols EXTERNAL LONG FUNCTION SYS$TRNLNM ! Declare the system service EXTERNAL WORD CONSTANT LNM$_STRING ! The request code that ! we will use DECLARE WORD NAMLEN, (2) ! Word to receive length LONG SYS_STATUS ! Longword to receive status COMMON (BUF) STRING NAME_STRING = 255 (3) RECORD ITEM_LIST ! Define item ! descriptor structure WORD BUFFER_LENGTH ! The buffer length WORD ITEM ! The request code LONG BUFFER_ADDRESS ! The buffer address LONG RETURN_LENGTH_ADDRESS ! The address of the return len ! word LONG TERMINATOR ! The terminator END RECORD ITEM_LIST ! End of structure definition DECLARE ITEM_LIST ITEMS ! Declare an item list ITEMS::BUFFER_LENGTH = 255% ! Initialize the item list ITEMS::ITEM = LNM$_STRING ITEMS::BUFFER_ADDRESS = LOC( NAME_STRING ) ITEMS::RETURN_LENGTH_ADDRESS = LOC( NAMLEN ) ITEMS::TERMINATOR = 0 (4) SYS_STATUS = SYS$TRNLNM( , 'LNM$FILE_DEV', 'CYGNUS',, ITEMS) (5) IF (SYS_STATUS AND 1%) = 0% (6) THEN ! Error path ELSE ! Success path END IF END SUB |
BASIC Notes
Example 4-4 System Service Call in BLISS |
---|
MODULE ORION= BEGIN EXTERNAL ROUTINE ERROR_PROC: NOVALUE; ! Error processing routine LIBRARY 'SYS$LIBRARY:STARLET.L32'; ! Library containing OpenVMS ! macros (including $TRNLNM). ! This declaration ! is required. GLOBAL ROUTINE ORION: NOVALUE= BEGIN OWN NAMBUF : VECTOR[255, BYTE], ! Output buffer NAMLEN : WORD, ! Translated string length ITEMS : BLOCK[16,BYTE] INITIAL(WORD(255, ! Output buffer length LNM$_STRING), ! Item code NAMBUF, ! Output buffer NAMLEN, ! Address of word for ! translated ! string length 0); ! List terminator LOCAL ! Return status from STATUS; ! system service STATUS = $TRNLNM(TABNAM = %ASCID'LNM$FILE_DEV', LOGNAME = %ASCID'CYGNUS', ITMLST = ITEMS); (1) IF NOT .STATUS THEN ERROR_PROC(.STATUS); (2) END; |
BLISS Notes
Example 4-5 System Service Call in C |
---|
#include <starlet.h> (1) #include <lib$routines.h> #include <ssdef.h> #include <lnmdef.h> #include <descrip.h> #include <stdio.h> typedef struct { (2) unsigned short buffer_length; unsigned short item_code; char *buffer_addr; short *return_len_addr; unsigned terminator; } item_list_t; main () { (3) $DESCRIPTOR(table_name, "LNM$FILE_DEV"); $DESCRIPTOR(log_name, "CYGNUS"); char translated_name[255]; int status; short return_length; item_list_t item_list; item_list.buffer_length = sizeof(translated_name); (4) item_list.item_code = LNM$_STRING; item_list.buffer_addr = translated_name; item_list.return_len_addr = &return_length; item_list.terminator = 0; status = sys$trnlnm(0, &table_name, &log_name, 0, &item_list); (5) if (!(status & 1)) (6) lib$signal(status); else printf("The logical name %s is equivalent to %*s\n", log_name.dsc$a_pointer, return_length, translated_name); } |
C Notes
Example 4-6 System Service Call in COBOL |
---|
IDENTIFICATION DIVISION. PROGRAM-ID. ORION. (1) ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 TABNAM PIC X(11) VALUE "LNM$FILE_DEV". 01 CYGDES PIC X(6) VALUE "CYGNUS". 01 NAMDES PIC X(255) VALUE SPACES. (2) 01 NAMLEN PIC S9(4) COMP. 01 ITMLIS. 02 BUFLEN PIC S9(4) COMP VALUE 225. 02 ITMCOD PIC S9(4) COMP VALUE 2. (3) 02 BUFADR POINTER VALUE REFERENCE NAMDES. 02 RETLEN POINTER VALUE REFERENCE NAMLEN. 02 FILLER PIC S9(5) COMP VALUE 0. 01 RESULT PIC S9(9) COMP. (4) PROCEDURE DIVISION. START-ORION. CALL "SYS$TRNLNM" (5) USING OMITTED BY DESCRIPTOR TABNAM BY DESCRIPTOR CYGDES (6) OMITTED BY REFERENCE ITMLIS GIVING RESULT. IF RESULT IS FAILURE (7) GO TO ERROR-CHECK. DISPLAY "NAMDES: ", NAMDES(1:NAMLEN). GO TO THE-END. ERROR-CHECK. DISPLAY "Returned Error: ", RESULT CONVERSION. THE-END. STOP RUN. |
COBOL Notes
Example 4-7 System Service Call in FORTRAN |
---|
SUBROUTINE ORION IMPLICIT NONE ! Require declaration of all symbols INCLUDE '($SYSSRVNAM)' ! Declare system service names (1) INCLUDE '($LNMDEF)' ! Declare $TRNLNM item codes INCLUDE '(LIB$ROUTINES)' ! Declare LIB$ routines STRUCTURE /ITEM_LIST_3_TYPE/ ! Structure of item list (2) INTEGER*2 BUFLEN ! Item buffer length INTEGER*2 ITMCOD ! Item code INTEGER*4 BUFADR ! Item buffer address INTEGER*4 RETADR ! Item return length address END STRUCTURE RECORD /ITEM_LIST_3_TYPE/ ITEMLIST(2) ! Declare itemlist CHARACTER*255 EQUIV_NAME ! For returned equivalence name INTEGER*2 NAMLEN ! For returned name length VOLATILE EQUIV_NAME,NAMLEN (3) INTEGER*4 STATUS ! For returned service status (4) ! Fill in itemlist ! ITEMLIST(1).ITMCOD = LNM$_STRING ITEMLIST(1).BUFLEN = LEN(EQUIV_NAME) (5) ITEMLIST(1).BUFADR = %LOC(EQUIV_NAME) ITEMLIST(1).RETADR = %LOC(NAMLEN) ITEMLIST(2).ITMCOD = 0 ! For terminator ITEMLIST(2).BUFLEN = 0 ! Call SYS$TRNLM ! STATUS = SYS$TRNLNM (, ! ATTR omitted (6) 1 'LNM$FILE_DEV', ! TABNAM 2 'CYGNUS', ! LOGNAM 3 , ! ACMODE omitted 4 ITEMLIST) ! ITMLST ! Check return status, display translation if successful ! IF (.NOT. STATUS) THEN (7) CALL LIB$SIGNAL(%VAL(STATUS)) ELSE WRITE (*,*) 'CYGNUS translates to: "', 1 EQUIV_NAME(1:NAMLEN), '"' END IF END |
Previous | Next | Contents | Index |
Copyright © Compaq Computer Corporation 1998. All rights reserved. Legal |
5843PRO_006.HTML
|