16-Aug-2011

IOSB status for GETxxI calls

Did you know that the status value in the I/O status block for most of the "get information" calls is a longword? I have the sneaking suspicion that this changed some time in recent history (where "recent history" equals "some time after VMS 5.x") when the number of $GETxxI routine return values exceeded the size of a word.

What this means in practice is that you should be testing and returning the full longword rather than just the word for calls such as $GETSYI(W), $GETJPI(W), $GETQUI(W), etc.

As an example, here's a section of code that does the wrong thing and then the correct thing:


#define __NEW_STARLET 1

#include <stdio.h>
#include <stdlib.h>
#include <ssdef.h>
#include <stsdef.h>
#include <efndef.h>
#include <quidef.h>
#include <iledef.h>
#include <iosbdef.h>
#include <descrip.h>
#include <lib$routines.h>
#include <starlet.h>

#define errchk_sig(arg) if (!$VMS_STATUS_SUCCESS(arg)) (void)lib$signal(arg);


/******************************************************************************/
int main (void) {

static IOSB iosb;
static int r0_status;
static int qflags;
static unsigned int status;
static unsigned int flags = 0x000f;
static ILE3 quiitms[] = { 4, QUI$_QUEUE_FLAGS, &qflags, NULL,
                          0, 0, NULL, NULL };

static char msg[255+1];
static struct dsc$descriptor_s msg_d = { 0,
                                         DSC$K_DTYPE_T,
                                         DSC$K_CLASS_S,
                                         msg };

    /*
    ** This call will succeed requesting information, but because our item
    ** list is missing the queue name we want info on, the IOSB will contain
    ** a status indicating we didn't pass enough parameters.
    */
    r0_status = sys$getquiw (EFN$C_ENF,
                             QUI$_DISPLAY_QUEUE,
                             0,
                             quiitms,
                             &iosb,
                             0,
                             0);
    errchk_sig (r0_status);

    /*
    ** Display the word value.  Perhaps not what we were expecting.
    */
    (void)printf ("iosb.iosb$w_status = %d\n",
                  iosb.iosb$w_status);
    msg_d.dsc$w_length = sizeof (msg) - 1;
    status = iosb.iosb$w_status;
    r0_status = lib$sys_getmsg (&status,
                                &msg_d.dsc$w_length,
                                &msg_d,
                                &flags);
    errchk_sig (r0_status);
    (void)printf ("%-.*s\n",
                  msg_d.dsc$w_length,
                  msg_d.dsc$a_pointer);

    /*
    ** Display the correct longword value.
    */
    (void)printf ("iosb.iosb$l_getxxi_status = %d\n",
                  iosb.iosb$l_getxxi_status);
    msg_d.dsc$w_length = sizeof (msg) - 1;
    status = iosb.iosb$l_getxxi_status;
    r0_status = lib$sys_getmsg (&status,
                                &msg_d.dsc$w_length,
                                &msg_d,
                                &flags);
    errchk_sig (r0_status);

    (void)printf ("%-.*s\n",
                  msg_d.dsc$w_length,
                  msg_d.dsc$a_pointer);
}


Compiling, linking and running this code produces the following output:


$ cc demo.c
$ link demo
$ run demo
iosb.iosb$w_status = 33036
%SYSTEM-F-NOMSG, Message number 0000810C
iosb.iosb$l_getxxi_status = 295180
%JBC-F-MISREQPAR, missing required parameter
$


Posted at August 16, 2011 3:48 PM
Tag Set:
Comments

Interesting for error reporting but mostly programs only the check the success bit and act on that.

Posted by: Ian Miller at September 21, 2011 8:57 PM

Comments are closed