Как определить, что FILE * ссылается на каталог? - PullRequest
0 голосов
/ 13 декабря 2018

Я только что обнаружил, что FILE* может ссылаться не только на обычный файл, но и на каталог.В последнем случае fread завершится неудачей, а errno будет установлен на 21 (Is a directory).

Можно проверить минимальное воспроизведение здесь

#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>

int main() {
    char const* sz = ".";

    int fd = open(sz, O_RDONLY | O_NOFOLLOW); // all cleanup omitted for brevity
    FILE* file = fdopen(fd, "rb");
    // I would like to test in this line if it is a directory

    char buffer[21];
    int const n = fread(buffer, 1, 20, file);
    if (0 < n) {
        buffer[n] = 0;
        printf(buffer);
    } else {
        printf("Error %d", errno); // 21 = Is a directory
    }
}

Чтоправильный способ раннего обнаружения того, что мой FILE* ссылается на каталог, не пытаясь прочитать из него?

EDIT , чтобы отразить повторяющиеся флаги: я хочу проверить на FILE*, а не имя файла.Проверка только имени файла и последующее его открытие - условие гонки.

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Если предположить, что в POSIX-подобной среде у вас есть только файловый поток (FILE *fp), то вы, вероятно, будете использовать fileno() и fstat():

#include <sys/stat.h>


struct stat sb;
if (fstat(fileno(fp), &sb) != 0)
    …oops…
if (S_ISDIR(sb.st_mode))
    …it is a directory…
else
    …it is not a directory…
0 голосов
/ 13 декабря 2018

Проверка Заголовок fcntl.h man :

должен определять следующие символические константы как флаги создания файла для использования в значении oflag для open () и openat ().Значения должны быть поразрядными и подходящими для использования в директивах предварительной обработки #if.

И флаг:

O_DIRECTORY Fail, если не каталог.

0 голосов
/ 13 декабря 2018

Если вы работаете в системе на основе POSIX, используйте stat() (если вы хотите использовать имя файла в sz перед вызовом open()) или fstat() (если вы хотите использовать дескриптор fd после вызова open()) для получения структуры состояния файла из ОС.Член структуры с именем st_mode можно использовать с POSIX API S_ISDIR(st_mode), чтобы проверить, является ли файл каталогом.

Для получения дополнительной информации см .: http://man7.org/linux/man-pages/man2/stat.2.html

...