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

Discussion in 'C++' started by petertwocakes, Nov 16, 2009.

  1. 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
     
    petertwocakes, Nov 16, 2009
    #1
    1. Advertising

  2. * 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
     
    Alf P. Steinbach, Nov 16, 2009
    #2
    1. Advertising

  3. On 16 Nov, 10:12, "Alf P. Steinbach" <> wrote:
    > * 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


    Thanks for the explanation, I wasn't aware of that ambiguity. I'll
    just change what it passed in, as suggested.
     
    petertwocakes, Nov 16, 2009
    #3
  4. petertwocakes

    SeanW Guest

    On Nov 16, 4:45 am, petertwocakes <>
    wrote:
    > 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
     
    SeanW, Nov 16, 2009
    #4
  5. petertwocakes

    James Kanze Guest

    On Nov 16, 9:45 am, petertwocakes <>
    wrote:

    > 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).

    --
    James Kanze
     
    James Kanze, Nov 16, 2009
    #5
  6. On 16 Nov, 18:37, James Kanze <> wrote:
    > On Nov 16, 9:45 am, petertwocakes <>
    > wrote:
    >
    > > 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).
    >
    > --
    > James Kanze


    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.
     
    petertwocakes, Nov 16, 2009
    #6
  7. petertwocakes

    Jerry Coffin Guest

    In article <bdc422dc-b1ba-490b-8980-1b7b494611c2
    @k19g2000yqc.googlegroups.com>, says...
    >
    > On Nov 16, 9:45 am, petertwocakes <>
    > wrote:
    >
    > > 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).


    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).

    --
    Later,
    Jerry.
     
    Jerry Coffin, Nov 16, 2009
    #7
  8. petertwocakes

    James Kanze Guest

    On Nov 16, 8:30 pm, Jerry Coffin <> wrote:
    > In article <bdc422dc-b1ba-490b-8980-1b7b494611c2
    > @k19g2000yqc.googlegroups.com>, says...
    > > On Nov 16, 9:45 am, petertwocakes <>
    > > wrote:


    > > > 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).


    > 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.)

    --
    James Kanze
     
    James Kanze, Nov 17, 2009
    #8
  9. petertwocakes

    Jerry Coffin Guest

    In article <ca107ffd-4ca8-46f3-b81f-
    >,
    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.

    --
    Later,
    Jerry.
     
    Jerry Coffin, Nov 17, 2009
    #9
  10. petertwocakes

    Jorgen Grahn Guest

    On Tue, 2009-11-17, Jerry Coffin wrote:
    > In article <ca107ffd-4ca8-46f3-b81f-
    > >,
    > 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

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Nov 18, 2009
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lord0
    Replies:
    1
    Views:
    571
    Thomas Weidenfeller
    Apr 19, 2006
  2. Andrzej
    Replies:
    7
    Views:
    423
    Andrzej
    May 23, 2005
  3. chiara
    Replies:
    6
    Views:
    474
    Barry Schwarz
    Oct 6, 2005
  4. 2Barter.net
    Replies:
    0
    Views:
    371
    2Barter.net
    Dec 13, 2006
  5. Casey Hawthorne
    Replies:
    385
    Views:
    5,676
    ng2010
    Apr 4, 2010
Loading...

Share This Page