Подтвердить что ты не робот

Есть ли способ получить имя файла из `FILE *`?

Возможный дубликат:
Получение имени файла из дескриптора файла в C

Есть ли простой и (разумно) переносимый способ получения имени файла из FILE*?

Я открываю файл с помощью f = fopen(filename, ...), а затем передаю f на другие функции, некоторые из которых могут сообщать об ошибке. Я хотел бы сообщить имя файла в сообщении об ошибке, но не нужно передавать дополнительный параметр.

Я мог бы создать пользовательскую оболочку struct { FILE *f, const char *name }, но возможно ли более простой способ? (Если FILE* не был открыт с помощью fopen, мне не нужен результат.)

4b9b3361

Ответ 1

На некоторых платформах (например, Linux) вы можете получить его, читая ссылку /proc/self/fd/<number>, так:

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

Это будет в моей системе распечатать /etc/passwd, если хотите.

Ответ 2

Это немного сложно, потому что FILE * может читать/писать из дескриптора файла, который вообще не связан с именованным файлом (например, неназванный канал или сокет). Вы можете получить дескриптор файла с fileno(), а затем есть системные способы узнать имя файла. Здесь обсуждается, как это сделать в Linux:

Получение имени файла из дескриптора файла в C

и под Windows это также не так просто:

http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx (в качестве дополнительного шага здесь вы используете _get_osfhandle(), чтобы получить дескриптор файла Windows из файла c-библиотеки дескриптор)