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

Является ли создание двух FILE для того же файлового дескриптора четко определенным?

POSIX задает функцию fdopen, которая создает FILE для файлового дескриптора. POSIX также указывает функцию fileno, которая возвращает дескриптор файла для FILE. Вместе эти два могут быть использованы для создания второго FILE доступа к тому же файловому описателю, что и существующий файл:

FILE *secondfile(FILE *f, const char *mode)
{
    int fd = fileno(f);

    return fd >= 0 ? fdopen(fd, mode) : NULL;
}

Является ли это хорошо определенной операцией в POSIX? Что произойдет, когда я получаю как исходный FILE, так и второй FILE, который я сделал для одного и того же дескриптора файла? Определено ли взаимодействие? Если да, то как?

Исторически Unices использовал фиксированную таблицу структур FILE для 20 файлов, которые вы могли открыть. Вызов fdopen() в файловом дескрипторе, который уже был связан с FILE, таким образом, повредит существующий файл и даст поведение undefined. Я не уверен, что POSIX по-прежнему допускает такую ​​реализацию stdio, поэтому я задаю этот вопрос.

4b9b3361

Ответ 1

POSIX явно разрешает одновременное одновременное связывание нескольких "дескрипторов" с одним и тем же основным "описанием открытого файла", где дескрипторы могут быть либо файловыми дескрипторами или потоков. Хотя он специально не рассматривает несколько потоков, открытых через fdopen() в одном и том же дескрипторе файла, я не вижу оснований полагать, что они будут подвержены большему или различным требованиям, чем любые два потока, связанные с одним и тем же описанием открытого файла, как правило, подвержены.

POSIX определяет ограничения на то, как можно использовать два дескриптора в одном и том же открытом файле, чтобы избежать поведения undefined. Здесь уместно, что эти ограничения мало для дескрипторов дескрипторов; почти все они применяются к потокам, и они организованы в основном вокруг условий, связанных с буферизацией. Исключения связаны с позиционированием.

Если вы используете свои потоки в соответствии с этими ограничениями - в основном, но не исключительно, гарантируя, что вывод не буферизуется неписаным в одном потоке при переключении на использование другого - вы можете ожидать, O, чтобы вести себя как задокументированные. В противном случае поведение явно undefined.

Ответ 2

Учитывая типичную реализацию Unix, с структурой данных FILE, содержащей файловый дескриптор для чтения, и буфером для eh, буферизации и если вы знаете размер буфера и политику его заполнения (когда данные необходимы, а не сразу, когда буфер пуст), я бы сказал, что вы можете определить, что произойдет. Но я не знаю, что говорит стандарт POSIX, и я знаю, что это будет сложно использовать в программе. ( "Хорошо, поэтому я прочитал первые 4096 байт из файла на диске в этот ФАЙЛ и следующие 4096 байт в этот ФАЙЛ, а третий 4096-байтовый фрагмент из файла будет считан в ФАЙЛ, который достигает конец его буфера, и ему нужно больше читать..." )

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

Мое предположение было бы в том, что POSIX не указывает это достаточно хорошо, чтобы гарантировать, что он будет работать. Например, указывает ли POSIX, когда буфер внутри ФАЙЛА будет заполнен путем чтения из дескриптора файла? Когда пустое, когда пустое и больше данных необходимо, или любой из них, в зависимости от чего-то? В зависимости от выбора там данные из файлового дескриптора будут отображаться в разных файлах.