[Info-vax] VMS enhancement suggestion: Add a "read regardless" file open option.

Craig A. Berry craigberry at nospam.mac.com
Tue Nov 10 18:16:24 EST 2020


On 11/10/20 3:48 PM, Jim wrote:
> On Tuesday, November 10, 2020 at 10:06:29 AM UTC-5, Craig A. Berry wrote:
>> On 11/10/20 7:25 AM, Simon Clubley wrote:
>>> On 2020-11-09, Dave Froble <da... at tsoft-inc.com> wrote:
>>
>>>> Seems like VAX Basic has a "read regardless" lock qualifier ...
>>>>
>>>
>>> I wasn't aware of that. Does it allow you to open a sequential file for
>>> reading while the file is also in the process of being created by another
>>> program ? You can clearly do it for batch log files but what about programs
>>> that don't specify that writing mode when creating a sequential file ?
>>>
>>>> Might that be helpful?
>>>>
>>>> And of course RMS would have the capability.
>>>>
>>>
>>> Interesting. One of the issues that was raised when I moved from RSTS/E
>>> to VMS in the early 1990s was that a VMS version of mode 4096 didn't
>>> exist and I wasn't aware it had been added in the meantime.

>> Search for "OpenVMS RMS RAB$V_RRL" and see how it works. That's
>> record-level, though, not file-level.
> 
> For file level access - search for fib$v_nolock or fib$m_nolock


Ah, yes, I either forgot or didn't know about that.  But it looks like
that's ACP-level only and doesn't fit Dave Froble's statement that I was
responding to, i.e., that whatever BASIC does, "RMS would have the
capability" because with FIB$M_NOLOCK you have to do a $QIO to open the
file.  Hein has a nice write-up here:

<https://community.hpe.com/t5/operating-system-openvms/open-file-with-no-locks-enabled-so-that-a-2nd-process-can-access/td-p/7011048#.X6sbMy9h1TY>

and I'm going to take the liberty of copy-pasting his program below
since who knows how long those HPE forum posts will still be around.

(N.B. I have never seen nor used RSTS/E and have no idea what mode 4096 
was.)

/*
** read_locked.c  Hein van den Heuvel, July 2006
**
** This program can be used to copy the allocated blocks from a locked file
** Much like BACKUP/IGNORE=INTERLOCK is use the ACP NOLOCK access to over-
** ride file interlock. This requires SYSPRV or CONTROL ACCESS to the file.
** Unlike BACKUP this program simply reads all ALLCOATED blocks as the
** EOF information is likely not to be updated by the active writer (zero).
** The program copies MOST file attributes, but not all as its intended
** use is limited to copy live log files and such.
**
** You may need to use SET FILE/ATTR=(EBK:x,FFB:y) on the output as needed.
**
** If the code format looks a little odd and dated... it is!
** This program is loosly basde on some old example which where floating
** around at Digital Equipment such as SET_EXTENT.
** Suspected authors: Barry Dysert, Guenther Froehlin, me?...
**
** Enjoy!
** Hein, HvdH Perfromance Consulting
**
*/

#define MAXBLOCKS 120
#define MAXBYTES MAXBLOCKS*512

#include atrdef
/*
**  libr/extr=fatdef/out=fatdef.h sys$library:sys$lib_c.tlb
*/
#include "fatdef.h"
#include fibdef
#include iodef
#include rms
#include stdio
#include stdlib
#include string

int sys$create(), sys$connect(), sys$write(), sys$close();
int sys$create(), sys$parse(), sys$search();
int sys$assign(), SYS$QIOW(), lib$stop();

main(argc,argv)
int argc;
char *argv[];
     {
     static char buf[MAXBYTES];
     static char *usage = "Usage: $ read_locked name output_name\n";
     static char esa[256], rsa[256];
     static int status, channel, bytes, vbn=1;
     static int file_hbk, file_nbytes, spec_nbytes;
     static struct FAB fab, out;
     static struct RAB rab;
     static struct NAM nam;
     static struct
         {
         short status;
         char not_used[6];
         } iosb;
     static struct
         {
         short count;
         short not_used;
         void *address;
         } fibdes;
     static struct fibdef fib;
     static struct atrdef atr[2];
FAT attributes;
     struct { int len; char *addr; } devnam_desc;

/******************************************************************************/

/*  Verify that we've been properly invoked */

     if (argc != 3) printf("%s",usage), exit(1);

/*  Use RMS to parse the file so that we get a FID of the QIO */

     fab = cc$rms_fab;
     fab.fab$l_fna = argv[1];
     fab.fab$b_fns = strlen (argv[1]);
     fab.fab$l_nam = &nam;

     nam = cc$rms_nam;
     nam.nam$l_esa = esa;
     nam.nam$b_ess = sizeof (esa) - 1;
     nam.nam$l_rsa = rsa;
     nam.nam$b_rss = sizeof (rsa) - 1;

     out = cc$rms_fab;
     out.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
     out.fab$l_fna = argv[2];
     out.fab$b_fns = strlen (argv[2]);

     rab = cc$rms_rab;
     rab.rab$l_fab = &out;
     rab.rab$l_rbf = buf;
     rab.rab$w_rsz = sizeof(buf);

     if (((status=sys$parse(&fab)) & 1) != 1) lib$stop(status);
     if (((status=sys$search(&fab)) & 1) != 1) lib$stop(status);

/* Get a channel for QIO access */

     devnam_desc.addr = nam.nam$l_dev;
     devnam_desc.len  = nam.nam$b_dev;
     if (((status=sys$assign(&devnam_desc,&channel,0,0,0)) & 1) != 1) 
lib$stop(status);

/*  Set up the structures required for the ACP interface */

     fibdes.count = sizeof(fib);
     fibdes.address = &fib;

     fib.fib$l_acctl    = FIB$M_NOLOCK;
     fib.fib$w_fid_num  = nam.nam$w_fid[0];
     fib.fib$w_fid_seq  = nam.nam$w_fid[1];
     fib.fib$w_fid_rvn  = nam.nam$w_fid[2];

     atr[0].atr$w_type  = ATR$C_RECATTR;
     atr[0].atr$w_size  = ATR$S_RECATTR;
     atr[0].atr$l_addr  = &attributes;
     atr[1].atr$w_type  = 0;
     atr[1].atr$w_size  = 0;

/*  Get the file's current attributes, such as hi-block, rfm,... */

     status = 
SYS$QIOW(0,channel,IO$_ACCESS|IO$M_ACCESS,&iosb,0,0,&fibdes,0,0,0,&atr,0);
     if ((status & 1) != 1) lib$stop(status);
     if ((iosb.status & 1) != 1) lib$stop(iosb.status);

/*  Validate the specified values (e.g. can't extend the file) */

     file_hbk = attributes.fat$w_hiblkl + (attributes.fat$w_hiblkh << 16);
     file_nbytes = file_hbk*512;

     out.fab$l_alq = file_hbk;
     out.fab$b_rat = attributes.fat$b_rattrib;
     out.fab$b_rfm = attributes.fat$b_rtype;
     out.fab$w_mrs = attributes.fat$w_maxrec;  /* LRL=fat$w_rsize ?? */
     out.fab$b_fsz = attributes.fat$b_vfcsize;
     status = sys$create ( &out ) ;
     if (status & 1) status = sys$connect ( &rab );
     while ((status & 1) && (file_nbytes > 0)) {

         if (file_nbytes >= MAXBYTES) {
                 bytes = MAXBYTES;
                 file_nbytes -= MAXBYTES;
         } else {
                 bytes = file_nbytes;
                 rab.rab$w_rsz = file_nbytes;
                 file_nbytes = 0;
         }

         status = 
SYS$QIOW(0,channel,IO$_READVBLK,&iosb,0,0,&buf,bytes,vbn,0,0,0,0);
         vbn += MAXBLOCKS;
         if (status & 1) status = iosb.status;
         if (status & 1) status = sys$write ( &rab );
     }

/*  Release the files */

     (void) SYS$QIOW(0,channel,IO$_DEACCESS,&iosb,0,0,&fibdes,0,0,0,0,0);
     (void) sys$close ( &out );
     return status;
     }






More information about the Info-vax mailing list