2012-06-27 12 views
6

Duplicar posible:
Getting Filename from file descriptor in C
Obtain filename from file pointer in C¿Cómo puedo encontrar un nombre de archivo, dado un puntero ARCHIVO?

Tengo una función aquí:

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

La única cosa que sabemos que aquí es la de un puntero al archivo; ¿Es posible obtener el nombre del archivo de acuerdo con el puntero?

+1

Creo que esto no es posible. Debe hacer un seguimiento del nombre de archivo por separado. –

+0

No es posible. De todos modos, [verifique esto] (http://stackoverflow.com/questions/9937645/obtain-filename-from-file-pointer-in-c) – tuxuday

+0

¿Qué sistema operativo? – hmjd

Respuesta

15

Consulte this answer para obtener el descriptor de archivo y this answer para obtener el nombre de archivo del descriptor de archivo. Debería estar bien en Linux (no estoy seguro acerca de otros sistemas operativos).

Aquí está un ejemplo rápido de trabajo (probado bajo 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; 
} 

Salida:

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

+1: hallazgos útiles. He formateado tu respuesta un poco para mejorar la legibilidad. –

+0

Lo he intentado, funciona muy bien, excepto que imprimirá/proc/self/fd/xxx después del nombre del archivo. – nzomkxia

+0

¿Qué pasa con este comentario: "Puede usar' readlink' en/proc/self/fd/NNN donde NNN es el descriptor de archivo "?¿Has probado readlink? – bcelary

0

Mientras buscaba, si usted es la raíz y el comando lsof se existido en su sistema , entonces puede usar fileno(fp) para obtener el descriptor del archivo de apertura, lsof -d descriptor. Puedes probarlo.

-2

Creo que es posible.
use fileno(fp) para obtener el descriptor.
Luego, puede usar la función fstat().

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

a continuación, se puede obtener una gran cantidad de infomación archivo en su *buf.

+2

la estructura devuelta por fstat no contiene un nombre de archivo. Ver http://linux.die.net/man/2/fstat. – bcelary

-1

De lo contrario, podría usar opendir y struct dirent si desea analizar todo el directorio y los archivos en una carpeta. Esto no utiliza un puntero de archivo, pero puede ser útil para usted, dependiendo de cómo esté funcionando su código.

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

Esto se puede hacer en 2 etapas. Primero, necesitarás obtener el descriptor del archivo, luego necesitarás recuperar el nombre del archivo. El siguiente es un ejemplo, ¡pero tiene algunas vulnerabilidades de desbordamiento de búfer graves!

#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

¿Qué pasa con OpenBSD? – user2284570

Cuestiones relacionadas