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
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