2011-02-01 10 views
12

Duplicar posible:
Getting Filename from file descriptor in C¿Hay alguna manera de obtener el nombre de archivo de un `FILE *`?

¿Hay un (razonablemente) portátil de manera simple y de conseguir el nombre de archivo de un FILE*?

Abro un archivo usando f = fopen(filename, ...) y luego paso f a varias otras funciones, algunas de las cuales pueden reportar un error. Me gustaría informar el nombre del archivo en el mensaje de error pero evito tener que pasar el parámetro extra.

Podría crear un contenedor personalizado struct { FILE *f, const char *name }, pero ¿hay alguna manera más simple? (Si el FILE* no se abrió utilizando fopen no me importa el resultado.)

+0

duplicado http://stackoverflow.com/questions/1188757/getting-filename-from-file-descriptor-in-c –

+1

Ninguna manera estándar que conozco; 'freopen' te permitirá cambiar el modo de lectura/escritura y el modo binario/normal, pero si quieres el nombre por sí mismo (por ejemplo, para imprimir un mensaje de error) no tienes suerte. – dmckee

+0

Dado que está utilizando un sistema que tiene una estructura de archivos, dudo que "pasar un parámetro adicional" sea un problema. ¿Cuál es tu razón para no pasarlo? ¿Actuación? – Lundin

Respuesta

12

en algunas plataformas (como Linux), es posible que pueda a buscarla mediante la lectura de la relación de /proc/self/fd/<number>, así como:

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

Esto, en mi sistema, imprimirá /etc/passwd, según lo desee.

+0

¿Y qué imprime en una tubería anónima? – dmckee

+0

@dmckee: 'pipe: []' – intelfx

2

Es un poco difícil, porque un ARCHIVO * puede leer/escribir desde un identificador de archivo que no está asociado con un archivo con nombre en absoluto (por ejemplo, un tubo sin nombre o un zócalo). Puede obtener el identificador de archivo con fileno() y luego hay formas específicas del sistema para conocer el nombre del archivo. Aquí hay una discusión sobre cómo hacer esto en Linux:

Getting Filename from file descriptor in C

y en Windows esto no es mucho más fácil, ya sea:

http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx (como un paso adicional aquí, se utiliza _get_osfhandle() para obtener el mango de Windows archivo desde el descriptor de archivo c-biblioteca)

Cuestiones relacionadas