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);
}
//==============================================================================