[net.unix] file descriptors --> filenames

hnij%bnl@sri-unix.UUCP (02/19/84)

I am trying to convert a program that runs on the RSX operating system to
run on UNIX, and have found a few system calls that UNIX does not support.
One is the "getnam" function, which returns the filename associated with
a given file desciptor.  Is there any equivalent in UNIX?  I thought there
was, but after looking through the unix manuals, I can't find any.

		John Labovitz
		<hnij@BNL.ARPA>

gwyn%brl-vld@sri-unix.UUCP (02/21/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

There is no practical way to obtain the "file" name (really, the link
name) of a file from its file descriptor.  The kernel does not keep
this information after opening the file.  It is in fact possible for
the link under which the file was opened to have gone away although the
data may remain (under some new name), by the time you inspect the file
descriptor.  This "feature" is a consequence of the more general idea
of file names ("links") that UNIX uses.

Although all the file (inode) information of real value is in the stat
return structure, it is true that on most UNIXes one cannot change this
information (permissions, etc.) without using some link name to access
the file.  4.2BSD supplies some new system calls (fchmod, etc.) to let
one change inode information via the file descriptor alone.  Although
I think a more general interface might have been a better way to go, I
am glad to see the new system calls IF they work their way into the AT&T
distribution.  However, I would recommend that you not rely on them for
the time being, which is to say, you may well need to pass the file name
to the module that needs to change file permissions.  The name must
exist somewhere in the system you are converting.

jackm%ardc@sri-unix.UUCP (02/21/84)

From:      Jack Moskowitz (PAD) <jackm@ardc>

If you need to pass the filenames to other programs that you exec()
you can do this through the environment string. This allows the
power of the unix multi-processing while still using the filename
identifiers that yu may need. I realize that this is a little
more than your request, however it may be of some use to you.

guyton%rand-unix@sri-unix.UUCP (02/27/84)

From:  James_Guyton <guyton@rand-unix>

The only "practical" way of doing this is to hang onto the
filename yourself when you do the open (and forget it when
you close).

This isn't a general solution for Unix programs (since you
can be passed open files via stdin, stdout, stderr, pipes,
etc.), but if you're converting a pgm from RSX, that
shouldn't be a problem for you.  You might also run into
problems if the program ever changes its current working
directory after an open.

I suggest having an array of strings indexed by the real
file descriptor ("fileno" of the FILE argument).  Use the
variable NOFILE out of <sys/param.h> for the size of the
array.

-- Jim

mark@elsie.UUCP (03/02/84)

There is one way you could get a file name from a file descriptor, but it will
be *SLOW*. Use fstat(fd,(struct stat *) buf) to get the inode number and
device for the file (see stat(2) of the manual). Then use ncheck(8) to get the
full path name of the file. E.g.:

fp = popen("ncheck -i '#inode' 'file sys'", "r");
fgets(buf,100,fp);
fgets(buf,100,fp);
pclose(fp);

The second fgets call should retrieve the full file name. Ncheck is slow, it
may take a minute or two to return (it has to do a lot of searching). It
will not, of course, work for fd's that are to devices or pipes. In general,
as others have commented, it is far better to keep the file name around for
latter reference.

-- 
Mark J. Miller
NIH/NCI/DCE/LEC
UUCP:	decvax!harpo!seismo!rlgvax!cvl!elsie!mark
Phone:	(301) 496-5688