Everhart, Glenn
From:	wayne@tachyon.xxx362482killspam-0dd3
Sent:	Wednesday, July 22, 1998 7:51 PM
To:	Info-VAX@Mvb.Saic.Com
Subject:	Re: help with disk driver acp functions
In article <35B5D3F7.5018C187@epamail.epa.gov>, Charles Hamm <hamm.charles@epamail.epa.gov> writes:
> This is a multi-part message in MIME format.
> 
> --------------1AEBB8B457DCACDD758F2052
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
> 
> i need some help with the disk driver acp to write to a file.
> 
> this is for a real-time application. the reason i am using qios directly
> (from c) is mainly to get access to asynch io's, so i can do something
> else while the data is writing. obviously the lower overhead of the acp
> interface is also attractive.
> 
> actually i have gotten the qio part working correctly. the only problem
> i have is that i can't seem to get the file size in the header to be
> updated. no matter how i seem to call the modify function, the actual
> file size stays at 0 after closing. the allocated size is correct. i can
> do a "set file/end" to make the file readable and prove to myself that
> the data was actually written.
> 
> does anybody know what i'm doing wrong? the example program is attached.
> 
> -- 
> Charles Hamm           US EPA (HERL/NTD)                RTP, NC, USA
> (v)919-541-3017        hamm.charles@epamail.epa.gov     (f)919-541-4849
> 
> --------------1AEBB8B457DCACDD758F2052
> Content-Type: text/plain; charset=us-ascii; name="wtqio.c"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline; filename="wtqio.c"
> 
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> 
> #include <starlet.h>
> #include <ssdef.h>
> #include <iodef.h>
> #include <fibdef.h>
> #include <psldef.h>
> #include <rms.h>
> 
> #include <site_lib/site.h>
> 
> #pragma message disable dollarid
> 
> typedef struct {
>   longword len;
>   struct fibdef *fib;
>   } FIBD;
> 
> typedef struct {
>   unsigned status: 16;
>   unsigned count: 16;
>   unsigned fill: 32;
>   } IOSB;
> 
> longword qioopen(longword*, FIBD*, char*, longword, longword);
> longword qiowrite(longword, FIBD*, short*, longword);
> longword qioclose(longword, FIBD*);
> void out(char*, longword);
> void done(longword);
> 
> boolean Donev = FALSE;
> IOSB Iosb[2];
> 
> int main(int argc, char **argv) {
> 
>   int i, j, k;
>   char *name = "wt.dat";
>   short a[256];
>   longword chan;
>   FIBD fibd;
>   struct fibdef fib;
> 
> /* init the fib and descriptor */
>   memclr(&fib, sizeof(struct fibdef));
>   fibd.len = sizeof(struct fibdef);
>   fibd.fib = &fib;
> 
> /* init the data block */
>   for (i=0; i<256; i++) a[i] = i;
> 
> /* do the io */
>   (void)qioopen(&chan, &fibd, name, 1, sizeof(a));
>   (void)qiowrite(chan, &fibd, a, sizeof(a));
>   for (i=0; i<1000000; i++) j=i+1;
>   (void)qioclose(chan, &fibd);
> 
>   } /* end main */
> 

> 
> longword qioopen(longword *chan, FIBD *fibd, char *name, longword recs,
>   longword recsiz) {
> 
>   static char spec[256];
>   longword status, reslen;
>   descrip(namedesc, "SYS$DISK");
>   struct FAB fab;
>   struct NAM nam;
> 
> /* init the fab and nam for rms */
>   (void)strcpy(spec, "sys$disk:");
>   (void)strcat(spec, name);
>   fab = cc$rms_fab;
>   fab.fab$l_fna = spec;
>   fab.fab$b_fns = (byte)strlen(spec);
>   fab.fab$b_rfm = (byte)FAB$C_FIX;
>   fab.fab$w_mrs = (word)recsiz;
>   nam = cc$rms_nam;
>   fab.fab$l_nam = &nam;
>   
> /* create and close the file, retaining the fid in the nam block */
>   status = sys$create(&fab);
>   if ((status != RMS$_NORMAL) && (status != RMS$_CREATED)) out("sys$cre", status);
>   status = sys$close(&fab);
>   if (status != RMS$_NORMAL) out("sys$clo", status);
> 
> /* open a channel to the default disk */
>   status = sys$assign(&namedesc, chan, 0, NULL, 0);
>   if (status != SS$_NORMAL) out("sys$ass", status);
> 
> /* copy the fid from the nam block to the fib and init some fib bits */
>   fibd->fib->fib$w_fid_num = nam.nam$w_fid_num;
>   fibd->fib->fib$w_fid_seq = nam.nam$w_fid_seq;
>   fibd->fib->fib$w_fid_rvn = nam.nam$w_fid_rvn;
>   fibd->fib->fib$v_seqonly = TRUE;
>   fibd->fib->fib$v_write = TRUE;
>   fibd->fib->fib$v_nowrite = TRUE;
>   fibd->fib->fib$v_noread = TRUE;
>   fibd->fib->fib$v_writethru = TRUE;
>   fibd->fib->fib$v_writethru = TRUE;
>   fibd->fib->fib$l_exsz = recs * (recsiz / 512);
> 
> /* open the file using the fib */
>   status = sys$qiow(0, *chan, (IO$_ACCESS | IO$M_ACCESS), &Iosb[0], NULL, 0,
>     fibd, NULL, NULL, NULL, NULL, 0);
>   if (status != SS$_NORMAL) out("qio acc", status);
>   return status;
> 
>   } /* end qioopen */
> 

> 
> longword qiowrite(longword chan, FIBD *fibd, short* rec, longword recsiz) {
> 
>   longword status;
>   static block = 0;
>   block++;
>   IOSB iosb;
> 
> /* extend the file */
>   fibd->fib->fib$v_extend = TRUE;
>   status = sys$qiow(0, chan, IO$_MODIFY,
>     &iosb, NULL, 0, fibd, 0, 0, 0, 0, 0);
>   (void)printf("ext bl%d st%d iost%d ct%d\n", block, status,
>     iosb.status, iosb.count);
>   status = sys$qiow(0, chan, IO$_MODIFY,
>     &iosb, NULL, 0, fibd, 0, 0, 0, 0, 0);
>   (void)printf("ext bl%d st%d iost%d ct%d\n", block, status,
>     iosb.status, iosb.count);
>   fibd->fib->fib$v_extend = FALSE;
> 
> /* write it */
>   status = sys$qio(block, chan, IO$_WRITEVBLK, &Iosb[block - 1], done, block,
>     rec, recsiz, block, 0, 0, 0);
>   (void)printf("wri bl%d st%d do%d\n", block, status, Donev);
>   if (status != SS$_NORMAL) out("wri", status);
> 
> /* update the filesize */
>   status = sys$qiow(0, chan, IO$_MODIFY,
>     &iosb, NULL, 0, fibd, 0, 0, 0, 0, 0);
>   (void)printf("filsz st%d iost%d ct%d\n", status,
>     iosb.status, iosb.count);
> 
>   return status;
> 
>   } /* end qiowrite */
> 

> void done(longword block) {
> 
>   if (succ(Iosb[0].status)) Donev = TRUE;
>   else (void)printf("ast bl%d io st %d count %d\n", block,
>     Iosb[block - 1].status, Iosb[block - 1].count);
>   (void)printf("ast bl%d do%d ct%d\n", block, Donev, Iosb[block - 1].count);
> 
>   } /* end done */
> 

> 
> longword qioclose(longword chan, FIBD *fibd) {
> 
>   longword status;
> 
> /* close the file */
>   status = sys$qiow(0, chan, IO$_DEACCESS, &Iosb[0], NULL, 0, fibd, 0, 0, 0, 0,
>     0);
>   (void)printf("deac st%d io err %d count %d\n", status, Iosb[0].status,
>     Iosb[0].count);
>   if (status != SS$_NORMAL) out("deac", status);
> 
> /* close the channel */
>   status = sys$dassgn(chan);
>   if (status != SS$_NORMAL) out("sys$ass", status);
> 
>   return status;
> 
>   } /* end qioclose */
> 

> 
> void out(char *msg, longword status) {
> 
>   (void)puts(msg);
>   exit(status);
> 
>   } /* end out */
> 
> --------------1AEBB8B457DCACDD758F2052--

Rather than fool with the acp (actually xqp nowadays) interface, why not use
rms?  If asynchronous i/o is all you need beyond the language-supplied
routines, rms has this capability.  And certainly it will take over a lot of
the housekeeping you are now doing manually.

I don't think the overhead is all that significant, especially since we are
talking about disk i/o.  

Wayne

-- 
===============================================================================
Wayne Sewell, Tachyon Software Consulting  (281)812-0738  wayne@tachyon.xxx
http://www.tachyon.xxx/www/tachyon.html and wayne.html  
change .xxx to .com in addresses above, assuming you are not a spambot  :-)
===============================================================================
Otter, on dining with Bluto:"It's perfectly safe if you keep your arms and legs
			away from his mouth."