[Info-vax] RMS and SSIO (again)
Arne Vajhøj
arne at vajhoej.dk
Mon Jan 10 14:17:25 EST 2022
On 1/9/2022 9:57 PM, Greg Tinkler wrote:
> frankly I am not surprised that the offshore VMS group could fix it,
> I am surprised the the back in the 80/90's the CRTL folk did not talk
> with the RMS group and have a good solution in place to start with.
> But then C IO was a very low priority, you either did RMS or your own
> $QIO. Now with open source it is a very different ball game.
>
> SSIO is not and was never a well designed solution. It looks more
> like a *nix persons view of how VMS should work.
> The SYS$MODIFY's function is what you just described, after an open,
> get RMS to pretend that the file is of a different format. And no it
> is not just 20 lines, that was the few line to help those that don't
> understand VMS/RMS what is possible. Careful code design would allow
> the initial open to use UDF so you don't need to do it each IO.
>
> "There is no need for all of that. It can be done other ways." Well
> if that is the case then please put your code up... and clearly you
> don't think SSIO is a good solution either. 8-))
I think SSIO is the only solution.
I don't believe the UDF hack is the solution.
But the UDF hack is not difficult to write.
Little bit more than 20 lines. With single reset call
for multiple files I ended up with a whooping 62 lines
of code.
$ type hack.c
#include <stdio.h>
#include <starlet.h>
#include <lib$routines.h>
#include <rms.h>
#include <rmedef.h>
static void set_rfm(struct FAB *fab, long int rfm)
{
long int stat;
fab->fab$l_fop |= FAB$M_ESC;
fab->fab$l_ctx |= RME$C_SETRFM;
fab->fab$b_rfm = rfm;
stat = sys$modify(fab,0,0);
if(stat & 1 == 0) lib$signal(stat);
}
static long int set_rfm_ext(struct FAB *fab, long int rfm)
{
long int stat;
long int oldrfm;
stat = sys$open(fab,0,0);
if(stat & 1 == 0) lib$signal(stat);
oldrfm = fab->fab$b_rfm;
set_rfm(fab, rfm);
stat = sys$close(fab,0,0);
if(stat & 1 == 0) lib$signal(stat);
return oldrfm;
}
#define MAX_FAB 100
static long int savrfm[MAX_FAB];
static struct FAB *savfab[MAX_FAB] = { NULL };
int hack_udfify_callback(int *first_arg, struct FAB *fab, struct RAB *rab)
{
int i;
long int oldrfm;
oldrfm = set_rfm_ext(fab, FAB$C_UDF);
for(i = 0; i < MAX_FAB; i++)
{
if(savfab[i] == NULL)
{
savrfm[i] = oldrfm;
savfab[i] = fab;
break;
}
}
return 0;
}
void hack_reset()
{
int i;
for(i = 0; i < MAX_FAB; i++)
{
if(savfab[i] != NULL)
{
set_rfm(savfab[i], savrfm[i]);
}
}
}
It works as expected.
$ type demo.c
#include <stdio.h>
#include <stdlib.h>
#include "hack.h"
void test1(char *fnm)
{
char cmd[1024];
sprintf(cmd, "write sys$output f$file_attributes(\"%s\",\"RFM\")", fnm);
system(cmd);
}
void test()
{
test1("z.1");
test1("z.2");
test1("z.3");
}
int main()
{
FILE *fp1, *fp2, *fp3;
test();
printf("Open files (2 with udfify callback and 1 without)\n");
fp1 = fopen("z.1", "r+", "shr=get", "acc", hack_udfify_callback, NULL);
fp2 = fopen("z.2", "r+", "shr=get", "acc", hack_udfify_callback, NULL);
fp3 = fopen("z.3", "r+", "shr=get");
test();
printf("Reset and close files\n");
hack_reset();
fclose(fp1);
fclose(fp2);
fclose(fp3);
test();
return 0;
}
$ cc demo
$ cc hack
$ link demo+hack
$ run demo
VAR
VAR
VAR
Open files (2 with udfify callback and 1 without)
UDF
UDF
VAR
Reset and close files
VAR
VAR
VAR
I just don't think it is useful for anything.
Arne
More information about the Info-vax
mailing list