[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