freopen - функции для открытия потоков
freopen(3)
функции для открытия потоков
Other Alias
fopen, fdopen
ОБЗОР
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
Требования макроса тестирования свойств для glibc
(см. feature_test_macros(7)):
fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
ОПИСАНИЕ
Функция
fopen() открывает файл с именем, которое задано в виде строки в
path, и связывает его с потоком.
Параметр mode указывает на строку, начинающуюся с одной из следующих
последовательностей (за ними могут следовать дополнительные символы,
описанные далее):
r
Открыть текстовый файл для чтения. Поток совмещается с началом файла.
r+
Открыть для чтения и записи. Поток совмещается с началом файла.
w
Обрезать файл до нулевой длины или создать текстовый файл для записи. Поток
совмещается с началом файла.
w+
Открыть для чтения и записи. Файл создаётся, если его не существует, в
противном случае он обрезается. Поток совмещается с началом файла.
a
Открыть для добавления (записи в конец файла). Файл создаётся, если его не
существует. Поток совмещается с концом файла.
a+
Открыть для чтения и добавления (записи в конец файла). Файл создаётся, если
не существует. Начальное положение в файле для чтения устанавливается в
начало файла, но вывод всегда добавляется в конец файла.
Строка mode может также содержать символ «b» в качестве последнего
символа или символа между двумя символами в любых описанных выше
двухсимвольных комбинациях. Это требуется только для совместимости с C89 и
не оказывает никакого влияния; символ «b» игнорируется во всех
POSIX-совместимых системах, включая Linux. Другие системы могут по-разному
обращаться с текстовыми и двоичными файлами, и добавление «b» может
оказаться полезным, если вы осуществляете ввод-вывод в двоичный файл и
ожидаете, что ваша программа может быть перенесена в не UNIX окружение.
О имеющихся расширениях mode в glibc смотрите
ЗАМЕЧАНИЯ далее.
Любой созданный файл будет иметь атрибуты S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), как изменённые в
соответствии со значением umask процесса (смотрите umask(2)).
Чтение и запись могут перемешиваться друг с другом в потоке, открытом для
чтения/записи, в любом порядке). Заметим, что в ANSI C требуется, чтобы
между выводом и вводом использовались функции позиционирования в файле, если
операция ввода не встретила конец файла. Если это условие не выполняется, то
при чтении разрешается возвращать результат, не совпадающий с данными самой
последней записи. Поэтому рекомендуется (а иногда и действительно необходимо
в Linux) использовать функции fseek(3) или fgetpos(3) между операциями
чтения и записи в одном потоке. Эти операции могут фактически быть пустыми
(например, fseek(..., 0L, SEEK_CUR), вызванная для того, чтобы возник её
побочный эффект синхронизации).
Открытие файла в режиме дописывания (a в качестве первого символа
mode) приводит к тому, что все последующие операции записи в этот поток
производятся в конец файла, как если бы перед ними была вызвана:
fseek(stream, 0, SEEK_END);
Функция fdopen() связывает поток с существующим дескриптором файла
fd. Режим mode потока (одно из следующих значений: «r», «r+», «w»,
,w+», «a», «a+») должен быть совместим с режимом дескриптора
файла. Указатель положения в файле в новом потоке принимает значение, равное
значению у fd, а указатели ошибок и конца файла очищаются. Режимы «w» или
«w+» не обрезают файл. При этом не делается копия дескриптора файла и он
будет закрыт одновременно с закрытием потока, созданного
fdopen(). Результат применения fdopen() к общему объекту памяти не
определён.
Функция freopen() открывает файл с именем path и связывает его с
потоком stream. Исходный поток (если такой существовал)
закрывается. Значение параметра mode такое же как у функции
fopen(). Основной задачей функции freopen() является смена файла,
связанного со стандартным текстовым потоком (stderr, stdin или
stdout).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении
fopen(),
fdopen() и
freopen() возвращается
указатель
FILE. В противном случае возвращается NULL и
errno
присваивается код ошибки.
ОШИБКИ
EINVAL
Передано неверное значение mode в fopen(), fdopen() или
freopen().
Функции fopen(), fdopen() и freopen() могут также завершаться с
ошибками и устанавливают значение errno равным какому-либо значению из
определённых в malloc(3).
Функция fopen() при ошибках устанавливает значение errno равным
какому-либо значению из определённых в open(2).
Функция fdopen() при ошибках устанавливает значение errno равным
какому-либо значению из определённых в fcntl(2).
Функция freopen() при ошибках устанавливает errno равным какому-либо
значению из определённых в open(2), fclose(3) и fflush(3).
АТРИБУТЫ
Описание терминов данного раздела смотрите в
attributes(7).
Интерфейс Атрибут Значение
fopen(),
fdopen(),
freopen()
безвредность в потоках: безвредно (MT-Safe)
СООТВЕТСТВИЕ СТАНДАРТАМ
fopen(),
freopen(): POSIX.1-2001, POSIX.1-2008, C89, C99.
fdopen(): POSIX.1-2001, POSIX.1-2008.
ЗАМЕЧАНИЯ
Замечания по glibc
Библиотека GNU C предоставляет следующие расширения строки в
mode:
c (начиная с glibc 2.3.3)
Не выполнять операцию открытия, последующие чтение и запись, точки отмены
нити (thread cancellation points). Этот флаг игнорируется для fdopen().
e (начиная с glibc 2.7)
Открыть файл с флагом O_CLOEXEC. Подробности смотрите в open(2). Этот
флаг игнорируется для fdopen().
m (начиная с glibc 2.3)
Пытаться получить доступ к файлу с помощью mmap(2), а не с помощью
системных операций ввода-вывода (read(2), write(2)). В настоящее время
mmap(2) используется только для файла, открытого на чтение.
x
Открыть файл в монопольном режиме (как с флагом O_EXCL у
open(2)). Если файл уже существует, то fopen() завершается с ошибкой и
устанавливает значение errno равное EEXIST. Этот флаг игнорируется для
fdopen().
В дополнении к этим символам, для fopen() и freopen() поддерживается
следующий синтаксис в mode:
,ccs=строка
Передаваемая строка используется как имя набора символов и поток
помечается как широкосимвольный. С того момента внутренние функции
преобразования перекодируют данные ввода-вывода в соответствии с набором
символов с именем строка. Если синтаксис ,ccs=строка не указан, то
широкосимвольность потока определяется по первой файловой операции. Если это
операция является широкосимвольной, то поток помечается как широкосимвольный
и загружаются функции для перекодировки.
ДЕФЕКТЫ
При анализе отдельных флагов в
mode (т. е., символов перед «ccs»)
реализация glibc для
fopen() и
freopen() ограничивает количество
обрабатываемых в
mode символов 7-ю (или, в glibc до версии 2.14, 6-ю, что
было недостаточно для включения всех возможных флагов, например
«rb+cmxe»). Текущая реализация
fdopen() анализирует в
mode не более 5
символов.