HP OpenVMS Systems Documentation

HP OpenVMS Programming Concepts Manual

The LIB$RUN_PROGRAM routine causes the current image to exit at the
point of the call and directs the CLI, if present, to start running
another program. If LIB$RUN_PROGRAM executes successfully, control
passes to the second program; if not, control passes to the CLI. The
calling program cannot regain control. This technique is called
chaining.

This routine is provided primarily for compatibility with PDP-11
systems, on which chaining is used to extend the address space of a
system. Chaining may also be useful in an operating system environment
where address space is severely limited and large images are not
possible. For example, you can use chaining to perform system
generation on a small virtual address space because disk space is
lacking.

With LIB$RUN_PROGRAM, the calling program can pass arguments to the
next program in the chain only by using the common storage area. One
way to do this is to direct the calling program to call LIB$PUT_COMMON
to pass the information into the common area. The called program then
calls LIB$GET_COMMON to retrieve the data.

In general, this practice is not recommended. There is no convenient
way to specify the order and type of arguments passed into the common
area, so programs that pass arguments in this way must know about the
format of the data before it is passed. Fortran COMMON or BASIC
MAP/COMMON areas are global OWN storage. When you use this type of
storage, it is very difficult to keep your program modular and AST
reentrant. Further, you cannot use LIB$RUN_PROGRAM if a CLI is present,
as with image subprocesses and detached subprocesses.

The following COBOL program also demonstrates the use of
LIB$RUN_PROGRAM. When you compile and link these two programs, the
first calls LIB$RUN_PROGRAM, which activates the executable image of
the second. This call results in the following screen display:

THIS MESSAGE DISPLAYED BY PROGRAM PROG2
WHICH WAS RUN BY PROGRAM PROG1
USING LIB$RUN_PROGRAM

The LIB$DO_COMMAND routine stops program execution and directs the CLI
to execute a command. The routine's argument is the text of the command
line that you want to execute.

This routine is especially useful when you want to execute a CLI
command after your program has finished executing. For example, you
could set up a series of conditions, each associated with a different
command. You could also use the routine to execute a SUBMIT or PRINT
command to handle a file that your program creates.

Because of the following restrictions on LIB$DO_COMMAND, you should be
careful when you incorporate it in your program:

After the call to LIB$DO_COMMAND, the current image exits, and
control cannot return to it.

The text of the command is passed to the current CLI. Because you
can define your own CLI in addition to DCL and MCR, you must make sure
that the command is handled by the intended CLI.

If the routine is called from a subprocess and a CLI is not
associated with that subprocess, the routine executes correctly.

You can also use LIB$DO_COMMAND to execute a DCL command file. To do
this, include the at sign (@) along with a command file specification
as the input argument to the routine.

Some DCL CLI$ routines perform the functions of LIB$DO_COMMAND. See the
HP OpenVMS DCL Dictionary for more information.

What you type after this prompt determines the action of
LIB$DO_COMMAND. LIB$DO_COMMAND executes any command that is entered as
a valid string according to the syntax of PL/I. If the command you
enter is incomplete, you are prompted for the rest of the command. For
example, if you enter the SHOW command, you receive the following
prompt:

The RTL provides a number of routines that give you access to the CLI
callback facility. These routines allow a program to "call
back" to the CLI to perform functions that normally are performed
by CLI commands. These routines perform the following functions:

LIB$GET_SYMBOL

Returns the value of a CLI symbol as a string.

Optionally, this routine also returns the length of the returned
value and a value indicating whether the symbol was found in the local
or global symbol table. This routine executes only when the current CLI
is DCL.

LIB$SET_SYMBOL

Causes the CLI to define or redefine a CLI symbol.

The optional argument specifies whether the symbol is to be defined
in the local or global symbol table; the default is local. This routine
executes only when the current CLI is DCL.

LIB$DELETE_SYMBOL

Causes the CLI to delete a symbol.

An optional argument specifies the local or global symbol table. If
the argument is omitted, the symbol is deleted from the local symbol
table. This routine executes only when the current CLI is DCL.

LIB$SET_LOGICAL

Defines or redefines a supervisor-mode process logical name.

Supervisor-mode logical names are not deleted when an image exits.
This routine is equivalent to the DCL command DEFINE. LIB$SET_LOGICAL
allows the calling program to define a supervisor-mode process logical
name without itself executing in supervisor mode.

LIB$DELETE_LOGICAL

Deletes a supervisor-mode process logical name.

This routine is equivalent to the DCL command DEASSIGN.
LIB$DELETE_LOGICAL does not require the calling program to be executing
in supervisor mode to delete a supervisor-mode logical name.

Two run-time library routines, LIB$ENABLE_CTRL and LIB$DISABLE_CTRL,
allow you to call the CLI to enable or disable control characters.
These routines take a longword bit mask argument that specifies the
control characters to be disabled or enabled. Acceptable values for
this argument are LIB$M_CLI_CTRLY and LIB$M_CLI_CTRLT.

LIB$DISABLE_CTRL

Disables CLI interception of control characters.

This routine performs the same function as the DCL command SET
NOCONTROL=
n, where
n is T or Y.

It prevents the currently active CLI from intercepting the control
character specified during an interactive session.

For example, you might use LIB$DISABLE_CTRL to disable CLI
interception of Ctrl/Y. Normally, Ctrl/Y interrupts the current
command, command procedure, or image. If LIB$DISABLE_CTRL is called
with LIB$M_CLI_CTRLY specified as the control character to be disabled,
Ctrl/Y is treated like Ctrl/U followed by a carriage return.

LIB$ENABLE_CTRL

Enables CLI interception of control characters.

This routine performs the same function as the DCL command SET
CONTROL=
n, where
n is T or Y.

You can use LIB$SPAWN and LIB$ATTACH together to spawn a subprocess and
attach the terminal to that subprocess. These routines execute
correctly only if the current CLI is DCL. For more information on the
SPAWN and ATTACH commands, see the HP OpenVMS DCL Dictionary. For more information
on creating processes, see Chapter 2.

LIB$SPAWN

Spawns a subprocess.

This routine is equivalent to the DCL command SPAWN. It requests
the CLI to spawn a subprocess for executing CLI commands.

LIB$ATTACH

Attaches the terminal to another process.

This routine is equivalent to the DCL command ATTACH. It requests
the CLI to detach the terminal from the current process and reattach it
to a different process.

The VAX instruction set was designed for efficient use by high-level
languages and, therefore, contains many functions that are directly
useful in your programs. However, some of these functions cannot be
used directly by high-level languages.

The run-time library provides routines that allow your high-level
language program to use most VAX machine instructions that are
otherwise unavailable. On Alpha machines, these routines execute a
series of Alpha instructions that emulate the operation of the VAX
instructions. In most cases, these routines simply execute the
instruction, using the arguments you provide. Some routines that accept
string arguments, however, provide some additional functions that make
them easier to use.

The variable-length bit field is a VAX data type used to store small
integers packed together in a larger data structure. It is often used
to store single flag bits.

The run-time library contains five routines for performing operations
on variable-length bit fields. These routines give higher-level
languages that do not have the inherent ability to manipulate bit
fields direct access to the bit field instructions in the VAX
instruction set. Further, if a program calls a routine written in a
different language to perform some function that also involves bit
manipulation, the called routine can include a call to the run-time
library to perform the bit manipulation.

Extracts a field from the specified variable-length bit field and
returns it in sign-extended longword form.

LIB$EXTZV

Extracts a field from the specified variable-length bit field and
returns it in zero-extended longword form.

LIB$FFC

Searches the specified field for the first clear bit. If it finds one,
it returns SS$_NORMAL and the bit position (
find-pos argument) of the clear bit. If not, it
returns a failure status and sets the
find-pos argument to the start position plus the size.

LIB$FFS

Searches the specified field for the first set bit. If it finds one, it
returns SS$_NORMAL and the bit position (
find-pos argument) of the set bit. If not, it returns
a failure status and sets the
find-pos argument to the start position plus the size.

LIB$INSV

Replaces the specified field with bits 0 through [
size -1] of the source (
src argument). If the size argument is 0, nothing is
inserted.

Three scalar attributes define a variable bit field:

Base address---The address of the byte in memory that serves as a
reference point for locating the bit field.

Bit position---The signed longword containing the displacement of
the least significant bit of the field with respect to bit 0 of the
base address.

Size---A byte integer indicating the size of the bit field in bits
(in the range 0 <= size <= 32). That is, a bit field can be no
more than one longword in length.

Figure 24-1 shows the format of a variable-length bit field. The
shaded area indicates the field.

Figure 24-1 Format of a Variable-Length Bit Field

Bit fields are zero-origin, which means that the routine regards the
first bit in the field as being the zero position. For more detailed
information about VAX bit numbering and data formats, see the
VAX Architecture Reference Manual.

The attributes of the bit field are passed to an RTL routine in the
form of three arguments in the following order:

base

The following BASIC example illustrates three RTL routines. It opens
the terminal as a file and specifies HEX> as the prompt. This prompt
allows you to obtain input from the terminal without the question mark
that VAX BASIC normally adds to the prompt in an INPUT statement. The
program calls OTS$CVT_TZ_L to convert the character string input to a
longword. It then calls LIB$EXTZV once for each position in the
longword to extract the bit in that position. Because LIB$EXTVZ is
called with a function reference within the PRINT statement, the bits
are displayed.

Integer and floating-point routines give a high-level language program
access to the corresponding machine instructions. For a complete
description of these instructions, see the VAX Architecture Reference Manual. Table 24-4
lists the integer and floating-point routines once up front.

A queue is a doubly linked list. A run-time library routine specifies a
queue entry by its address. Two longwords, a forward link and a
backward link, define the location of the entry in relation to the
preceding and succeeding entries. A self-relative queue is a queue in
which the links between entries are displacements; the two longwords
represent the displacements of the current entry's predecessor and
successor. The VAX instructions INSQHI, INSQTI, REMQHI, and REMQTI
allow you to insert and remove an entry at the head or tail of a
self-relative queue. Each queue instruction has a corresponding RTL
routine.

The self-relative queue instructions are interlocked and cannot be
interrupted, so that other processes cannot insert or remove queue
entries while the current program is doing so. Because the operation
requires changing two pointers at the same time, a high-level language
cannot perform this operation without calling the RTL queue access
routines.

When you use these routines, cooperating processes can communicate
without further synchronization and without danger of being
interrupted, either on a single processor or in a multiprocessor
environment. The queue access routines are also useful in an AST
environment; they allow you to add or remove an entry from a queue
without being interrupted by an asynchronous system trap.

The remove queue instructions (REMQHI or REMQTI) return the address of
the removed entry. Some languages, such as BASIC, COBOL, and Fortran,
do not provide a mechanism for accessing an address returned from a
routine. Further, BASIC and COBOL do not allow routines to be arguments.

In BASIC and Fortran, queues can be quadword aligned in a named COMMON
block by using a linker option file to specify alignment of program
sections. The LIB$GET_VM routine returns memory that is quadword
aligned. Therefore, you should use LIB$GET_VM to allocate the virtual
memory for a queue. For instance, to create a COMMON block called
QUEUES, use the LINK command with the FILE/OPTIONS qualifier, where
FILE.OPT is a linker option file containing the line: