At 04:47 PM 3/16/00 -0600, Craig A. Berry wrote:
>At 7:24 AM -0500 3/16/00, lane @ DUPHY4.Physics.Drexel.Edu wrote:
> > > At 4:44 PM -0800 3/15/2000, [EMAIL PROTECTED] wrote:
> > > I did not say that
> > >>lib$fid_to_name() was turning DISK$USER: to USER:, I did say that it was
> >>>turning _SNFRN$DKB100: to USER: and that we ought not use it.
> >
> >... more details snipped....
> >(I don't see this problem [vms6.2], so my comments are general)
>
>Although the trail of speculation included many guesses about
>compiler and OS bugs, I think where we are now is that
>lib$fid_to_name sticks in the volume label for the device part of a
>filespec, presumably in any version of VMS (although that remains
>untested). This behavior works fine unless the volume label is
>identical to a rooted logical that points to somewhere other than the
>root of the same device.
OK, I've got a little test program that I think finally shows what's
happening (program included at end of message). To make a long story short,
it appears that lib$fid_to_name does not grab the volume label as I
originally thought, but rather the logical created by the MOUNT/SYSTEM
command (DVI$_LOGVOLNAM).
I think the conclusion must be, as Dan said many messages ago, "Don't do
that"; that is, as it turns out, don't create a logical name identical to
DVI$_LOGVOLNAM and expect anything to work that references that disk. It
might be nice if we could test for this in configure.com, but I don't think
there is anything wrong with the existing code. The rest of this message
tries to document, exhaustingly if not exhaustively, why that's true.
The logical created by MOUNT/SYSTEM will be DISK$volume-label by default,
and in fact this logical will be defined even if you give it another one
explicitly. So, for example,
$ mount/system node$drb0: foo
will yield one logical: DISK$FOO, but
$ mount/system node$drb0: foo bar
will yield two logicals: DISK$FOO and BAR.
As far as I can tell (and I can't test too aggressively since dismounting
disks with 200 users logged in is unpopular), lib$fid_to_name will take the
logical given explicitly to the MOUNT command as P3, and only use the
DISK$volume-label logical if there is no P3. The MOUNT command must record
this in VOLSET.SYS or some such place, from whence it is returned by
sys$getdvi when requested with DVI$_LOGVOLNAM.
My user disk is mounted as follows in SYSTARTUP_VMS.COM:
$ MOUNT/SYSTEM BUBBA$DRB2: DISK8 DISK8
and since we have a logical identical to the volume label, lib$fid_to_name
at first blush appears to be returning the volume label, but I'm pretty sure
this is really the logical:
$ run fidvoltest
Enter a complete path to a known file: sys$login:login.com
stat() says sys$login:login.com is file 43202, 89, 0 on device _BUBBA$DRB2
lib$fid_to_name gives a resulting name of DISK8:[BERRYC]LOGIN.COM;6
but on our system disk, no logical is given explicitly when it is mounted,
so lib$fid_to_name returns the DISK$volume-label form:
$ run fidvoltest
Enter a complete path to a known file: sys$common:[sysexe]directory.exe
stat() says sys$common:[sysexe]directory.exe is file 434, 2, 0 on device _BUBBA$DRA0
lib$fid_to_name gives a resulting name of DISK$DISK13:[SYSCOMMON.SYSEXE]DIRECTORY.EXE;1
Incidentally, the second example demonstrates that we cannot simply chop the
device name off and add back the one returned by stat() since there would be
tricky directory name munging to do. It also demonstrates that
lib$fid_to_name does not return the device lock name (DVI$_DEVLOCKNAM)
because for this volume that value is DISK13, identical to the volume label.
Instead it returns DVI$_LOGVOLNAM:
$ write sys$output f$getdvi("dra0:", "logvolnam")
DISK$DISK13
I close with the program I used to test this out -- compile with CC/PREFIX=ALL:
$ type fidvoltest.c
#include <stat.h>
#include <libdef.h>
#include <lib$routines.h>
#include <descrip.h>
#include <rms.h>
#include <rmsdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <str$routines.h>
int
main()
{
static char fname1[NAM$C_MAXRSS+1];
static char fname2[NAM$C_MAXRSS+1];
unsigned long int retsts;
$DESCRIPTOR( fname1_dsc, fname1 );
$DESCRIPTOR( fname2_dsc, fname2 );
$DESCRIPTOR( prompt_dsc, "Enter a complete path to a known file: ");
struct dsc$descriptor_s devdsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
struct stat statbuf;
retsts = lib$get_input( &fname1_dsc, &prompt_dsc );
if (retsts & 1) {
str$trim( &fname1_dsc, &fname1_dsc, &fname1_dsc.dsc$w_length );
fname1[fname1_dsc.dsc$w_length] = '\0';
} else {
printf("Error getting input\n");
exit(44);
}
if (stat(fname1, &statbuf) != 0) {
printf("Stat failed\n");
exit(44);
}
printf("stat() says %s is file %d, %d, %d on device %s\n",
fname1, statbuf.st_ino[0], statbuf.st_ino[1], statbuf.st_ino[2],
statbuf.st_dev);
devdsc.dsc$a_pointer = statbuf.st_dev;
devdsc.dsc$w_length = strlen(statbuf.st_dev);
retsts = lib$fid_to_name(&devdsc,&statbuf.st_ino,
&fname2_dsc,&fname2_dsc.dsc$w_length,0,0);
if (retsts & 1) {
fname2[fname2_dsc.dsc$w_length] = '\0';
printf("lib$fid_to_name gives a resulting name of %s\n", fname2);
} else {
exit(retsts);
}
}