HP OpenVMS Systems

ask the wizard
Content starts here

printing process states from C?

» close window

The Question is:

 
My question is about how to use the STARLET macros from C in general and the
 $STATEDEF macro in specific.  When the manual
 (http://www.openvms.compaq.com:8000/72final/4527/4527pro_044.html) states for
 SYS$GETJPI:
...
JPI$_STATE
When you specify JPI$_STATE, $GETJPI returns the state of the process, which is
 a longword integer value. Each state has a symbolic representation. If the
 process is currently executing, its state is always SCH$K_CUR. The $STATEDEF
 macro defines the follo
wing symbols, which identify the various possible states...
 
How do you make use of this information?  I've gotten the value of JPI$_STATE.
 But I don't see how the $STATEDEF macro used.  I want to get the same
 information displayed by SHOW SYSTEM (CUR, LEF...).  C code example greatly
 appreciated.
 
Here's the modified code from that link above.
/*  Defining __NEW_STARLET enables the program to benefit from better type
    checking for prototypes and structures provided by OpenVMS.
*/
 
#define     __NEW_STARLET       1
 
#include    <efndef>            /*  No Event Flag Event Flag  */
#include    <iledef>            /*  Item List Entry Definitions  */
#include    <iosbdef>           /*  I/O Status Block Structure Definition  */
#include    <jpidef>            /*  $GETJPI Item Code Definitions  */
#include    <ssdef>             /*  SS Message Codes  */
#include    <starlet>           /*  Function Prototypes for System Services */
#include    <stdio>             /*  C Standard I/O Functions  */
#include    <string>            /*  MEMSET Prototype  */
#include    <stsdef>            /*  Status Block Definitions  */
 
#define     NUM_ILE               6
#define     NAME_LENGTH          16
#define     IMAGE_LENGTH        255
 
 
/*  Macro to initialize a 32-bit item_list_3.                 */
 
#define init_ile32(ile, length, code, bufaddr, retlen_addr) \
{   (ile)->ile3$w_length = (length);           \
    (ile)->ile3$w_code = (code);         \
    (ile)->ile3$ps_bufaddr = (bufaddr); \
    (ile)->ile3$ps_retlen_addr = (retlen_addr); }
main ()
 
char
    imagename [IMAGE_LENGTH],
    procname [NAME_LENGTH],
    username [NAME_LENGTH];
 
int
    count = 0,
    retpid,
    status;
 
unsigned int
    pid = -1;
 
unsigned short
    imagename_length,
    procname_length,
    username_length;
 
long
    state;
ILE3
    jpi_ile [NUM_ILE];
 
IOSB
    iosb;
 
 
/*  Zeroing the item list has the effect of creating the terminating entry. */
 
    memset (jpi_ile, 0, ILE3$K_LENGTH*NUM_ILE);
 
 
/*  Initialize the item list entries to fetch the user name, the process
    name, the image name and the PID.                                     */
 
    init_ile32 (
        &jpi_ile [0],
        NAME_LENGTH,
        JPI$_USERNAME,
        username,
        &username_length);
 
    init_ile32 (
        &jpi_ile [1],
        NAME_LENGTH,
        JPI$_PRCNAM,
        procname,
        &procname_length);
 
    init_ile32 (
        &jpi_ile [2],
        IMAGE_LENGTH,
        JPI$_IMAGNAME,
        imagename,
        &imagename_length);
 
    init_ile32 (
        &jpi_ile [3],
        sizeof (int),
        JPI$_PID,
        &retpid,
        NULL);
 
    init_ile32 (
        &jpi_ile [4],
        sizeof (long),
        JPI$_STATE,
        &state,
        NULL);
 
 
/*  Initial wildcard $GETJPI.
*/
 
    status = sys$getjpiw (
        0,
        &pid,
        NULL,
        &jpi_ile,
        &iosb,
        NULL,
        0);
/*  Loop for all processes on this node.                        */
 
    while (status != SS$_NOMOREPROC)
    {
        if (status & STS$M_SUCCESS)
        {
 
 
/*  Zero terminate process and image name strings.               */
 
            imagename [imagename_length] = '\0';
            username [username_length] = '\0';
            procname [procname_length] = '\0';
 
 
/*  Print header if this is the first.                           */
 
            if (count == 0)
                printf ("   PID   User Name       State  Process Name Image\n");
 
 
 
/*  Count process and print process data.                          */
 
            count++;
            printf ("%08X %-15s %-15s %2ld %s\n",
                retpid,
                username,
                procname,
                state, /* really want CUR,LEF... */
                imagename);
        }
 
 
/*  Skip process if suspended or no privilege to see process.  Return any
    other error.                                                         */
 
        else if ((status != SS$_NOPRIV) && (status != SS$_SUSPENDED))
            return (status);
 
 
/*  Find next process.                                                    */
 
        status = sys$getjpiw (
            0,
            &pid,
            NULL,
            &jpi_ile,
            &iosb,
            NULL,
            0);
    }
    return (SS$_NORMAL);
 
 
 
Thanks
 


The Answer is :

The values in $STATEDEF give you a symbolic representation of the numeric
state value. They do not provide strings or any other ASCII representation of
the process state.
 
The symbols can be used in a program like so:
 
    status = sys$getjpiw (
        0,
        &pid,
        NULL,
        &jpi_ile,
        &iosb,
        NULL,
        0);
 
    if (state == SCH$C_CUR)
    {
       ...do something...
    }
 
If you want to print something out, you have to do something like this in
your program:
 
char *state_names[SCH$C_CUR] = {
     "unused\0",
     "COLPG\0",
     "MWAIT\0",
     "CEF\0",
     "PFW\0",
    ...etc...
     }
 
And then, in your printf statement:
 
            printf ("%08X %-15s %-15s %2ld %s\n",
                retpid,
                username,
                procname,
                state_names[state],   /* *****
                imagename);
 
This is how it's done inside the code that processes the SHOW SYSTEM command.
 
 
Also, just to be pendantic, $STATEDEF is in LIB, not STARLET...
 
 

answer written or last revised on ( 12-JUL-2000 )

» close window