How to retrieve the name of the file from a FILE *

J

jacob navia

Recently there was a discussion in this group about
how to retrieve the file name given a FILE *.

The question raised my curiosity, and after some
research I have come up with a good implementation.

The solution is in the tutorial for lcc-win32
(http://www.cs.virginia.edu/~lcc-win32) page
331.

jacob
 
J

Joona I Palaste

jacob navia said:
Recently there was a discussion in this group about
how to retrieve the file name given a FILE *.
The question raised my curiosity, and after some
research I have come up with a good implementation.
The solution is in the tutorial for lcc-win32
(http://www.cs.virginia.edu/~lcc-win32) page
331.

This solution is non-portable as it makes use of the Win32 system APIs.
As usual... *sigh*... Jacob Navia failed to mention this fact.
 
J

jacob navia

Joona said:
This solution is non-portable as it makes use of the Win32 system APIs.
As usual... *sigh*... Jacob Navia failed to mention this fact.
Yes, it is based on the win32 API. That is why I did not publish the
code here, just giving a pointer to the code
 
J

Joona I Palaste

jacob navia said:
Yes, it is based on the win32 API. That is why I did not publish the
code here, just giving a pointer to the code

Why did you even give a pointer here? This newsgroup is not concerned
about system-specific code no matter where that code is written. Also,
having to download a 5-megabyte PDF file just to see two pages of C
code doesn't exactly appeal to me, and I don't think it appeals to
many other people either.
 
D

Dan Pop

In said:
The question raised my curiosity, and after some
research I have come up with a good implementation.

If it's not portable, you're abusing this newsgroup by advertising it.
If it's portable, my congratulations!

Dan
 
C

CBFalconer

Dan said:
If it's not portable, you're abusing this newsgroup by advertising
it. If it's portable, my congratulations!

I feel morally certain that M.Navias method is non-portable.
However, I can conceive of a portable method, if you are willing to
replace the fopen call with something else, say fnopen. Then it
only has to cache a copy of the file name in a hashtable, keyed by
the FILE* pointer returned, and retrieval is a simple O(1) lookup.
 
M

Mark McIntyre

Recently there was a discussion in this group about
how to retrieve the file name given a FILE *.

The question raised my curiosity, and after some
research I have come up with a good implementation.

The solution is in the tutorial for lcc-win32
(http://www.cs.virginia.edu/~lcc-win32) page
331.

It doesn't work. Please try not to post broken code, even in links, under
the guise of "good implementations"
 
J

jacob navia

Mark said:
It doesn't work. Please try not to post broken code, even in links, under
the guise of "good implementations"

Obviously I have just written it, so it is not well tested. Can you give
any examples for your assertion? In which circumstances it doesn't work?
 
K

Keith Thompson

jacob navia said:
Obviously I have just written it, so it is not well tested. Can you
give any examples for your assertion? In which circumstances it
doesn't work?

It doesn't work on any system other than MS Windows. I can't say
whether it does work on MS Windows; that's why we have
Windows-specific newsgroups, where people can comment intelligently on
Windows-specific code.

(I also took a brief look at the code, and I noticed that it returns
the strings "stdin", "stdout", and "stderr" for the corresponding
arguments. Those are C identifiers, not file names.)

There is no portable way to retrieve a file name from a FILE* value.
The closest you can come is to remember the name when you open the
file. If you don't have control over the code that opens the file,
you'll have to either give up on getting the name or resort to
non-portable code.
 
J

jacob navia

Keith said:
It doesn't work on any system other than MS Windows. I can't say
whether it does work on MS Windows; that's why we have
Windows-specific newsgroups, where people can comment intelligently on
Windows-specific code.

Under unix it is possible to do that too, I am sure. Maybe
using the inode of the file, you can get into the name,
or similar.

There is no portable directory handling in C. This hole in the
language is quite incredible, and there are a lot of proposals
on how to fill it. The standards comitee has blocked all those
propositions, some of them quite advanced.

I can't change this. I did not want to discuss system specific
code in this group so I gave just a pointer to the code. I
do not understand why all this fuzz.
(I also took a brief look at the code, and I noticed that it returns
the strings "stdin", "stdout", and "stderr" for the corresponding
arguments. Those are C identifiers, not file names.)

Yes, but since there isn't any file associated with the terminal,
I thought it could work like that... Maybe I should return
$CONIN $CONOUT or similar. You have a point here.
There is no portable way to retrieve a file name from a FILE* value.
The closest you can come is to remember the name when you open the
file. If you don't have control over the code that opens the file,
you'll have to either give up on getting the name or resort to
non-portable code.

Yes, I do not discuss that. I proposed a system specific
way of doing this under a popular platform, that's all.

jacob
 
K

Keith Thompson

jacob navia said:
Keith Thompson wrote: [...]
Under unix it is possible to do that too, I am sure. Maybe
using the inode of the file, you can get into the name,
or similar.

I'm not convinced that it's possible in any reasonable fashion, but I
won't get into the details.

[snip]
Yes, I do not discuss that. I proposed a system specific
way of doing this under a popular platform, that's all.

But you didn't mention that it's system specific. Here's what
you wrote:

] Recently there was a discussion in this group about
] how to retrieve the file name given a FILE *.
]
] The question raised my curiosity, and after some
] research I have come up with a good implementation.
]
] The solution is in the tutorial for lcc-win32
] (http://www.cs.virginia.edu/~lcc-win32) page

The phrase "good implementation", in the context of comp.lang.c, can
usually be assumed to refer to portable code.

A quick pointer to system-specific code is probably ok. If you had
told us that it's specific to MS Windows, we could have avoided this
branch of the thread and saved a lot of time.
 
D

Dik T. Winter

> Keith Thompson wrote: ....
>
> Under unix it is possible to do that too, I am sure. Maybe
> using the inode of the file, you can get into the name,
> or similar.

You can be sure, you are also wrong. To get the file name, the file
*must* have a name in the first place. And a file that has been
removed after the file was opened by the program does not have a
name (but it exists until the program closes it). But even if the
file has a name it might be very difficult to get the filename.
 
S

S.Tobias

jacob navia said:
Under unix it is possible to do that too, I am sure. Maybe
using the inode of the file, you can get into the name,
or similar.

FYI, in unix-like systems usually a file in an inode can have more
than one name, or none at all. Or to be more precise: files have
no names at all - file names are just identifiers of entries in
a directory, which point to inodes.
 
R

Richard Bos

Keith Thompson said:
It doesn't work on any system other than MS Windows. I can't say
whether it does work on MS Windows; that's why we have
Windows-specific newsgroups, where people can comment intelligently on
Windows-specific code.

(I also took a brief look at the code, and I noticed that it returns
the strings "stdin", "stdout", and "stderr" for the corresponding
arguments. Those are C identifiers, not file names.)

Which means, in fact, that this code is far from a "good
implementation", since it is obviously incorrect. I can make a file
called "stdout", and open it using fopen(). Pretending that stdout is
connected to this file called "stdout" is, plain and simply, wrong.

Richard
 
J

Jarno A Wuolijoki

I feel morally certain that M.Navias method is non-portable.
However, I can conceive of a portable method, if you are willing to
replace the fopen call with something else, say fnopen. Then it
only has to cache a copy of the file name in a hashtable, keyed by
the FILE* pointer returned, and retrieval is a simple O(1) lookup.

How do you hash pointers portably?
 
K

Kenneth Brody

Keith said:
jacob navia said:
Keith Thompson wrote: [...]
Under unix it is possible to do that too, I am sure. Maybe
using the inode of the file, you can get into the name,
or similar.

I'm not convinced that it's possible in any reasonable fashion, but I
won't get into the details.

Remember, under *nix, there might not even be a filename associated with
the FILE*. It may be a pipe, or the file may have been removed since it
was opened.

Or, there may be multiple filenames associated with the inode.

[...]
 
D

Dan Pop

In said:
However, I can conceive of a portable method, if you are willing to
replace the fopen call with something else, say fnopen. Then it
only has to cache a copy of the file name in a hashtable, keyed by
the FILE* pointer returned, and retrieval is a simple O(1) lookup.

Your method doesn't cover the predefined streams, which are the
interesting cases. If I open a file myself, I already know its name,
but it is sometimes helpful to know where your stdin data comes from.

Dan
 
D

Dan Pop

In said:
Under unix it is possible to do that too, I am sure. Maybe
using the inode of the file, you can get into the name,
or similar.

How do you get the inode of the file from the corresponding FILE
structure? All the Unix implementation cares about is the file
descriptor returned by the open() call.

But even if you get somehow the inode number, you can have as many file
names connected to the same inode as you want under Unix. They are
called hard links:

fangorn:/bin 23> ls -l -i gunzip gzip zcat
240249 -rwxr-xr-x 3 root root 53076 2003-03-14 01:16 gunzip
240249 -rwxr-xr-x 3 root root 53076 2003-03-14 01:16 gzip
240249 -rwxr-xr-x 3 root root 53076 2003-03-14 01:16 zcat

Dan
 
R

Richard Tobin

How do you get the inode of the file from the corresponding FILE
structure? All the Unix implementation cares about is the file
descriptor returned by the open() call.

You call the POSIX stat() function on that file descriptor.
But even if you get somehow the inode number, you can have as many file
names connected to the same inode as you want under Unix.

Including, of course, zero. Not to mention the case where the file
descriptor is a pipe or socket or some other thing that doesn't have a
real inode.

-- Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top