Kednos PL/I for OpenVMS Systems
User Manual


Previous Contents Index

  1. System routines are often written so the parameter passed occupies more storage than the object requires. For example, some system services have parameters that return a single bit value in a longword. These variables must be declared BIT(32) ALIGNED (not BIT(1) ALIGNED) so adjacent storage is not overwritten by return values or used incorrectly as input. (Longword Boolean parameters should always be declared BIT(32) ALIGNED.)
  2. AST procedures and those passed as parameters of type ENTRY VALUE or ANY VALUE must be external procedures. This applies to all system routines which take procedure parameters, unless explicitly stated otherwise.
  3. This is actually an unsigned integer. This declaration is interpreted as a signed number; use the POSINT function to determine the actual value, if necessary.
  4. System services require CHARACTER string representation for parameters. Most other system routines allow either CHARACTER or CHARACTER VARYING. For parameter declarations, n should be an asterisk. Note that all system services, RTL routines and utility routines are declared in PLI$STARLET.
  5. PL/I does not support FIXED BINARY numbers with precisions greater than 32. To use larger values, declare variables to be BIT variables of the appropriate size and use the POSINT and SUBSTR bits as necessary to access the values, or declare the item as a structure. The RTL routines LIB$ADDX and LIB$SUBX, which are declared in PLI$STARLET, may be useful if you need to perform arithmetic on these types.
  6. Routines declared in PLI$STARLET often use ANY so that you can declare the data structure in the most convenient way for your application. ANY may be necessary in some cases because PL/I does not allow parameter declarations for some data types used by the OpenVMS system.
  7. For parameter declarations, the bounds must be constant for arrays passed by reference, or the REFERENCE attribute must be used. For arrays passed by descriptor, asterisks should be used for the array extent instead. (OpenVMS system routines almost always take arrays by reference.)

Note

All system services and many system constants and data structures are declared in PLI$STARLET.TLB.

If a system routine argument is optional, it will be indicated in the format section of the routine description in one of two ways:

If the comma appears outside the brackets, you must either pass a zero by value or use a comma in the argument list as a placeholder to indicate the place of the omitted argument. If this is the last argument in the list, you do not need to include the comma as a placeholder, as the PL/I compilers will pass a zero by value for the argument, fullfilling any minimum argument vector length requirements, for instance in the case of VMS system services. Otherwise, you can use a comma in the argument list as a placeholder, and the PL/I compilers will pass a zero by value for the argument.

To determine the PL/I parameter descriptors in the declaration of a given system routine, you can display or print the text module for that routine. For example:


$ LIBRARY/EXTRACT=SYS$TRNLNM/OUTPUT=LP:TRNLNM -
_$ SYS$LIBRARY:PLI$STARLET/TEXT

This LIBRARY command prints the contents of the text module SYS$TRNLNM from the library SYS$LIBRARY:PLI$STARLET. The file is printed on the device LP; the listing file is named TRNLNM.TXT.

11.6.4.3 Symbol Definitions

Many system routines depend on values that are defined in separate symbol definition files. OpenVMS Run-Time Library routines require you to include symbol definitions when you are calling a Screen Management facility routine or a routine that is a jacket to a system service. A jacket routine provides a simpler interface to the corresponding system service. For example, the routine LIB$SYS_ASCTIM is a jacket routine for the $ASCTIM system service.

If you are calling a system service, you must include the module $SSDEF to check status. Many system services require other symbol definitions as well. To determine whether you need to include other symbol definitions for the system service you want to use, refer to the documentation for that particular system service. If the documentation states that values are defined in a macro, you must include those symbol definitions in your program.

For example, the description for the flags parameter in the SYS$MGBLSC (Map Global Section) system service states that "Symbolic names for the flag bits are defined by the $SECDEF macro." Therefore, when you call SYS$MGBLSC you must include the definitions provided in the $SECDEF module.

A definition module is included as follows:


%INCLUDE $SSDEF; 

You can declare the names of global symbols using the GLOBALREF and VALUE attributes. Then, you can use the names to represent values in an argument list to invoke a system service. For symbolic names that are not defined as OpenVMS global symbols, PL/I provides text modules in the default INCLUDE library PLI$STARLET.

The names of the text modules, and the names and values of the symbols defined in each, are the same as the MACRO definitions in the system macro library, STARLET.MLB.

11.7 Condition Values

Many system routines return a condition value that indicates success or failure; this value can be either returned or signaled. If a condition value is returned, then you must check the returned value to determine whether the call to the system routine was successful. If a condition value is signaled, then the condition value is signaled to your program instead of being returned as a function value.

Thus, to obtain a condition value from any system routine, you can declare the routine as a function. For example:


DECLARE SYS$SETEF ENTRY (FIXED BINARY(31) VALUE) 
                  RETURNS (FIXED BINARY(31)); 

This declaration of the SYS$SETEF service allows you to invoke the routine as a function and to obtain a condition value. To provide a unique means of identifying every return condition in the system, fields within the longword value are defined as shown in Figure 11-8.

Figure 11-8 Condition Value Fields


control bits (31-28)

Define special actions to be taken. At present, only bit 28 is used; when set, it inhibits the printing of the message associated with the return status value at image exit. Bits 29 through 31 are reserved for future use by Hewlett Packard.

facility number (27-16)

Is a unique value assigned to the system component or facility that is returning the status value. Within this field, bit 27 has a special significance. If bit 27 is clear, the facility is retistered with Hewlett Packard: the remaining value in the facility number field is a number assigned by Hewlett Packard. If bit 27 is set, the number can indicate a customer-defined facility.

message number (15-3)

Gives an identification number that specifically describes the return status or condition. Within this field, bit 15 has a special significance. If bit 15 is set, then this message number is unique to the facility that is issuing the message. If bit 15 is clear, then this message has been issued by more than one system facility.

severity (2-0)

Specifies a numeric value indicating the severity of the return status. The possible values in these three bits, and their meanings, are as follows:
Value Meaning
0 Warning
1 Success
2 Error
3 Informational
4 Severe Error
5-7 Reserved

Note that odd values indicate success (an information condition is considered a successful status) and that even values indicate failures (a warning is considered an unsuccessful status).

For testing condition values in a PL/I program, you can choose to test only whether a procedure completed successfully, or you can test for specific return status values. For either case, you can use the variables declared in the text module $STSDEF. This module is in the default PL/I text library PLI$STARLET.TLB. The module $STSDEF contains the following declarations:


DECLARE STS$VALUE FIXED BINARY(31),    /* status value              */ 
       1 STS$FIELDS BASED (ADDR(STS$VALUE)), 
         2 STS$SEVERITY,               /* low-order 3 bits          */ 
           3 STS$SUCCESS BIT(1),       /* low-order bit             */ 
           3 STS$REST BIT(2),          /* bits 1 through 2          */ 
         2 STS$MSG,                    /* bits 2 through 15         */ 
           3 STS$MSG_NO BIT(12),       /* numeric value             */ 
           3 STS$FAC_SP BIT(1),        /* if set, facility-specific */ 
         2 STS$FAC,                    /* bits 16 through 27        */ 
           3 STS$FAC_NO BIT(11),       /* facility number           */ 
           3 STS$CUST_DEF BIT(1),      /* 0 = registered facility   */ 
         2 STS$CONTROL, 
           3 STS$INHIB_MSG BIT(1),     /* 1 = do not print          */ 
           3 STS$RESERVED BIT(3),      /* 32 bits                   */ 
         2 STS$FILLER CHARACTER(0);    /* for byte alignment        */ 

To obtain these declarations, specify a %INCLUDE statement in a PL/I program as follows:


%INCLUDE $STSDEF; 

The compiler will automatically locate this module in PLI$STARLET.

To test a condition value for success or failure, you need only test the structure member STS$SUCCESS declared in the structure STS$FIELDS. If this bit is true, then the condition value is a successful value. For example:


%INCLUDE SYS$SETPRN; 
 
%INCLUDE $STSDEF; 
 
STS$VALUE = SYS$SETPRN('Student'); 
IF ^STS$SUCCESS THEN GOTO BAD_NAME; 

The statements at the label BAD_NAME can test the value of the variable STS$VALUE and take some action based on its value.

11.7.1 Testing for Specific Condition Values

You can also test for specific condition values. Each numeric condition value defined by the system has a symbolic name associated with it. The names of these values are defined as system global symbols, and their values can be accessed by referring to their symbolic names.

The global symbol names for OpenVMS condition values have the following format:

facility$_code 

facility

Is an abbreviation or acronym for the system facility that defined the global symbol.

code

Is a mnemonic for the specific condition value.

Some examples of facility codes used in global symbol names follow.
Facility Code Used by
PLI PL/I run-time procedures; these status codes are listed in Appendix A.
SS System services; these status codes are listed in the OpenVMS System Services Reference Manual.
DTK DTK$ Run-Time Library facility.
LIB LIB$ Run-Time Library facility.
MTH MTH$ Run-Time Library facility.
OTS OTS$ Run-Time Library facility.
SMG SMG$ Run-Time Library facility.
STR STR$ Run-Time Library facility.
RMS File system procedures; these status codes are listed in the OpenVMS Record Management Services Reference Manual.
SOR SORT procedures; these status codes are listed in the VMS Sort/Merge Utility Manual.

Definitions for the global symbol names for these facilities are located in the default system object module libraries, and thus are automatically located when you link a PL/I program that references them.

When you write a PL/I program that calls system procedures and you want to test for specific return status values using the symbol names, you must do the following:

  1. Determine, from the documentation of the routine, the return status values that can be returned, and choose the values for which you want to provide specific tests.
  2. Include the appropriate module containing the definition from PLI$STARLET or declare the symbolic name for each value of interest as FIXED BINARY(31) and give the variable the GLOBALREF and VALUE attributes. (Note that the first method can be optimized more effectively by the compiler in some cases because the actual values are available at compile time.)

For example, the documentation of the SYS$SETPRN service indicates that it may return the status codes SS$_DUPLNAM (if the name specified as an argument duplicates a name that already exists) and SS$_IVLOGNAM (if the name is invalid; for example, if it contains more than 15 characters). These symbol names can be defined and used as in the following example.


%INCLUDE SYS$SETPRN; 
 
%INCLUDE $SSDEF;              /* includes SS$_DUPLNAM and SS$_IVLOGNAM */ 
 
%INCLUDE $STSDEF; 
   .
   .
   .
STS$VALUE = SYS$SETPRN(NAME); 
IF STS$VALUE - SS$_DUPLNAM THEN 
   GET LIST(NAME) OPTIONS 
                  (PROMPT('Name in use. Reenter: ')); 
IF STS$VALUE = SS$_IVLOGNAM 
   THEN GET LIST(NAME) OPTIONS 
                   (PROMPT('Invalid string. Reenter: ')); 

The next example illustrates the invocation of the Set Event Flag (SYS$SETEF) system service, followed by tests for (1) success or failure and (2) the successful status code SS$_WASSET.


%INCLUDE SYS$SETEF; 
 
%INCLUDE $SSDEF; 
 
%INCLUDE $STSDEF; 
 
STS$VALUE = SYS$SETEF(4); 
 
IF ^STS$SUCCESS THEN RETURN (STS$VALUE);(1)
IF STS$VALUE = SS$_WASSET THEN DO;(2)

In this example, the symbolic name SS$_WASSET is included from PLI$STARLET. The value associated with this condition value is a successful value; it indicates that the flag specified in the routine invocation was previously set.

The routine invocation returns the condition value in the variable STS$VALUE. The IF statement checks the variable STS$SUCCESS for success or failure. If the service returned a failure condition, the routine returns with the value of STS$VALUE in the RETURN statement. If the service returned with a successful status, the routine continues with an IF statement that checks whether or not the flag was previously set. If so, the DO statement specified in the THEN clause activates the DO-group.

11.7.2 Setting and Displaying Fields Within a Status Value

You can use the structure STS$FIELDS to set or display fields within a status value. For example, to define application-specific message numbers using the format used by VMS, you can specify a facility-wide message number, set the STS$CUST_DEF field to '1'B, assign unique numbers to messages, and define severities for the messages.

Because the fields within this structure are defined as bit strings, and because it is usually more convenient to express facility or message numbers as integers, you must use the UNSPEC built-in function to convert integer values to the appropriate bit-string representation. The following example shows how to define a value for STS$VALUE in which the customer-defined facility number is 55 and the unique message number is 14:


DECLARE I FIXED BINARY(31); 
 
I = 55; 
STS$FAC_NO = UNSPEC(I); 
STS$CUST_DEF = '1'B; 
 
I = 14; 
STS$MSG_NO = UNSPEC(I); 
STS$FAC_SP = '1'B; 

The intermediate variable I is used to perform the conversions, because the UNSPEC built-in function does not accept constants for arguments.

To set a value for a severity, you must also use the STRING built-in function so that you can set the field to a single value (note that there are two bit-string variables defined within the field SEVERITY). For example:


I = 4; 
STRING(STS$SEVERITY) = UNSPEC(I); 

Here, the severity field of STS$VALUE is set to 4.

You can use a similar technique to display fields within a status value. For example, to display the entire facility number (including STS$CUST_DEF), you could write the following:


UNSPEC(I) = STRING(STS$FAC); 
PUT SKIP LIST('Facility',I); 

Here, the UNSPEC pseudovariable assigns an integer value to I that represents the bit-string value of the STS$FAC field. You can use the same technique to output the STS$SEVERITY and STS$MSG fields. To display or interpret the STS$FAC_NO or STS$MSG_NO fields, you could use the following:


UNSPEC(I) = STS$FAC_NO; 
PUT SKIP LIST('Customer facility number',I); 

You do not need to use the UNSPEC built-in function or the UNSPEC pseudovariable to set or interpret the 1-bit fields STS$SUCCESS, STS$CUST_DEF, STS$FAC_SP, or STS$INHIB_MSG. See the OpenVMS Messages Utility Reference Manual for more information on user-defined messages.

11.8 Examples of Calling System Routines

This section provides complete examples of calling system routines, including some SORT/MERGE examples, from PL/I. In addition to the examples provided here, the VMS Run-Time Library Routines Volume and the OpenVMS System Services Reference Manual also provide examples for selected routines. Refer to these manuals for help on the use of a specific system routine. For additional information on the OpenVMS SORT/MERGE utility, refer to the VMS Sort/Merge Utility Manual.

The system service examples on the next few pages illustrate a number of system service calls. These examples illustrate the following tasks:

All the sample programs use the system service INCLUDE files in PLI$STARLET to declare the system services. The text of each sample program shows the INCLUDE file for the system service.

All the examples also include the module $STSDEF; however, the contents of this text module are not shown in the examples. The contents of $STSDEF are listed in Section 11.7.

11.8.1 Logical Name Translation

Example 11-2 illustrates a call to the Translate Logical Name (SYS$TRNLNM) system service. This system service returns the result of a single logical name translation. In this example, the routine ORION translates the logical name CYGNUS and displays the result on the terminal. If the name is not defined, the routine displays a message indicating that fact. The following notes are keyed to Example 11-2:

  1. The procedure declares the logical name to be translated, the logical name table to be searched, a structure that describes to SYS$TRNLNM what information is desired, and where this information should be stored.
  2. The reference to SYS$TRNLNM specifies the logical name table, the logical name CYGNUS, and the structure that contains pointers to the variables that will receive the translated logical name length and the logical name. The routine reference does not specify all the arguments. At run time, the argument list for this routine will contain zeros for the omitted arguments.

Example 11-2 Translating a Logical Name

ORION: PROCEDURE OPTIONS(MAIN) RETURNS(FIXED BINARY(31)); 
 
    %INCLUDE SYS$TRNLNM; 
    %INCLUDE $LNMDEF; 
    %INCLUDE $SSDEF; 
    %INCLUDE $STSDEF; 
 
    %REPLACE MAXLEN BY 256; 
 
    DECLARE 
       CYGDES CHARACTER(6) STATIC INITIAL ('CYGNUS'), 
       NAMETAB CHARACTER(17) STATIC INITIAL ('LNM$PROCESS_TABLE'), 
       1 RESULTS, 
         2 BUFFER_LENGTH FIXED BINARY(15) INITIAL(MAXLEN), 
         2 ITEM_CODE FIXED BINARY(15) INITIAL(LNM$_STRING), 
         2 BUFFER_ADDRESS POINTER, 
         2 RETURN_LENGTH_ADDRESS POINTER, 
         2 TERMINATOR FIXED BINARY(31) INITIAL(0), 
       BUFFER CHARACTER(MAXLEN), 
       RETURN_LENGTH FIXED BINARY(15);                      (1)
 
    RESULTS.BUFFER_ADDRESS = ADDR(BUFFER); 
    RESULTS.RETURN_LENGTH_ADDRESS = ADDR(RETURN_LENGTH); 
    STS$VALUE = SYS$TRNLNM( , NAMETAB, CYGDES, , RESULTS);  (2)
    IF STS$VALUE = SS$_NOLOGNAM 
    THEN 
       PUT SKIP LIST('CYGNUS not defined'); 
    ELSE 
       IF STS$SUCCESS 
       THEN 
          PUT SKIP LIST('CYGNUS is',SUBSTR(BUFFER,1,RETURN_LENGTH)); 
 
    RETURN(STS$VALUE); 
 
    END ORION; 


Previous Next Contents Index