23

Possible Duplicate:
Getting Filename from file descriptor in C
Obtain filename from file pointer in C

I have a function here:

handle_file(FILE *file)
{
    if(condition)
    {
        print filename and other msg;
    }
}

The only thing we know here is the a pointer to the file; is it possible to get the filename according to the pointer?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
nzomkxia
  • 1,219
  • 4
  • 16
  • 35
  • 2
    I believe this is not possible. You should keep track of the filename separately. – Ivaylo Strandjev Jun 27 '12 at 07:18
  • Not possible. Anyway [check this](http://stackoverflow.com/questions/9937645/obtain-filename-from-file-pointer-in-c) – tuxuday Jun 27 '12 at 07:23
  • I agree that this isn't possible using only the pointer to the file. Perhaps try storing a char* pointer that references the filename where ever you got the file from in the first place. You should be able to do this in the same block as the fopen without too much trouble. – JonVD Jun 27 '12 at 07:25
  • For macOS, see this [answer](https://stackoverflow.com/a/58082106/15168) to another question by [D.Nathanael](https://stackoverflow.com/users/8474738/d-nathanael). – Jonathan Leffler Sep 24 '19 at 16:06

5 Answers5

24

Check out this answer to obtain file descriptor and this answer to get file name from file descriptor. Should be OK on Linux (not sure about other operating systems).

Here's a quick working example (tested under Cygwin/Win7):

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

int main()
{
    int MAXSIZE = 0xFFF;
    char proclnk[0xFFF];
    char filename[0xFFF];
    FILE *fp;
    int fno;
    ssize_t r;

    // test.txt created earlier
    fp = fopen("test.txt", "r");
    if (fp != NULL)
    {
        fno = fileno(fp);
        sprintf(proclnk, "/proc/self/fd/%d", fno);
        r = readlink(proclnk, filename, MAXSIZE);
        if (r < 0)
        {
            printf("failed to readlink\n");
            exit(1);
        }
        filename[r] = '\0';
        printf("fp -> fno -> filename: %p -> %d -> %s\n",
                fp, fno, filename);
    }
    return 0;
}

Output:

fp -> fno -> filename: 0x80010294 -> 3 -> /tmp/test.txt
Community
  • 1
  • 1
bcelary
  • 1,827
  • 1
  • 17
  • 17
1

This can be done in 2 stages. First, you will need to get the file descriptor, then you will need to recover the filename. The following is an example, but has some serious buffer overflow vulnerabilities!

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

char * recover_filename(FILE * f) {
  int fd;
  char fd_path[255];
  char * filename = malloc(255);
  ssize_t n;

  fd = fileno(f);
  sprintf(fd_path, "/proc/self/fd/%d", fd);
  n = readlink(fd_path, filename, 255);
  if (n < 0)
      return NULL;
  filename[n] = '\0';
  return filename;
}
svlasov
  • 9,923
  • 2
  • 38
  • 39
Alex Chamberlain
  • 4,147
  • 2
  • 22
  • 49
-1

As I searched, if you are the root and command lsof is existed in your system, then you can use fileno(fp) to get the descriptor of the opening file, lsof -d descriptor. You can try it.

MYMNeo
  • 818
  • 5
  • 9
-1

Otherwise you could use opendir and struct dirent if you want to analyse all the directory and files in a folder. This is not using a file pointer, but may be usefull for you, depending of how your code is working.

DIR *BaseDIR;
struct dirent *curentDir;
BaseDIR = opendir("path/to/the/directory");
while((curentDir = readdir(BaseDIR)) != NULL){
      printf("directory or file name : %s\n",curentDir->d_name);
}
closedir(BaseDIR);
-3

I think it's possible.
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);

then, you can get a lot of file infomation in your *buf.

madper
  • 806
  • 1
  • 10
  • 25
  • 4
    the structure returned by fstat does not contain a file name. See http://linux.die.net/man/2/fstat. – bcelary Jun 28 '12 at 12:15