OpenVMS Source Code Demos
QIO_DEMO
//================================================================================================
// title : qio_demo_100.c
// author : Neil Rieck
// created: 2016-04-06
// notes : I first used sys$qio in VMS-BASIC but slight changes are required with c. Inspecting
// library file "SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C]STARLET.H" reveals that
// many 32-bit parameters now need to be 64-bit. So this little hack was built to see if
// sys$qio would work in a c program compiled with "/nopointer_size" which defaults to
// 32-bits.
// BASIC C/C++
// EXTERNAL LONG FUNCTION SYS$QIO ( & int sys$qio(
// LONG BY VALUE, & unsigned int efn,
// WORD BY VALUE, & unsigned short int chan,
// WORD BY VALUE, & unsigned int func,
// BASIC$QUADWORD BY REF, & struct _iosb *iosb,
// LONG BY REF , & void (*astadr)(__unknown_params),
// LONG BY VALUE, & __int64 astprm,
// ANY BY REF , & void *p1,
// LONG BY VALUE, & __int64 p2,
// LONG BY VALUE, & __int64 p3,
// LONG BY VALUE, & __int64 p4,
// LONG BY VALUE, & __int64 p5,
// LONG BY VALUE ) __int64 p6);
//
// ver who when what
// --- --- ------ --------------------------------------------------------------------------------
// 100 NSR 160406 original effort
//================================================================================================
#define PROGRAM_VER "qio_demo_100.c" //
#define __NEW_STARLET 1 // recommended for Alpha and Itanium
#include <stdio.h> //
#include <stdlib.h> //
#include <string.h> //
#include <ctype.h> //
#include <errno.h> //
#include <time.h> //
#include <efndef.h> //
#include <unistd.h> // read()
//
// OpenVMS specific stuff (some of this stuff is for RMS)
//
#include <starlet.h> // sys$qiow, sys$open, etc.
#include <iodef.h> // io$m_readvblk, etc.
#include <iosbdef.h> // iosb
#include <rms.h> // fab,rab,rms
#include <descrip.h> // for vms string descriptors in C
#include <str$routines.h> // for vms string descriptors in VMS
#include <ssdef.h> //
#include <lib$routines.h> //
#include <libwaitdef.h> //
//
// VMSIFY
// a macro for use in the VMS world (VMS strings employ this structure)
// notes: this macro can be used to pass VMS strings down to lower modules
// the $DESCRIPTOR macro does something similar employing sizeof-1
// this macro combines two operations
//
#define VMSIFY(a,b) { \
a.dsc$b_dtype = DSC$K_DTYPE_T; \
a.dsc$b_class = DSC$K_CLASS_S; \
a.dsc$w_length = strlen(b); \
a.dsc$a_pointer = (char *) malloc(strlen(b)); \
strncpy(a.dsc$a_pointer,b,a.dsc$w_length); \
}
//------------------------------------------------------------------------------
// delay()
// a quick hack to introduce a programmed delay
//------------------------------------------------------------------------------
#if __G_FLOAT != 0
# define FLOAT_TYPE LIB$K_VAX_F
#elif __D_FLOAT != 0
# define FLOAT_TYPE LIB$K_VAX_D
#elif __IEEE_FLOAT != 0
# define FLOAT_TYPE LIB$K_IEEE_S
#else
# error "Try specifying a floating point qualifier on the compile"
#endif
//
static void delay(float delay_time){
long rc;
unsigned long float_type = FLOAT_TYPE;
rc = lib$wait(&delay_time,0,&float_type);
}
//==============================================================================
// main()
//==============================================================================
int main() {
int count;
int rc;
struct _iosb iosb_qio;
char buf1[2000];
char buf2[2000];
unsigned int vms_ef;
unsigned short vms_ch;
unsigned short vms_func;
time_t t;
char *p;
char *device;
struct dsc$descriptor_s vms_misc1;
unsigned long seconds;
//=====================================================
// real code starts here :-)
//=====================================================
printf("-i-hack: main\n");
//
device = getenv("SYS$INPUT");
if (device!=NULL){
printf("-i-sys$input %s\n", device);
}else{
printf("-e-can't translate sys$input\n");
exit(1);
}
//
rc = lib$get_ef( &vms_ef);
if ((rc&7)!=1){
printf("-e-lib$get_ef-rc:%ld\n",rc);
exit(1);
}else{
printf("-i-ef: %ld\n",vms_ef);
}
//
VMSIFY(vms_misc1, device); // sys$assign requires a vms string descriptor
rc = sys$assign(&vms_misc1, &vms_ch,0,0,0); // allocate a channel for reading
if ((rc&7)!=1){
printf("-e-sys$assign-rc:%ld\n",rc); //
exit(1);
}
//
// vms_func = IO$_READVBLK | IO$M_TIMED | IO$M_NOECHO;
vms_func = IO$_READVBLK | IO$M_TIMED;
seconds = 10;
printf("-i-starting qiow with timeout of %ld-seconds\n",seconds);
printf("-i-type something then hit <enter>\n\n");
// rc = sys$qiow( EFN$C_ENF , //ef
rc = sys$qiow( vms_ef , //ef
vms_ch , //chan
vms_func , //func
&iosb_qio , //iosb
0 , //ast addr
0 , //ast param
&buf1 , //buffer (p1)
sizeof(buf1) , //len (p2)
seconds , //timeout in seconds (p3)
0 , //read term (p4)
0 , //prompt addr (p5)
0); //prompt size (p6)
if ((rc&7)!=1) { //check qio submit status
printf("-i-hack sys$qiow-rc0: %dl\n", rc);
count = 0;
}else{
rc = iosb_qio.iosb$w_status; //
if ((rc&7)!=1) { //check qio completion status
printf("-i-hack sys$qiow-rc1: %ld\n", rc);
switch(rc){
case SS$_TIMEOUT:
printf("-w-timeout\n");
break;
default:
}
// printf("-i-hack count : %ld\n", iosb_qio.iosb$w_bcnt);
}else{
count = iosb_qio.iosb$w_bcnt; // xfer the byte count
}
}
printf("-i-bytes received: %ld\n", count);
if (count>0) {
strncpy(buf2,buf1,count);
buf2[count] = '\0';
printf("-i-data: %s\n", buf2);
}
exit(1);
}
//==============================================================================