Читаем Linux программирование в примерах полностью

Таблица 9.4. Флаги O_xx для open(), creat() и fcntl()

КатегорияФункцииФлаги
Доступ к файлуopen(), fcntl()O_RDONLY, O_RDWR, O_WRONLY
Создание файлаopen()O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC
Статус файлаopen(), fcntl()O_APPEND, O_DSYNC, O_NONBLOCK, O_RSYNC, O_SYNC

Помимо первоначальной установки различных флагов с помощью open(), вы можете использовать fcntl() для получения текущих установок, а также их изменения. Это осуществляется с помощью значений cmd F_GETFL и F_SETFL соответственно. Например, вы можете использовать эти команды для изменения установки неблокирующего флага, O_NONBLOCK, подобным образом:

int fd_flags;

if ((fd_flags = fcntl(fd, F_GETFL)) < 0)

 /* обработать ошибку */

if ((fd_flags & O_NONBLOCK) != 0) { /* Установлен неблокирующий флаг */

 fd_flags &= ~O_NONBLOCK; /* Сбросить его */

 if (fcntl(fd, F_SETFL, fd_flags) != 0) /* Дать ядру новое значение */

  /* обработать ошибку */

}

Помимо самих режимов именованная константа O_ACCMODE является маской, которую вы можете использовать для выделения из возвращаемого значения режимов прав доступа.

fd_flags = fcntl(fd, F_GETFL);

switch (fd_flags & O_ACCESS) {

case O_RDONLY:

 /* ...действия только для чтения... */

 break;

case O_WRONLY:

 /* ...действия только для записи... */

 break;

case O_RDWR:

 /* ...действия для чтения и записи... */

 break;

}

POSIX требует, чтобы O_RDONLY, O_RDWR и O_WRONLY были побитово различными, таким образом, гарантируется, что код, подобный только что показанному, будет работать и является простым способом определения того, как был открыт произвольный дескриптор файла.

Используя F_SETFL вы можете также изменить эти режимы, хотя по-прежнему применяется проверка прав доступа. Согласно справочной странице GNU/Linux fcnlt(2) флаг O_APPEND не может быть сброшен, если он использовался при открытии файла.

9.4.3.4. Неблокирующий ввод/вывод для каналов и FIFO

Ранее для описания способа работы каналов мы использовали сравнение с двумя людьми, моющими и вытирающими тарелки с использованием сушилки; когда сушилка заполняется, останавливается моющий, а когда она пустеет, останавливается вытирающий. Это блокирующее поведение: производитель или потребитель блокируются в вызове write() или read(), ожидая либо освобождения канала, либо появления в нем данных.

В действительности человек, ожидающий опустения или заполнения сушилки, не должен просто неподвижно стоять.[101] Вместо этого незанятый супруг мог бы пойти и найти другую работу по кухне (такую, как подметание всех крошек за детьми на полу), пока сушилка снова не будет готова.

На языке Unix/POSIX эта концепция обозначается термином неблокирующий ввод/вывод, т.е. запрошенный ввод/вывод либо завершается, либо возвращает значение ошибки, указывающее на отсутствие данных (для читающего) или отсутствие места (для записывающего). Неблокирующий ввод/вывод применяется к каналам и FIFO, а не к обычным файлам на диске. Он может применяться также и к определенным устройствам, таким как терминалы, и к сетевым соединениям, обе эти темы выходят за рамки данной книги.

С функцией open() может использоваться флаг O_NONBLOCK для указания неблокирующего ввода/вывода, он может быть установлен и сброшен с помощью fcntl(). Для open() и read() неблокирующий ввод/вывод прост.

Открытие FIFO с установленным или сброшенным O_NONBLOCK демонстрирует следующее поведение:

open("/fifо/file", O_RDONLY, mode)

Блокируется до открытия FIFO для записи.

open("/fifo/file", O_RDONLY | O_NONBLOCK, mode)

Открывает файл, возвращаясь немедленно.

open("/fifo/file", O_WRONLY, mode)

Блокирует до открытия FIFO для чтения.

open("/fifo/file", O_WRONLY | O_NONBLOCK, mode)

Если FIFO был открыт для чтения, открывает FIFO и немедленно возвращается. В противном случае возвращает ошибку (возвращаемое значение -1 и errno установлен в ENXIO).

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных