[comp.lang.c] FILE *foo to filename?

akcs.dgy@vpnet.chi.il.us (Donald Yuniskis) (10/30/90)

Given:
  FILE *foo;
whats a clean way of obtaining the filename assoctiated with foo?
An initial thought is stat(fileno(foo)..) to get inode number but then what?
Any help is appreciated... thx, dgy

pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (10/31/90)

In article <272cd831-5edcomp.lang.c@vpnet.chi.il.us> akcs.dgy@vpnet.chi.il.us (Donald Yuniskis) writes:
>Given:
>  FILE *foo;
>whats a clean way of obtaining the filename assoctiated with foo?
>An initial thought is stat(fileno(foo)..) to get inode number but then what?
>Any help is appreciated... thx, dgy

You don't want to do this.  If the file's link count is more than one,
you can't do it at all, and even if the file's link count is equal to
one, you'd have to search the whole file system to get the right
filename.  Even assuming you know that FILE *foo is actually a file and
not a pipe, socket, etc.

(This is actually a comp.unix.* question.)

--
Paul Falstad, pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD
I would bring back hanging, and go into rope.  I would cut off the more
disreputable parts of the body and use the space for playing fields.

poser@csli.Stanford.EDU (Bill Poser) (10/31/90)

In article <272cd831-5edcomp.lang.c@vpnet.chi.il.us> akcs.dgy@vpnet.chi.il.us (Donald Yuniskis) writes:
>Given:
>  FILE *foo;
>whats a clean way of obtaining the filename assoctiated with foo?
>An initial thought is stat(fileno(foo)..) to get inode number but then what?
>Any help is appreciated... thx, dgy

If you are opening the file to begin with, just keep the name around.
I sometimes keep a table of file information, say an array or linked list
of structs something like:

	struct FileInfo{
		char *name;
		FILE *fp;
		short mode;
	};

If you're not opening the files yourself of course you can't do this.
What you do becomes operating system dependant - the file system is
not part of C. On a UNIX system, as suggested, you have to try to
match the inode number obtained from stat with a pathname. This is
not easy since the system does not maintain pointers from inodes
to paths, only from paths to inodes (that is, directories). You can
traverse the directory tree looking for matches to the inode number,
but this can be quite time-consuming. Note also that the path corresponding
to an inode number is not unique - there can be many links to a single
inode.

I'm curious, though, why anyone would want to do this.
It isn't terribly common to pass file pointers around in contexts
where one cannot also pass the name if desired.  Does the
application involve a child that inherits the parent's file descriptors
but not its data?

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (11/01/90)

In article <272cd831-5edcomp.lang.c@vpnet.chi.il.us>, akcs.dgy@vpnet.chi.il.us (Donald Yuniskis) writes:
> Given:
>   FILE *foo;
> what's a clean way of obtaining the filename assoctiated with foo?

There isn't any portable way, and even on a particular system

> An initial thought is stat(fileno(foo)..) to get inode number but then what?

there may not *BE* any filename associated with foo.  Consider

	foo = popen("cat >/dev/null");

fileno() isn't going to do you much good there and no more will stat().

Your best bet is to provide and use your own interface:

	FILE *mnem_fopen(...);
	void mnem_fclose(...);
	char *mnem_fname(FILE *);

where mnem_fopen() would stash the stream pointer and a copy of the
name away in a table or list or something, mnem_fclose() would clear
the entry out of the table, and mnem_fname() would return a pointer
to (the copy of) the name or NULL as appropriate.

Then on UNIX and PCs at least, there's all kinds of fun possible where
you open a file with a relative name like "foo.bar" and then change
directory; a copy of the original string won't do any more because it'll
be misinterpreted.

Then there are changes to the file system:  on UNIX and VMS at least,
a file *name* can be deleted from its directory while the *file* is
still in use.  In UNIX this is quite a useful idiom:  open a scratch
file and unlink it straight away; now you have a file which will automatically
disappear when the program terminates, but can be safely used while it's
running.  Or a file may be renamed, and a new file created with the old
name...

-- 
The problem about real life is that moving one's knight to QB3
may always be replied to with a lob across the net.  --Alasdair Macintyre.