Article 129566 of comp.os.vms:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!bloom-beacon.mit.edu!gatech!news.mathworks.com!news.ultranet.com!usenet.eel.ufl.edu!netline-fddi.jpl.nasa.gov!nntp-server.caltech.edu!SOL1.GPS.CALTECH.EDU!CARL
From: carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick)
Newsgroups: comp.os.vms
Subject: Re: Renaming of Application LOG FILEs
Date: 18 Sep 1995 08:01:50 GMT
Organization: HST Wide Field/Planetary Camera
Lines: 81
Distribution: world
Message-ID: <43j91f$75k@gap.cco.caltech.edu>
References: <1995Sep17.182053.11266@eisner>,<43iv5l$q0h@gap.cco.caltech.edu>
Reply-To: carl@SOL1.GPS.CALTECH.EDU
NNTP-Posting-Host: sol1.gps.caltech.edu

In article <43iv5l$q0h@gap.cco.caltech.edu>, carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick) writes:
=You can:
=	1)  Immediately after calling fopen(), call fgetname() to get the full
=	    file specification of the file you just opened, and fstat() to get
=	    the file ID.
=	2)  Prior to writing to the file, call LIB$FID_TO_NAME to get the full
=	    filespec currently associated with the fid of the open file.  If
=	    the filespec returned by LIB$FID_TO_NAME doesn't match the filespec 
=	    you got in step 1, close the file and create a new one.

I'm afraid I was in error here.  There are circumstances under which fgetname()
and LIB$FID_TO_NAME won't return the same filename, even if the file hasn't
been renamed.  The circumstance in which I found that to be the case was when
the filespec supplied to fopen() involves a rooted logical.  fgetname() returns
a filespec using the logical name; LIB$FID_TO_NAME returns the longer filespec
with the name (either physical device name or logical name pointing to the
actual device).  Note:  This means that LIB$FID_TO_NAME may return invalid
filenames:  It just works its way up the directory tree, adding directory names
as it goes, and doesn't care how many directories it puts between the brackets.
However, that doesn't really matter for this application.  So what you've
actually got to do is to call LIB$FID_TO_NAME as soon as possible after
creating the file (and hope that someone hasn't managed to rename the file in
the meantime), and compare that value with what LIB$FID_TO_NAME gives you just
before you're ready to write to the file.

Anyway, here's an example of calling LIB$FID_TO_NAME, fgetname(), and fstat()
to get the necessary information.  If you actually want to use the code, I'd
advise you to add some error checking.  And you may want to avoid my use of an
undocumented feature of LIB$FID_TO_NAME:  As the device-name argument, it will
accept a filespec including the device name as well as accepting just the
device name.

#include stdio
#include descrip
#define $DESCRIPTOR_D(name)	struct dsc$descriptor_d name = \
	{ 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 }
#include stat

main()
{	unsigned long LIB$PUT_OUTPUT(), LIB$FID_TO_NAME(), STR$COMPARE_EQL(),
		LIB$RENAME_FILE();
	int strlen();
	static char buffer[512];
 	$DESCRIPTOR(devnam, buffer);
	$DESCRIPTOR(equmsg, "The file has not been renamed.");
	$DESCRIPTOR(neqmsg, "The file has been renamed.");
	$DESCRIPTOR(oldname, "TEST.DAT");
	$DESCRIPTOR(newname, "TEST.TMP");
	$DESCRIPTOR_D(oldfilespec);
	$DESCRIPTOR_D(newfilespec);
	FILE *fp;
	stat_t statbuf;

	fp = fopen("TEST.DAT", "w");
	fgetname(fp, buffer);
	devnam.dsc$w_length = strlen(buffer);
	fstat(fileno(fp), &statbuf);
	LIB$FID_TO_NAME(&devnam, &statbuf.st_ino[0], &oldfilespec);
	LIB$PUT_OUTPUT(&oldfilespec);
	LIB$FID_TO_NAME(&devnam, &statbuf.st_ino[0], &newfilespec);
	LIB$PUT_OUTPUT(&newfilespec);
	if (STR$COMPARE_EQL(&oldfilespec, &newfilespec) == 0)
		LIB$PUT_OUTPUT(&equmsg);
	else
		LIB$PUT_OUTPUT(&neqmsg);
	LIB$RENAME_FILE(&oldname, &newname);
	LIB$FID_TO_NAME(&devnam, &statbuf.st_ino[0], &newfilespec);
	LIB$PUT_OUTPUT(&newfilespec);
	if (STR$COMPARE_EQL(&oldfilespec, &newfilespec) == 0)
		LIB$PUT_OUTPUT(&equmsg);
	else
		LIB$PUT_OUTPUT(&neqmsg);
}
--------------------------------------------------------------------------------
Carl J Lydick | INTERnet: CARL@SOL1.GPS.CALTECH.EDU | NSI/HEPnet: SOL1::CARL

Disclaimer:  Hey, I understand VAXen and VMS.  That's what I get paid for.  My
understanding of astronomy is purely at the amateur level (or below).  So
unless what I'm saying is directly related to VAX/VMS, don't hold me or my
organization responsible for it.  If it IS related to VAX/VMS, you can try to
hold me responsible for it, but my organization had nothing to do with it.


