Is it possible to get the name of a FILE given a FILE*?

P

petertwocakes

Hi,

Given my function which recieves a pointer to a FILE

FileFunction(FILE* inFile)
{
....
}

is it possible to find the name of the file?

Thanks
 
A

Alf P. Steinbach

* petertwocakes:
Hi,

Given my function which recieves a pointer to a FILE

FileFunction(FILE* inFile)
{
...
}

is it possible to find the name of the file?

You'll have to use C++ implemenation and/or operating system functions, and even
then it's questionable whether there is such a thing as "the" name of a file.

In both Windows and *nix a file can have any number of names, even in the same
directory, i.e. for these popular operating systems there's generally no such
thing as "the" name of a file (in Windows it's further complicated with any
given directory entry potentially being a pair of names, one short name in old
8+3 DOS format and one longer more descriptive name).

But presumably you mean the name that was used earlier within the C++ program to
open the FILE, and whether that's available, and if so how, depends on the C++
implementation; it's not standard functionality.

A practical solution is to not pass just a FILE*.

Instead pass an object of some class you've defined.


Cheers & hth.,

- Alf
 
P

petertwocakes

* petertwocakes:





You'll have to use C++ implemenation and/or operating system functions, and even
then it's questionable whether there is such a thing as "the" name of a file.

In both Windows and *nix a file can have any number of names, even in the same
directory, i.e. for these popular operating systems there's generally no such
thing as "the" name of a file (in Windows it's further complicated with any
given directory entry potentially being a pair of names, one short name in old
8+3 DOS format and one longer more descriptive name).

But presumably you mean the name that was used earlier within the C++ program to
open the FILE, and whether that's available, and if so how, depends on the C++
implementation; it's not standard functionality.

A practical solution is to not pass just a FILE*.

Instead pass an object of some class you've defined.

Cheers & hth.,

- Alf

Thanks for the explanation, I wasn't aware of that ambiguity. I'll
just change what it passed in, as suggested.
 
S

SeanW

Given my function which recieves a pointer to a FILE
is it possible to find the name of the file?


FYI, here's what a FILE* is in a fairly recent version
of the GNU C library:

struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is
flags. */
#define _IO_file_flags _flags

/* The following pointers correspond to the C++ streambuf protocol.
*/
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly.
*/
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of
backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */

struct _IO_marker *_markers;

struct _IO_FILE *_chain;

int _fileno;
int _blksize;
_Io_Off_t _old_offset; /* This used to be _offset but it's too
small. */

#define __HAVE_COLUMN /* temporary */
/* 1+column number of pbase(); 0 is unknown. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];

/* char* _save_gptr; char* _save_egptr; */

_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

As you can see the only connection to the underlying file
is the _fileno member, which, due to the existence
of hard links, can not be used to uniquely identify
a file name.

Sean
 
J

James Kanze

Given my function which recieves a pointer to a FILE
FileFunction(FILE* inFile)
{
...
}
is it possible to find the name of the file?

Perhaps on some OS's, but generally (and in particular under
Windows or Unix), it's not possible: a file can have several
different names, or it can have no name at all (a pipe).
 
P

petertwocakes

Perhaps on some OS's, but generally (and in particular under
Windows or Unix), it's not possible: a file can have several
different names, or it can have no name at all (a pipe).

Thanks for the replies. Always better to get a "no" than to waste time
down blind alleys!
Thanks for the definition of FILE - makes it pretty clear.
 
J

Jerry Coffin

Perhaps on some OS's, but generally (and in particular under
Windows or Unix), it's not possible: a file can have several
different names, or it can have no name at all (a pipe).

Windows will let you retrieve the name used to open a file using
GetFileInformationByHandleEx with the FILE_NAME_INFO flag (though
it's possible that will no longer be valid when you retrieve it).

Linux (and probably some other UNIX variants) will let you do roughly
the same thing by looking in:

/proc/self/fd/[descriptor]

where [descriptor] is the descriptor for that file. Again, there's no
guarantee that the name will still be valid when you retrieve it --
it's just giving you back the name that was passed to open() when
that descriptor was returned. It could have been unlinked or renamed
in the interim -- or worse yet, it could have been unlinked and a new
file with that name/path created, so you have the valid name of the
wrong file. Nonetheless, the name can be useful for some purposes
(especially if you verify that it still refers to the already-open
file, which usually isn't terribly difficult, though it is usually
quite non-portable).
 
J

James Kanze

Windows will let you retrieve the name used to open a file
using GetFileInformationByHandleEx with the FILE_NAME_INFO
flag (though it's possible that will no longer be valid when
you retrieve it).
Linux (and probably some other UNIX variants) will let you do
roughly the same thing by looking in:
/proc/self/fd/[descriptor]

where [descriptor] is the descriptor for that file. Again,
there's no guarantee that the name will still be valid when
you retrieve it -- it's just giving you back the name that was
passed to open() when that descriptor was returned.

I wasn't aware of this. What does it return when the
handle/file descriptor was created by CreatePipe/popen?
It could have been unlinked or renamed in the interim -- or
worse yet, it could have been unlinked and a new file with
that name/path created, so you have the valid name of the
wrong file. Nonetheless, the name can be useful for some
purposes (especially if you verify that it still refers to the
already-open file, which usually isn't terribly difficult,
though it is usually quite non-portable).

Just the name, despite the aleas, would probably be sufficient
for things like an error message or a log output. I can also
imagine some interpreters refusing to write to a file whose name
contained a ".." element, for security reasons (but such an
interpreter would probably have checked that before opening the
file).

(FWIW: /proc is not defined by Posix. I've seen it on numberous
Unix, but the exact format and arrangement varies considerably.
So your code under Unix would end up depending on each
individual variant. Still, it sounds like something that would
be worth implementing in some cases.)
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Windows will let you retrieve the name used to open a file
using GetFileInformationByHandleEx with the FILE_NAME_INFO
flag (though it's possible that will no longer be valid when
you retrieve it).
Linux (and probably some other UNIX variants) will let you do
roughly the same thing by looking in:
/proc/self/fd/[descriptor]

where [descriptor] is the descriptor for that file. Again,
there's no guarantee that the name will still be valid when
you retrieve it -- it's just giving you back the name that was
passed to open() when that descriptor was returned.

I wasn't aware of this. What does it return when the
handle/file descriptor was created by CreatePipe/popen?

I suspect it simply returns false to indicate failure, but I've never
tried it to see (and the documentation doesn't explicitly state what
happens when you try to get the name of something that doesn' thave
one).

[ ... ]
(FWIW: /proc is not defined by Posix. I've seen it on numberous
Unix, but the exact format and arrangement varies considerably.

Right -- one of those places that the vendors should have gotten
together and just made some decisions a long time ago. When you get
down to it, the format and arrangement don't matter nearly as much as
everybody agreeing on a common format/arrangement.
So your code under Unix would end up depending on each
individual variant. Still, it sounds like something that would
be worth implementing in some cases.)

I'd tend to guess so -- when you get down to it, few people have much
reason to care about more than a half dozen variants of UNIX (if even
that). Better still, a lot of this is just paths, so quite a bit of
it can probably be handled in configuration files.
 
J

Jorgen Grahn

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Windows will let you retrieve the name used to open a file
using GetFileInformationByHandleEx with the FILE_NAME_INFO
flag (though it's possible that will no longer be valid when
you retrieve it).
Linux (and probably some other UNIX variants) will let you do
roughly the same thing by looking in:
/proc/self/fd/[descriptor]

where [descriptor] is the descriptor for that file. Again,
there's no guarantee that the name will still be valid when
you retrieve it -- it's just giving you back the name that was
passed to open() when that descriptor was returned.

I wasn't aware of this. What does it return when the
handle/file descriptor was created by CreatePipe/popen?

I suspect it simply returns false to indicate failure, but I've never
tried it to see (and the documentation doesn't explicitly state what
happens when you try to get the name of something that doesn' thave
one).

You've both got it a bit backwards -- those "files" under /proc/self/fd/
are just symbolic links. You can either follow those links, or not.
For example:

tuva:/home/grahn# ls -l /proc/14450/fd/
total 0
lr-x------ 1 root root 64 Nov 18 20:11 0 -> /dev/null
l-wx------ 1 root root 64 Nov 18 20:11 1 -> /dev/null
l-wx------ 1 root root 64 Nov 18 20:11 2 -> /var/log/apache2/error.log
lrwx------ 1 root root 64 Nov 18 20:11 3 -> socket:[81740]
lrwx------ 1 root root 64 Nov 18 20:11 4 -> socket:[81741]
lr-x------ 1 root root 64 Nov 18 20:11 5 -> pipe:[81747]
...

Since they are there for informational purposes only, it doesn't harm
to have fake names for them. You're not supposed to try to open them
anyway (with some exceptions).

Off topic, I know ...

/Jorgen
 

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,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top