Linux программирование в примерах | страница 90



, >O_WRONLY и >O_RDWR, при вызове >open() могут добавляться с использованием поразрядного >OR дополнительные флаги. Стандарт POSIX предоставляет ряд этих дополнительных флагов. В табл. 4.7 представлены флаги, которые используются для большинства обычных приложений.


Таблица 4.7. Дополнительные флаги POSIX для >open()

ФлагЗначение
>O_APPENDПринудительно осуществляет все записи в конец файла
>O_CREATСоздает новый файл, если он не существует.
>O_EXCLПри использовании вместе с >O_CREAT возвращает ошибку, если файл уже существует
>O_TRUNCУрезает файл (устанавливает его длину в 0), если он существует.

Если даны >O_APPEND и >O_TRUNC, можно представить, как оболочка могла бы открывать или создавать файлы, соответствующие операторам >> и >>>. Например:

>int fd;

>extern char *filename;

>mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; /* 0666 */

>fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, mode); /* для > */

>fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, mode); /* для >> */

Обратите внимание, что флаг >O_EXCL здесь не используется, поскольку как для >>, так и для >>> не является ошибкой существование файла. Запомните также, что система применяет к запрошенным правам доступа >umask.

Также легко видеть, что, по крайней мере концептуально, >creat() можно было бы легко написать следующим образом:

>int creat(const char *path, mode_t mode) {

> return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode);

>}

ЗАМЕЧАНИЕ. Если файл открыт с флагом >O_APPEND, все данные будут записаны в конец файла, даже если текущее смещение было восстановлено с помощью >lseek().

Современные системы предоставляют дополнительные флаги с более специализированным назначением. Они кратко описаны в табл. 4.8.


Таблица 4.8. Дополнительные расширенные флаги POSIX для >open()

ФлагЗначение
>O_APPENDПринудительно осуществляет все записи в конец файла
>O_CREATСоздает новый файл, если он не существует.
>O_EXCLПри использовании вместе с >O_CREAT возвращает ошибку, если файл уже существует
>O_TRUNCУрезает файл (устанавливает его длину в 0), если он существует.

Флаги >O_DSYNC, >O_RSYNC и >O_SYNC требуют некоторых пояснений. Системы Unix (включая Linux) содержат внутренний кэш дисковых блоков, который называется буферным кэшем (buffer cache). Когда возвращается системный вызов >write(), данные, переданные операционной системе, были скопированы в буфер в буферном кэше. Они необязательно были записаны на диск.

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