2012-06-27 5 views
6

Mögliche Duplizieren:
Getting Filename from file descriptor in C
Obtain filename from file pointer in CWie finde ich einen Dateinamen bei einem FILE-Zeiger?

ich eine Funktion hier haben:

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

Das einzige, was wir hier kennen, ist das ein Zeiger auf die Datei; ist es möglich, den Dateinamen nach dem Zeiger zu erhalten?

+1

Ich glaube, das ist nicht möglich. Sie sollten den Dateinamen getrennt verfolgen. –

+0

Nicht möglich. Wie auch immer [dieses überprüfen] (http://stackoverflow.com/questions/9937645/obtain-filename-from-file-pointer-in-c) – tuxuday

+0

Welches Betriebssystem? – hmjd

Antwort

15

Überprüfen Sie this answer, um den Dateideskriptor zu erhalten, und this answer, um den Dateinamen aus dem Dateideskriptor abzurufen. Sollte unter Linux OK sein (nicht sicher über andere Betriebssysteme).

Hier ist eine schnelle Arbeitsbeispiel (getestet unter 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; 
} 

Ausgang:

fp -> fno -> filename: 0x80010294 -> 3 -> /tmp/test.txt 
+1

+1: Hilfreiche Funde. Ich habe deine Antwort ein wenig formatiert, um die Lesbarkeit zu verbessern. –

+0

Ich habe das versucht, funktioniert sehr gut, außer dass/proc/self/fd/xxx nach dem Dateinamen gedruckt wird. – nzomkxia

+0

Was ist mit diesem Kommentar: "Sie können' readlink' auf/proc/self/fd/NNN verwenden, wobei NNN der Dateideskriptor ist "?Hast du readlink ausprobiert? – bcelary

0

Wie ich gesucht, wenn man die Wurzel ist und Befehl lsof ist in Ihrem System existiert , dann können Sie fileno(fp) verwenden, um den Deskriptor der Eröffnungsdatei lsof -d descriptor abzurufen. Du kannst es versuchen.

-2

Ich denke, es ist möglich.
Verwenden Sie fileno(fp), um den Deskriptor zu erhalten.
Dann können Sie fstat() Funktion verwenden.

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

dann können Sie eine Menge Dateiinfomationen in Ihrem *buf bekommen.

+2

Die von fstat zurückgegebene Struktur enthält keinen Dateinamen. Siehe http://linux.die.net/man/2/fstat. – bcelary

-1

Andernfalls könnten Sie opendir und struct dirent verwenden, wenn Sie alle Verzeichnisse und Dateien in einem Ordner analysieren möchten. Dies verwendet keinen Dateizeiger, kann aber nützlich für Sie sein, abhängig davon, wie Ihr Code funktioniert.

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); 
2

Dies kann in 2 Stufen erfolgen. Zuerst müssen Sie den Dateideskriptor abrufen, dann müssen Sie den Dateinamen wiederherstellen. Das Folgende ist ein Beispiel, hat aber einige schwerwiegende Pufferüberlauf-Schwachstellen!

#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; 
} 
+0

Was ist mit OpenBSD? – user2284570

Verwandte Themen