Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

3.2.1 Using the PID to Obtain Information

The process information procedures return information about processes by using the process identification (PID) or the process name. The PID is a 32-bit number that is unique for each process in the cluster. Specify the PID by using the pidadr argument. All the significant digits of a PID must be specified; only leading zeros can be omitted.

With kernel threads, the PID continues to identify a process, but it can also identify a kernel thread within that process. In a multithreaded process each kernel thread has its own PID that is based on the initial threads PID.

3.2.2 Using the Process Name to Obtain Information

To obtain information about a process using the process name, specify the prcnam argument. Although a PID is unique for each process in the cluster, a process name is unique (within a UIC group) only for each process on a node. To locate information about processes on the local node, specify a process name string of 1 to 15 characters. To locate information about a process on a particular node, specify the full process name, which can be up to 23 characters long. The full process name is configured in the following way:

Note that a local process name can look like a remote process name. Therefore, if you specify ATHENS::SMITH, the system checks for a process named ATHENS::SMITH on the local node before checking node ATHENS for a process named SMITH.

OpenVMS Programming Interfaces: Calling a System Routine and the OpenVMS System Services Reference Manual describe these routines completely, listing all items of information that you can request. LIB$GETJPI, SYS$GETJPI, and SYS$GETJPIW share the same item codes with the following exception: LIB$K_ items can be accessed only by LIB$GETJPI.

In the following example, the string argument rather than the numeric argument is specified, causing LIB$GETJPI to return the UIC of the current process as a string:


! Define request codes 
INCLUDE '($JPIDEF)' 
 
! Variables for LIB$GETJPI 
CHARACTER*9 UIC 
INTEGER LEN 
 
STATUS = LIB$GETJPI (JPI$_UIC, 
2                    ,,, 
2                    UIC, 
2                    LEN) 

To specify a list of items for SYS$GETJPI or SYS$GETJPI(W) (even if that list contains only one item), use a record structure. Example 3-1 uses SYS$GETJPI(W) to request the process name and user name associated with the process whose process identification number is in SUBPROCESS_PID.

Example 3-1 Obtaining Different Types of Process Information

   .
   .
   .
! PID of subprocess 
INTEGER SUBPROCESS_PID 
 
! Include the request codes 
INCLUDE '($JPIDEF)' 
! Define itmlst structure 
STRUCTURE /ITMLST/ 
 UNION 
  MAP 
   INTEGER*2 BUFLEN 
   INTEGER*2 CODE 
   INTEGER*4 BUFADR 
   INTEGER*4 RETLENADR 
  END MAP 
  MAP 
   INTEGER*4 END_LIST 
  END MAP 
 END UNION 
END STRUCTURE 
! Declare GETJPI itmlst 
RECORD /ITMLST/ JPI_LIST(3) 
! Declare buffers for information 
CHARACTER*15    PROCESS_NAME 
CHARACTER*12    USER_NAME 
INTEGER*4       PNAME_LEN, 
2               UNAME_LEN 
! Declare I/O status structure 
STRUCTURE /IOSB/ 
 INTEGER*2 STATUS, 
2          COUNT 
 INTEGER*4 %FILL 
END STRUCTURE 
! Declare I/O status variable 
RECORD /IOSB/ JPISTAT 
! Declare status and routine 
INTEGER*4       STATUS, 
2               SYS$GETJPIW 
                   . 
                   . ! Define SUBPROCESS_PID 
                   . 
! Set up itmlst 
JPI_LIST(1).BUFLEN    = 15 
JPI_LIST(1).CODE      = JPI$_PRCNAM 
JPI_LIST(1).BUFADR    = %LOC(PROCESS_NAME) 
JPI_LIST(1).RETLENADR = %LOC(PNAME_LEN) 
JPI_LIST(2).BUFLEN    = 12 
JPI_LIST(2).CODE      = JPI$_USERNAME 
JPI_LIST(2).BUFADR    = %LOC(USER_NAME) 
JPI_LIST(2).RETLENADR = %LOC(UNAME_LEN) 
JPI_LIST(3).END_LIST  = 0 
! Request information and wait for it 
STATUS = SYS$GETJPIW (, 
2                     SUBPROCESS_PID, 
2                     , 
2                     JPI_LIST, 
2                     JPISTAT, 
2                     ,) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
! Check final return status 
IF (.NOT. JPISTAT.STATUS) THEN 
  CALL LIB$SIGNAL (%VAL(JPISTAT.STATUS)) 
END IF 
   .
   .
   .

3.2.3 Using SYS$GETJPI and LIB$GETJPI

SYS$GETJPI uses the PID or the process name to obtain information about one process and the -1 wildcard as the pidadr to obtain information about all processes on the local system. If a PID or process name is not specified, SYS$GETJPI returns information about the calling process. SYS$GETJPI cannot perform a selective search---it can search for only one process at a time in the cluster or for all processes on the local system. If you want to perform a selective search for information or get information about processes across the cluster, use SYS$GETJPI with SYS$PROCESS_SCAN.

3.2.3.1 Requesting Information About a Single Process

Example 3-2 is a Fortran program that displays the process name and the PID of the calling program. If you want to get the same information about each process on the system, specify the initial process identification argument as -1 when you invoke LIB$GETJPI or SYS$GETJPI(W). Call the GETJPI routine (whichever you choose) repeatedly until it returns a status of SS$_NOMOREPROC, indicating that all processes on the system have been examined.

Example 3-2 Using SYS$GETJPI to Obtain Calling Process Information

! No process name or PID is specified; $GETJPI returns data on the 
! calling process. 
 
        PROGRAM CALLING_PROCESS 
 
        IMPLICIT NONE                   ! Implicit none 
 
        INCLUDE '($jpidef)   /nolist'   ! Definitions for $GETJPI 
 
        INCLUDE '($ssdef)    /nolist'    ! System status codes 
 
        STRUCTURE /JPIITMLST/           ! Structure declaration for 
         UNION                          !  $GETJPI item lists 
          MAP 
           INTEGER*2 BUFLEN, 
        2            CODE 
           INTEGER*4 BUFADR, 
        2            RETLENADR 
          END MAP 
          MAP                           ! A longword of 0 terminates 
           INTEGER*4 END_LIST           !  an item list 
          END MAP 
         END UNION 
        END STRUCTURE 
        RECORD /JPIITMLST/              ! Declare the item list for 
        2         JPILIST(3)            !  $GETJPI 
 
        INTEGER*4 SYS$GETJPIW           ! System service entry points 
 
        INTEGER*4 STATUS,               ! Status variable 
        2         PID                   ! PID from $GETJPI 
 
        INTEGER*2 IOSB(4)               ! I/O Status Block for $GETJPI 
 
        CHARACTER*16 
        2         PRCNAM                ! Process name from $GETJPI 
        INTEGER*2 PRCNAM_LEN            ! Process name length 
        ! Initialize $GETJPI item list 
 
        JPILIST(1).BUFLEN    = 4 
        JPILIST(1).CODE      = JPI$_PID 
        JPILIST(1).BUFADR    = %LOC(PID) 
        JPILIST(1).RETLENADR = 0 
        JPILIST(2).BUFLEN    = LEN(PRCNAM) 
        JPILIST(2).CODE      = JPI$_PRCNAM 
        JPILIST(2).BUFADR    = %LOC(PRCNAM) 
        JPILIST(2).RETLENADR = %LOC(PRCNAM_LEN) 
        JPILIST(3).END_LIST  = 0 
        ! Call $GETJPI to get data for this process 
 
        STATUS = SYS$GETJPIW ( 
        2                    ,           ! No event flag 
        2                    ,           ! No PID 
        2                    ,           ! No process name 
        2                    JPILIST,    ! Item list 
        2                    IOSB,       ! Always use IOSB with $GETJPI! 
        2                    ,           ! No AST 
        2                    )           ! No AST arg 
        ! Check the status in both STATUS and the IOSB, if 
        ! STATUS is OK then copy IOSB(1) to STATUS 
 
        IF (STATUS) STATUS = IOSB(1) 
 
        ! If $GETJPI worked, display the process, if done then 
        ! prepare to exit, otherwise signal an error 
 
        IF (STATUS) THEN 
                TYPE 1010, PID, PRCNAM(1:PRCNAM_LEN) 
1010                FORMAT (' ',Z8.8,'  ',A) 
        ELSE 
                CALL LIB$SIGNAL(%VAL(STATUS)) 
        END IF 
 
        END 

Example 3-3 creates the file PROCNAME.RPT that lists, using LIB$GETJPI, the process name of each process on the system. If the process running this program does not have the privilege necessary to access a particular process, the program writes the words NO PRIVILEGE in place of the process name. If a process is suspended, LIB$GETJPI cannot access it and the program writes the word SUSPENDED in place of the process name. Note that, in either of these cases, the program changes the error value in STATUS to a success value so that the loop calling LIB$GETJPI continues to execute.

Example 3-3 Obtaining the Process Name

   .
   .
   .
! Status variable and error codes 
INTEGER STATUS, 
2       STATUS_OK, 
2       LIB$GET_LUN, 
2       LIB$GETJPI 
INCLUDE '($SSDEF)' 
PARAMETER (STATUS_OK = 1) 
 
! Logical unit number and file name 
INTEGER*4 LUN 
CHARACTER*(*) FILE_NAME 
PARAMETER (FILE_NAME = 'PROCNAME.RPT') 
! Define item codes for LIB$GETJPI 
INCLUDE '($JPIDEF)' 
 
! Process name 
CHARACTER*15 NAME 
INTEGER LEN 
! Process identification 
INTEGER PID /-1/ 
   .
   .
   .
! Get logical unit number and open the file 
STATUS = LIB$GET_LUN (LUN) 
OPEN (UNIT = LUN, 
2     FILE = 'PROCNAME.RPT', 
2     STATUS = 'NEW') 
! Get information and write it to file 
DO WHILE (STATUS) 
  STATUS = LIB$GETJPI(JPI$_PRCNAM, 
2                     PID, 
2                     ,, 
2                     NAME, 
2                     LEN) 
  ! Extra space in WRITE commands is for 
  ! FORTRAN carriage control 
  IF (STATUS) THEN 
    WRITE (UNIT = LUN, 
2          FMT = '(2A)') ' ', NAME(1:LEN) 
    STATUS = STATUS_OK 
  ELSE IF (STATUS .EQ. SS$_NOPRIV) THEN 
    WRITE (UNIT = LUN, 
2          FMT = '(2A)') ' ', 'NO PRIVILEGE' 
    STATUS = STATUS_OK 
  ELSE IF (STATUS .EQ. SS$_SUSPENDED) THEN 
    WRITE (UNIT = LUN, 
2          FMT = '(2A)') ' ', 'SUSPENDED' 
    STATUS = STATUS_OK 
  END IF 
 
END DO 
! Close file 
IF (STATUS .EQ. SS$_NOMOREPROC) 
2  CLOSE (UNIT = LUN) 
   .
   .
   .

Example 3-4 demonstrates how to use the process name to obtain information about a process.

Example 3-4 Using SYS$GETJPI and the Process Name to Obtain Information About a Process

! To find information for a particular process by name, 
! substitute this code, which includes a process name, 
! to call $GETJPI in Example 3-2
 
! Call $GETJPI to get data for a named process 
 
STATUS = SYS$GETJPIW ( 
2                    ,           ! No event flag 
2                    ,           ! No PID 
2                    'SMITH_1',  ! Process name 
2                    JPILIST,    ! Item list 
2                    IOSB,       ! Always use IOSB with $GETJPI! 
2                    ,           ! No AST 
2                    )           ! No AST arg 
 
 

3.2.3.2 Requesting Information About All Processes on the Local System

You can use SYS$GETJPI to perform a wildcard search on all processes on the local system. When the initial pidadr argument is specified as -1 , SYS$GETJPI returns requested information for each process that the program has privilege to access. The requested information is returned for one process per call to SYS$GETJPI.

To perform a wildcard search, call SYS$GETJPI in a loop, testing the return status.

When performing wildcard searches, SYS$GETJPI returns an error status for processes that are inaccessible. When a program that uses a -1 wildcard checks the status value returned by SYS$GETJPI, it should test for the following status codes:
Status Explanation
SS$_NOMOREPROC All processes have been returned.
SS$_NOPRIV The caller lacks sufficient privilege to examine a process.
SS$_SUSPENDED The target process is being deleted or is suspended and cannot return the information.

Example 3-5 is a C program that demonstrates how to use the SYS$GETJPI -1 wildcard to search for all processes on the local system.

Example 3-5 Using SYS$GETJPI to Request Information About All Processes on the Local System

#include <stdio.h> 
#include <jpidef.h> 
#include <stdlib.h> 
#include <ssdef.h> 
 
/* Item descriptor */ 
 
struct { 
        unsigned short buflen, item_code; 
        void *bufaddr; 
        void *retlenaddr; 
        unsigned int terminator; 
}itm_lst; 
 
/* I/O Status Block */ 
 
struct { 
        unsigned short iostat; 
        unsigned short iolen; 
        unsigned int device_info; 
}iosb; 
 
main() { 
 
        unsigned short len; 
        unsigned int efn=1,pidadr = -1,status, usersize; 
        char username[12]; 
        
/* Initialize the item list */ 
 
        itm_lst.buflen = 12; 
        itm_lst.item_code = JPI$_USERNAME; 
        itm_lst.bufaddr = username; 
        itm_lst.retlenaddr = &usersize; 
        itm_lst.terminator = 0; 
 
        do{ 
 
        status = SYS$GETJPIW(0,                 /* no event flag */ 
                             &pidadr,           /* process id */ 
                             0,                 /* process name */ 
                             &itm_lst,          /* item list */ 
                             &iosb,             /* I/O status block */ 
                             0,                 /* astadr (AST routine) */ 
                             0);                /* astprm (AST parameter) */ 
                 switch(status) 
                 { 
case SS$_NOPRIV: 
                printf("\nError: No privileges for attempted operation"); 
                break; 
case SS$_SUSPENDED: 
                printf("\nError: Process is suspended"); 
                break; 
case SS$_NORMAL: 
                if (iosb.iostat == SS$_NORMAL) 
                     printf("\nUsername: %s",username); 
                else 
                     printf("\nIOSB condition value  %d returned",iosb.iostat); 
                        } 
 
        }while(status != SS$_NOMOREPROC); 
 
} 

3.2.4 Using SYS$GETJPI with SYS$PROCESS_SCAN

Using the SYS$PROCESS_SCAN system service greatly enhances the power of SYS$GETJPI. With this combination, you can search for selected groups of processes or kernel threads on the local system as well as for processes or kernel threads on remote nodes or across the cluster. When you use SYS$GETJPI alone, you specify the pidadr or the prcnam argument to locate information about one process. When you use SYS$GETJPI with SYS$PROCESS_SCAN, the pidctx argument generated by SYS$PROCESS_SCAN is used as the pidadr argument to SYS$GETJPI. This context allows SYS$GETJPI to use the selection criteria that are set up in the call to SYS$PROCESS_SCAN.

When using SYS$GETJPI with a PRCNAM specified, SYS$GETJPI returns data for only the initial thread. This parallels the behavior of the DCL commands SHOW SYSTEM, SHOW PROCESS, and MONITOR PROCESS. If a valid PIDADR is specified, then the data returned describes only that specific kernel thread. If a PIDADR of zero is specified, then the data returned describes the calling kernel thread.

SYS$GETJPI has the flag, JPI$_THREAD, as part of the JPI$_GETJPI_CONTROL_FLAGS item code. The JPI$_THREAD flag designates that the service call is requesting data for all of the kernel threads in a multithreaded process. If the call is made with JPI$_THREAD set, then SYS$GETJPI begins with the initial thread, and SYS$GETJPI returns SS$_NORMAL. Subsequent calls to SYS$GETJPI with JPI$_THREAD specified returns data for the next thread until there are no more threads, at which time the service returns SS$_NOMORETHREAD.

If you specify a wildcard PIDADR -1 along with JPI$_THREAD, you cause SYS$GETJPI to return information for all threads for all processes on the system on subsequent calls. SYS$GETJPI returns the status SS$_NORMAL until there are no more processes, at which time it returns SS$_NOMOREPROC. If you specify a wildcard search, you must request either the JPI$_PROC_INDEX or the JPI$_INITIAL_THREAD_PID item code to distinguish the transition from the last thread of a multithreaded process to the next process. The PROC_INDEX and the INITIAL_THREAD_PID are different for each process on the system.

Table 3-3 shows four item codes of SYS$GETJPI that provide kernel threads information.

Table 3-3 SYS$GETJPI Kernel Threads Item Codes
Item Code Meaning
JPI$_INITIAL_THREAD_PID Returns the PID of the initial thread for the target process.
JPI$_KT_COUNT Returns the current count of kernel threads for the target process.
JPI$_MULTITHREAD Returns the maximum kernel thread count allowed for the target process.
JPI$_THREAD_INDEX Returns the kernel thread index for the target thread or process.

This wildcard search is initiated by invoking SYS$GETJPI with a -1 specified for the PID, and is available only on the local node. With kernel threads, a search for all threads in a single process is available, both on the local node and on another node on the cluster.

In a dual architecture or mixed-version cluster, one or more nodes in the cluster may not support kernel threads. To indicate this condition, a threads capability bit (CSB$M_CAP_THREADS) exists in the CSB$L_CAPABILITY cell in the cluster status block. If this bit is set for a node, it indicates that the node supports kernel threads. This information is passed around as part of the normal cluster management activity when a node is added to a cluster. If a SYS$GETJPI request that requires threads support needs to be passed to another node in the cluster, a check is made on whether the node supports kernel threads before the request is sent to that node. If the node supports kernel threads, the request is sent. If the node does not support kernel threads, the status SS$_INCOMPAT is returned to the caller, and the request is not sent to the other node.

You can use SYS$PROCESS_SCAN only with SYS$GETJPI; you cannot use it alone. The process context generated by SYS$PROCESS_SCAN is used like the -1 wildcard except that it is initialized by calling the SYS$PROCESS_SCAN service instead of by a simple assignment statement. However, the SYS$PROCESS_SCAN context is more powerful and more flexible than the -1 wildcard. SYS$PROCESS_SCAN uses an item list to specify selection criteria to be used in a search for processes and produces a context longword that describes a selective search for SYS$GETJPI.

Using SYS$GETJPI with SYS$PROCESS_SCAN to perform a selective search is a more efficient way to locate information because only information about the processes you have selected is returned. For example, you can specify a search for processes owned by one user name, and SYS$GETJPI returns only the processes that match the specified user name. You can specify a search for all batch processes, and SYS$GETJPI returns only information about processes running as batch jobs. You can specify a search for all batch processes owned by one user name and SYS$GETJPI returns only information about processes owned by that user name that are running as batch jobs.

By default, SYS$PROCESS_SCAN sets up a context for only the initial thread of a multithreaded process. However, if the value PSCAN$_THREAD is specified for the item code PSCAN$_PSCAN_CONTOL_FLAGS, then threads are included in the scan. The PSCAN$_THREAD flag takes precedence over the JPI$_THREAD flag in the SYS$GETJPI call. With PSCAN$_THREAD specified, threads are included in the entire scan. With PSCAN$_THREAD not specified, threads are included in the scan for a specific SYS$GETJPI call only if JPI$_THREAD is specified.

Table 3-4 shows two item codes of SYS$PROCESS_SCAN that provide kernel thread information.

Table 3-4 SYS$PROCESS_SCAN Kernel Threads Item Codes
Item Code Meaning
PSCAN$_KT_COUNT Uses the current count of kernel threads for the process as a selection criteria. The valid item-specific flags for this item code are EQL, GEQ, GTR, LEQ, LSS, NEQ, and OR.
PSCAN$_MULTITHREAD Uses the maximum count of kernel threads for the process as a selection criteria. The valid item-specific flags for this item code are EQL, GEQ, GTR, LEQ, LSS, NEQ, and OR.

3.2.4.1 Using SYS$PROCESS_SCAN Item List and Item-Specific Flags

SYS$PROCESS_SCAN uses an item list to specify the selection criteria for the SYS$GETJPI search.

Each entry in the SYS$PROCESS_SCAN item list contains the following:

Item-specific flags enable you to control selection information. For example, you can use flags to select only those processes that have attribute values that correspond to the value in the item list, as shown in Table 3-5.

Table 3-5 Item-Specific Flags
Item-Specific Flag Description
PSCAN$M_OR Match this value or the next value.
PSCAN$M_EQL Match value exactly (the default).
PSCAN$M_NEQ Match if value is not equal.
PSCAN$M_GEQ Match if value is greater than or equal to.
PSCAN$M_GTR Match if value is greater than.
PSCAN$M_LEQ Match if value is less than or equal to.
PSCAN$M_LSS Match if value is less than.
PSCAN$M_CASE_BLIND Match without regard to case of letters.
PSCAN$M_PREFIX_MATCH Match on the leading substring.
PSCAN$M_WILDCARD Match string is a wildcard pattern.

The PSCAN$M_OR flag is used to connect entries in an item list. For example, in a program that searches for processes owned by several specified users, each user name must be specified in a separate item list entry. The item list entries are connected with the PSCAN$M_OR flag as shown in the following Fortran example. This example connects all the processes on the local node that belong to SMITH, JONES, or JOHNSON.


PSCANLIST(1).BUFLEN   = LEN('SMITH') 
PSCANLIST(1).CODE     = PSCAN$_USERNAME 
PSCANLIST(1).BUFADR   = %LOC('SMITH') 
PSCANLIST(1).ITMFLAGS = PSCAN$M_OR 
PSCANLIST(2).BUFLEN   = LEN('JONES') 
PSCANLIST(2).CODE     = PSCAN$_USERNAME 
PSCANLIST(2).BUFADR   = %LOC('JONES') 
PSCANLIST(2).ITMFLAGS = PSCAN$M_OR 
PSCANLIST(3).BUFLEN   = LEN('JOHNSON') 
PSCANLIST(3).CODE     = PSCAN$_USERNAME 
PSCANLIST(3).BUFADR   = %LOC('JOHNSON') 
PSCANLIST(3).ITMFLAGS = 0 
PSCANLIST(4).END_LIST = 0 

Use the PSCAN$M_WILDCARD flag to specify that a character string is to be treated as a wildcard. For example, to find all process names that begin with the letter A and end with the string ER, use the string A*ER with the PSCAN$M_WILDCARD flag. If the PSCAN$M_WILDCARD flag is not specified, the search looks for the 4-character process name A*ER.

The PSCAN$M_PREFIX_MATCH defines a wildcard search to match the initial characters of a string. For example, to find all process names that start with the letters AB, use the string AB with the PSCAN$M_PREFIX_MATCH flag. If you do not specify the PSCAN$M_PREFIX_MATCH flag, the search looks for a process with the 2-character process name AB.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_006.HTML