Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get the filename from a `FILE*`? [duplicate]

Tags:

c

Possible Duplicate:
Getting Filename from file descriptor in C

Is there a simple and (reasonably) portable way of getting the filename from a FILE*?

I open a file using f = fopen(filename, ...) and then pass down f to various other functions, some of which may report an error. I'd like to report the filename in the error message but avoid having to pass around the extra parameter.

I could create a custom wrapper struct { FILE *f, const char *name }, but is there perhaps a simpler way? (If the FILE* wasn't opened using fopen I don't care about the result.)

like image 885
nominolo Avatar asked Feb 01 '11 12:02

nominolo


People also ask

How do I get the filename from the file pointer?

use fileno(fp) to get the descriptor. Then, you can use fstat() function. The fstat() function shall obtain information about an open file asso‐ ciated with the file descriptor fildes, and shall write it to the area pointed to by buf. int fstat(int fildes, struct stat *buf);

How can I recover the file name using its file descriptor?

You can use readlink on /proc/self/fd/NNN where NNN is the file descriptor. This will give you the name of the file as it was when it was opened — however, if the file was moved or deleted since then, it may no longer be accurate (although Linux can track renames in some cases).


1 Answers

On some platforms (such as Linux), you may be able to fetch it by reading the link of /proc/self/fd/<number>, as so:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    char path[1024];
    char result[1024];

    /* Open a file, get the file descriptor. */
    FILE *f = fopen("/etc/passwd", "r");
    int fd = fileno(f); 

    /* Read out the link to our file descriptor. */
    sprintf(path, "/proc/self/fd/%d", fd);
    memset(result, 0, sizeof(result));
    readlink(path, result, sizeof(result)-1);

    /* Print the result. */
    printf("%s\n", result);
}

This will, on my system, print out /etc/passwd, as desired.

like image 97
davidg Avatar answered Oct 22 '22 04:10

davidg