HP OpenVMS Systems Documentation |
HP OpenVMS Programming Concepts Manual
1.8 Optional HP Software Development Tools
HP supplies optional software development tools for the OpenVMS
environment, such as HP DECset. HP DECset is a set of tools that
supports software coding, testing, and maintenance of applications and
data.
These tools can be used individually or as part of the optional HP
software development environment.
The basic OpenVMS tool for transparent, intuitive management of data is the Record Management Services (RMS) subsystem. RMS is a collection of routines that gives programmers a device-independent method for storing, retrieving, and modifying data for their application. RMS also provides extensive protection and reliability features to ensure data integrity. RMS is a higher level interface to the file system and OpenVMS I/O subsystem. It is used by all products that run on OpenVMS VAX, OpenVMS Alpha, and OpenVMS I64 for file and record operations. A subset of RMS services permits network file operations that are generally transparent to the user.
On OpenVMS Alpha and OpenVMS I64 systems, RMS supports I/O operations
to and from 64-bit addressable space.
RMS supports a variety of file organizations, record formats, and record-access modes. RMS supports sequential, relative, and indexed disk file organizations, and fixed- and variable-length records. It supports a number of record-access modes: sequential, by key value, by relative record number, or by record file address. RMS is designed primarily for mass storage devices (disks and tapes), but also supports unit-record devices such as terminals or printers. RMS routines assist user programs in processing and managing files and their contents. RMS routines perform these services for application programs:
RMS promotes safe and efficient file sharing by providing multiple
access modes, automatic record locking when applicable, and optional
buffer sharing by multiple processes.
RMS file utilities allow users to analyze the internal structure of an RMS file and to determine the most appropriate set of parameters to tune an RMS file. RMS utilities can also be used to create, efficiently load, and reclaim space in an RMS file. RMS file maintenance utilities include the following:
The Analyze/RMS_File utility allows the programmer to analyze the internal structure of an OpenVMS RMS file and generate a report on its structure and use, as well as interactively explore the file's structure. The utility can generate an FDL file from an RMS file for use with the Edit/FDL utility to optimize the data file. File Definition Language (FDL) is a special-purpose language for specifying file characteristics; it is useful with higher level languages or for ensuring that files are properly tuned. FDL makes use of RMS control blocks: the file access block (FAB), the record access block (RAB), and the extended attribute block (XAB). The Edit/FDL utility creates a new FDL file according to user specifications. The Create/FDL utility uses the specifications of an existing FDL file to create a new empty data file. You can use the Convert utility to copy records from one file to another, while changing the record format and file organization, and to append records to an existing file. The Convert/Reclaim utility reclaims empty bucket space in an indexed file to allow new records to be written to it.
Part 1
This part describes the creation, communication, and control of
processes. It also describes symmetric multiprocessing (SMP), and the
synchronizing of data access, programming operations, and access to
resources.
|
Characteristic | Subprocess | Detached Process |
---|---|---|
Privileges | Received from creating process. | Specified by creating process. |
Quotas and limits | Some shared with creating process. | Specified by creating process, but not shared with creating process. |
User authorization file | Used for information not given by creating process. | Used for most information not given by creating process. |
User identification code | Received from creating process. | Specified by creating process. |
Restrictions | Exist as long as creating process exists. | None. |
How created | SYS$CREPRC, or LIB$SPAWN from another process. | SYS$CREPRC from another process. |
When deleted | When creating process exits, or at image exit or logout, depending on whether a CLI is present. | At image exit or logout, depending on whether a CLI is present. |
Command language interpreter (CLI) present | Usually not if created with SYS$CREPRC; always yes if spawned. | Usually present, but not necessarily. |
The execution context of a process defines a process to the system and includes the following:
When the system creates a detached process as the result of a login, it uses the system user authorization file (SYSUAF.DAT) to determine the process's execution context.
For example, the following occurs when you log in to the system:
A process executes in one of the following modes:
You can create a subprocess using the LIB$SPAWN run-time library routines, the SYS$CREPRC system service, or the C system() call. A subprocess created with LIB$SPAWN is called a spawned subprocess.
Table 2-2 lists the context values provided by LIB$SPAWN, SYS$CREPRC, and the C system() call for a subprocess when you are using the default values in the routine calls.
Context | LIB$SPAWN | SYS$CREPRC | C system () |
---|---|---|---|
DCL | Yes | No 1 | Yes |
Default device and directory | Parent's | Parent's | Parent's |
Symbols | Parent's | No | Parent's |
Logical names | Parent's 2 | No 2 | Parent's 2 |
Privileges | Parent's | Parent's 3 | Parent's |
Priority | Parent's | 0 or 2, depending on language | Parent's |
As of OpenVMS Version 7.3-1, the way OpenVMS names spawned subprocesses was changed to improve performance. Prior to OpenVMS Version 7.3-1, if no process name was supplied, the system constructed a name by appending _n to the user name, where n was the next available nonduplicate integer for any process currently in the system. For example, the first spawned process from the SYSTEM would be called SYSTEM_1, the second, SYSTEM_2, and so on. The next available number was chosen as soon as a gap was found.
With OpenVMS Version 7.3-1, the default-constructed process name for subprocesses was changed. Instead of searching incrementally for the next unique number, a random number is chosen to append to the user name. Therefore, the first processes that are spawned from user SYSTEM might be SYSTEM_154, SYSTEM_42, SYSTEM_87, and so on. This procedure results in a very high probability of finding a unique name on the first try, because it is unlikely that the same number is already in use. This procedure greatly reduces the cost of process creation, and applications that rely on spawned subprocesses might see a dramatic performance improvement with this change.
However, some applications might rely on the prior method of assigning subprocess names. The DCL_CTLFLAGS parameter, a bitmask used to alter default behavior for certain commands on a systemwide basis, is available to allow you to configure the system as necessary. The low bit of the bitmask is defined, and it controls the default process-name assignment for a subprocess created using the SPAWN command or LIB$SPAWN routine.
Bit 0 of DCL_CTLFLAGS selects the behavior for assigning the default subprocess names:
The LIB$SPAWN routine enables you to create a subprocess and to set some context options for the new subprocess. LIB$SPAWN creates a subprocess with the same priority as the parent process (generally priority 4). The format for LIB$SPAWN is:
LIB$SPAWN ([command_string],[input_file],
,[output_file],[flags],[process-name],[process_id],[completion_status]
,[completion_efn],[completion_astadr],[completion_astarg],[prompt],[cli])
For complete information on using each argument, refer to the LIB$SPAWN routine in HP OpenVMS RTL Library (LIB$) Manual.
Use the command_string argument to specify a single DCL command to execute once the subprocess is initiated. You can also use this argument to execute a command procedure that, in turn, executes several DCL commands (@command_procedure_name).
Redefining SYS$INPUT and SYS$OUTPUT
Use the input_file and output_file arguments to specify alternate input and output devices for SYS$INPUT and SYS$OUTPUT. Using alternate values for SYS$INPUT and SYS$OUTPUT can be particularly useful when you are synchronizing processes that are executing concurrently.
Passing Parent Process Context Information to the Subprocess
Use the flags argument to specify which characteristics of the parent process are to be passed on to the subprocess. With this argument, you can reduce the time required to create a subprocess by passing only a part of the parent's context. You can also specify whether the parent process should continue to execute (execute concurrently) or wait until the subprocess has completed execution (execute in line).
After the Subprocess Completes Execution
Use the completion_status, completion_efn, and completion_astadr arguments to specify the action to be taken when the subprocess completes execution (send a completion status, set a local event flag, or invoke an AST procedure). For more information about event flags and ASTs, refer to Chapter 8.
The LIB$SPAWN routine and SPAWN command do not return a completion status code of 0 from a subprocess command procedure.
The LIB$SPAWN routine can fail in a detached process as well, because it is dependent upon and requires the presence of a command language interpreter (CLI), such as DCL. Without a CLI present in the current process, this call fails with a "NOCLI, no CLI present to perform function" error. Note that a detached process may not have a CLI present.
You can use SYS$CREPRC in place of LIB$SPAWN; though with SYS$CREPRC the context of the parent process (symbols and logical names) is not propogated into the subprocess.
When using LIB$SPAWN asynchronously (with CLI$M_NOWAIT), you have to synchronize completion. For if the parent process should exit, all subprocesses exit, potentially resulting in an unexpected series of failures of all subprocesses of the exiting parent process.
Specifying an Alternate Prompt String
Use the prompt argument to specify a prompt string for the subprocess.
Specifying an Alternate Command Language Interpreter
Use the cli argument to specify a command language interpreter for the subprocess.
Examples of Creating Subprocesses
The following examples create a subprocess that executes the commands in the COMMANDS.COM command procedure, which must be a command procedure on the current default device in the current default directory. The created subprocess inherits symbols, logical names (including SYS$INPUT and SYS$OUTPUT), keypad definitions, and other context information from the parent. The subprocess executes while the parent process hibernates.
! Declare status and library routine INTEGER STATUS, LIB$SPAWN STATUS = LIB$SPAWN ('@COMMANDS') |
The equivalent C code follows:
#include <descrip.h> #include <lib$routines.h> #include <ssdef.h> #include <stsdef.h> main() { int RetStat; $DESCRIPTOR( CmdDsc, "@COMMANDS" ); RetStat = lib$spawn( &CmdDsc ); if (!$VMS_STATUS_SUCCESS( RetStat )) return RetStat; return SS$_NORMAL; } |
The following Fortran program segment creates a subprocess that does not inherit the parent's symbols, logical names, or keypad definitions. The subprocess reads and executes the commands in the COMMANDS.COM command procedure. (The CLI$symbols are defined either in the $CLIDEF module of the system object or in shareable image library. See Chapter 26 for more information.)
! Mask for LIB$SPAWN INTEGER MASK EXTERNAL CLI$M_NOCLISYM, 2 CLI$M_NOLOGNAM, 2 CLI$M_NOKEYPAD ! Declare status and library routine INTEGER STATUS, LIB$SPAWN ! Set mask and call LIB$SPAWN MASK = %LOC(CLI$M_NOCLISYM) .OR. 2 %LOC(CLI$M_NOLOGNAM) .OR. 2 %LOC(CLI$M_NOKEYPAD) STATUS = LIB$SPAWN ('@COMMANDS.COM', 2 ,, 2 MASK) |
The equivalent C program follows:
#include <clidef.h> #include <descrip.h> #include <lib$routines.h> #include <ssdef.h> #include <stsdef.h> main() { int RetStat; int FlagsMask = CLI$M_NOCLISYM | CLI$M_NOLOGNAM | CLI$M_NOKEYPAD; $DESCRIPTOR( CmdDsc, "@COMMANDS.COM" ); RetStat = lib$spawn( &CmdDsc, 0, 0, &FlagsMask ); if (!$VMS_STATUS_SUCCESS( RetStat )) return RetStat; return SS$_NORMAL; } |
The following Fortran program segment creates a subprocess to execute the image $DISK1:[USER.MATH]CALC.EXE. CALC, reads data from DATA84.IN, and writes the results to DATA84.RPT. The subprocess executes concurrently. (CLI$M_NOWAIT is defined in the $CLIDEF module of the system object or shareable image library; see Chapter 26.)
! Mask for LIB$SPAWN EXTERNAL CLI$M_NOWAIT ! Declare status and library routine INTEGER STATUS, LIB$SPAWN STATUS = LIB$SPAWN ('RUN $DISK1:[USER.MATH]CALC', ! Image 2 'DATA84.IN', ! Input 2 'DATA84.RPT', ! Output 2 %LOC(CLI$M_NOWAIT)) ! Concurrent |
The C version of the example follows:
#include <clidef.h> #include <descrip.h> #include <lib$routines.h> #include <ssdef.h> #include <stsdef.h> main() { int RetStat; int FlagsMask = CLI$M_NOWAIT; $DESCRIPTOR( CmdDsc, "RUN $DISK1:[USER.MATH]CALC" ); $DESCRIPTOR( InpDsc, "DATA84.IN" ); $DESCRIPTOR( OutDsc, "DATA84.RPT" ); RetStat = lib$spawn( &CmdDsc, &InpDsc, &OutDsc, &FlagsMask ); if (!$VMS_STATUS_SUCCESS( RetStat )) return RetStat; return SS$_NORMAL; } |
The following example shows the calling of a C system() function:
#include <ssdef.h> #include <stdio.h> #include <stdlib.h> main() { printf("calling system() \n"); system("show system"); printf("done\n"); return SS$_NORMAL; } |
This example shows the use of the system() call to spawn a DCL SHOW
SYSTEM command; it subsequently returns and the execution of the main()
image continues..
2.4.4 Using SYS$CREPRC to Create a Subprocess
The Create Process (SYS$CREPRC) system service creates both subprocesses and detached processes. This section discusses creating a subprocess; Section 2.5 describes creating a detached process. When you call the SYS$CREPRC system service to create a process, you define the context by specifying arguments to the service. The number of subprocesses a process can create is controlled by its PQL$_PRCLM subprocess quota, an individual quota description under the quota argument.
Though SYS$CREPRC does not set many context values for the subprocess by default, it does allow you to set many more context values than LIB$SPAWN. For example, you cannot specify separate privileges for a subprocess with LIB$SPAWN directly, but you can with SYS$CREPRC.
By default, SYS$CREPRC creates a subprocess rather than a detached process. The format for SYS$CREPRC is as follows:
SYS$CREPRC ([pidadr] ,[image] ,[input] ,[output] ,[error] ,[prvadr]
,[quota]
,[prcnam] ,[baspri] ,[uic] ,[mbxunt] ,[stsflg] ,[itemlst] ,[node])
Ordinarily, when you create a subprocess, you need only assign it an image to execute and, optionally, the SYS$INPUT, SYS$OUTPUT, and SYS$ERROR devices. The system provides default values for the process's privileges, resource quotas, execution modes, and priority. In some cases, however, you may want to define these values specifically. The arguments to the SYS$CREPRC system service that control these characteristics follow. For details, see the descriptions of arguments to the SYS$CREPRC system service in the HP OpenVMS System Services Reference Manual.
The default values passed into the subprocess might not be complete enough for your use. The following sections describe how to modify these default values with SYS$CREPRC.
Redefining SYS$INPUT, SYS$OUTPUT, and SYS$ERROR
Use the input, output, and error arguments to specify alternate input, output, and error devices for SYS$INPUT, SYS$OUTPUT, and SYS$ERROR. Using alternate values for SYS$INPUT, SYS$OUTPUT, and SYS$ERROR can be particularly useful when you are synchronizing processes that are executing concurrently. By providing alternate equivalence names for the logical names SYS$INPUT, SYS$OUTPUT, and SYS$ERROR, you can place these logical name/equivalence name pairs in the process logical name table for the created process.
The following C program segment is an example of defining input, output, and error devices for a subprocess:
#include <descrip.h> #include <ssdef.h> #include <starlet.h> #include <stdio.h> #include <stsdef.h> // Comment syntax here assumes compiler support main() { int RetStat; $DESCRIPTOR(input,"SUB_MAIL_BOX"); // Descriptor for input stream $DESCRIPTOR(output,"COMPUTE_OUT"); // Descriptor for output and error $DESCRIPTOR(image,"COMPUTE.EXE"); // Descriptor for image name // Create the subprocess RetStat = sys$creprc( 0, // process id &image, // image &input, (1) // input SYS$INPUT device &output, (2) // output SYS$OUTPUT device &output, (3) // error SYS$ERROR device 0,0,0,0,0,0,0); if (!$VMS_STATUS_SUCCESS( RetStat )) return RetStat; return SS$_NORMAL; } } |
The SYS$CREPRC system service does not provide default equivalence names for the logical names SYS$INPUT, SYS$OUTPUT, and SYS$ERROR. If none are specified, any entries in the group or system logical name tables, if any, may provide equivalences. If, while the subprocess executes, it reads or writes to one of these logical devices and no equivalence name exists, an error condition results.
The SYS$CREPRC system service also does not provide default equivalence names for the logical names SYS$LOGIN, SYS$LOGIN_DEVICE, and SYS$SCRATCH. These logical names are available to the created process only when the specified image is LOGINOUT, and when the PRC$M_NOUAF flag is not set.
In a program that creates a subprocess, you can cause the subprocess to share the input, output, or error device of the creating process. You must first follow these steps:
Previous | Next | Contents | Index |