7.11. Функция fcntl
7.11. Функция fcntl
Сокращение fcntl означает «управление файлами» (file control). Эта функция выполняет различные операции управления дескрипторами. Перед описанием этой функции и ее влияния на сокет нам нужно составить некоторое более общее представление о ее возможностях. В табл. 7.9 приводятся различные операции, выполняемые функциями fcntl и ioctl и маршрутизирующими сокетами.
Таблица 7.9. Операции функций fcntl и ioctl и маршрутизирующих сокетов
Операция fcntl ioctl Маршрутизирующий сокет Posix.1g Установка сокета для неблокируемого ввода-вывода F_SETFL, O_NONBLOCK FIONBIO fcntl Установка сокета для ввода-вывода, управляемого сигналом F_SETFL, O_ASYNC FIOASYNC fcntl Установка владельца сокета F_SETOWN SIOCSPGRP или FIOSETOWN fcntl Получение владельца сокета F_GETOWN SIOCGPGRP или FIOGETOWN fcntl Получение текущего количества байтов в приемном буфере сокета FIONREAD Проверка, находится ли процесс на отметке внеполосных данных SIOCATMARK sockatmark Получение списка интерфейсов SIOCGIFCONF Sysctl Операции интерфейсов SIOC[GS]IFxxx Кэш-операции ARP SIOCxARP RTM_xxx Операции таблицы маршрутизации SIOGxxxRT RTM_xxxПервые шесть операций могут применяться к сокетам любым процессом, следующие две (операции над интерфейсами) используются реже, а последние две (ARP и таблица маршрутизации) выполняются администрирующими программами, такими как ifconfig и route. О различных операциях функции ioctl мы поговорим подробнее в главе 17, а о маршрутизирующих сокетах — в главе 18.
Существует множество способов выполнения первых четырех операций, но, как указано в последней колонке, стандарт POSIX определяет, что функция fcntl является предпочтительным способом. Отметим также, что POSIX предлагает функцию sockatmark (см. раздел 24.3) как наиболее предпочтительный способ тестирования на предмет пребывания процесса на отметке внеполосных данных. Оставшиеся операции с пустой последней колонкой не стандартизованы POSIX.
ПРИМЕЧАНИЕ
Отметим также, что первые две операции, устанавливающие сокет для неблокируемого ввода-вывода и для ввода-вывода, управляемого сигналом, традиционно применялись с использованием команд FNDELAY и FASYNC функции fcntl. POSIX определяет константы О_xxx.
Функция fcntl предоставляет следующие возможности, относящиеся к сетевому программированию:
? Неблокируемый ввод-вывод. Мы можем установить флаг состояния файла O_NONBLOCK, используя команду F_SETFL для отключения блокировки сокета. Неблокируемый ввод-вывод мы описываем в главе 16.
? Управляемый сигналом ввод-вывод. Мы можем установить флаг состояния файла O_ASYNC, используя команду F_SETFL, после чего при изменении состояния сокета будет генерироваться сигнал SIGIO. Мы рассмотрим это в главе 25.
? Команда F_SETOWN позволяет нам установить владельца сокета (идентификатор процесса или идентификатор группы процессов), который будет получать сигналы SIGIO и SIGURG. Первый сигнал генерируется, если для сокета включен управляемый сигналом ввод-вывод (см. главу 25), второй — когда для сокета приходят новые внеполосные (out-of-band data) данные (см. главу 24). Команда F_GETOWN возвращает текущего владельца сокета.
ПРИМЕЧАНИЕ
Термин «владелец сокета» определяется POSIX. Исторически реализации, происходящие от Беркли, называли его «идентификатор группы процессов сокета», потому что переменная, хранящая этот идентификатор, — это элемент so_pgid структуры socket [128, с. 438].
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* int arg */);
Возвращает: в случае успешного выполнения результат зависит от аргумента cmd, -1 в случае ошибки
Каждый дескриптор (включая сокет) имеет набор флагов, которые можно получить с помощью команды F_GETFL и установить с помощью команды F_SETFL. На сокет влияют следующие два флага:
? O_NONBLOCK — неблокируемый ввод-вывод;
? O_ASYNC — ввод-вывод, управляемый сигналом.
Позже мы опишем оба эти флага подробнее. Отметим, что типичный код, который устанавливает неблокируемый ввод-вывод с использованием функции fcntl, выглядит следующим образом:
int flags;
/* Делаем сокет неблокируемым */
if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
err_sys("F_GETFL error");
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
err_sys("F_SETFL error");
Учтите, что вам может встретиться код, который просто устанавливает желаемый флаг:
/* Неправильный способ сделать сокет неблокируемым */
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
err_sys("F_SETFL error");
Хотя при этом и устанавливается флаг отключения блокировки, также снимаются все остальные флаги состояния файла. Единственный корректный способ установить один из этих флагов состояния файла — получить текущие флаги, с помощью операции логического ИЛИ добавить новый флаг, а затем установить флаги.
Следующий код сбрасывает флаг отключения блокировки в предположении, что переменная flags была задана с помощью вызова функции fcntl, показанного ранее:
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
err_sys("F_SETFL error");
Сигналы SIGIO и SIGURG отличаются от других тем, что они генерируются для сокета, только если сокету был присвоен владелец с помощью команды F_SETOWN. Целое значение аргумента arg для команды F_SETOWN может быть либо положительным, задающим идентификатор процесса, получающего сигнал, либо отрицательным, абсолютное значение которого — это идентификатор группы процессов, получающей сигнал. Команда F_GETOWN возвращает владельца сокета, так как возвращаемое значение функции fcntl — либо идентификатор процесса (положительное возвращаемое значение), либо идентификатор группы процессов (отрицательное значение, отличное от -1). Разница между заданием процесса и группы процессов, получающих сигнал, в том, что в первом случае сигнал будет получен только одиночным процессом, тогда как во втором случае его получают все процессы в группе.
Когда создается новый сокет с помощью функции socket, у него нет владельца. Сокет, создаваемый из прослушиваемого сокета, наследует от него принадлежность владельцу (как и многие другие параметры сокетов [128, с. 462-463].
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
9.4.3. Управление атрибутами файла: fcntl()
9.4.3. Управление атрибутами файла: fcntl() Системный вызов fcntl() («управление файлом») предоставляет контроль над различными атрибутами либо самого дескриптора файла, либо лежащего в его основе открытого файла. Справочная страница GNU/Linux fcntl(2) описывает это таким способом:#include
9.4.3.5. Сводка fcntl()
9.4.3.5. Сводка fcntl() Сводка для системного вызова fcntl() приведена в табл. 9.5.Таблица 9.5. Сводка fcntl() Значение cmd Значение arg Возвращает F_DUPFD Наименьший новый дескриптор Дублирует аргумент fd F_GETFD Получает флаги дескриптора файла (close-on-exec) F_SETFD Новое значение
14.2.2. Блокировка POSIX: fcntl() и lockf()
14.2.2. Блокировка POSIX: fcntl() и lockf() Системный вызов fcntl() (file control — управление файлом) используется для блокировки файла. (Другое использование fcntl() было описано в разделе 9.4.3 «Управление атрибутами файла: fcntl()».) Он объявлен следующим образом:#include <unistd.h> /* POSIX */#include <fcntl.h>int
7.11. Функция fcntl
7.11. Функция fcntl Сокращение fcntl означает «управление файлами» (file control). Эта функция выполняет различные операции управления дескрипторами. Перед описанием этой функции и ее влияния на сокет нам нужно составить некоторое более общее представление о ее возможностях. В табл.
9.3. Блокирование записей с помощью fcntl по стандарту Posix
9.3. Блокирование записей с помощью fcntl по стандарту Posix Согласно стандарту Posix, интерфейсом для блокировки записей является функция fcntl:#include <fcntl.h>int fcntl(int fd, int cmd,… /* struct flock *arg */);/* Возвращает –1 в случае ошибки: результат, возвращаемый в случае успешного завершения,
Блокировка записей fcntl
Блокировка записей fcntl Последняя пpoгрaммa использует fcntl для синхронизации. Функция main приведена в листинге А.30. Эта программа будет выполняться успешно только в том случае, если количество потоков равно 1, поскольку блокировка fcntl предназначена для использования между
Функция SUM
Функция SUM Ваши возможности в подведении итогов не ограничены простым подсчетом записей. Используя функцию SUM, можно генерировать итоговые результаты для всех возвращаемых записей по любым числовым полям. Например, для создания запроса, который генерирует итоги по
20.3.7. Вызовы ioctl(2) и fcntl(2) являются препятствиями
20.3.7. Вызовы ioctl(2) и fcntl(2) являются препятствиями Механизмы ioctl(2) и fcntl(2) обеспечивают способ написания перехватчиков (hooks) в драйверах устройств. Первоначальным историческим использованием ioctl(2) была установка параметров, таких как скорость передачи и количество
20.3.7. Вызовы ioctl(2) и fcntl(2) являются препятствиями
20.3.7. Вызовы ioctl(2) и fcntl(2) являются препятствиями Механизмы ioctl(2) и fcntl(2) обеспечивают способ написания перехватчиков (hooks) в драйверах устройств. Первоначальным историческим использованием ioctl(2) была установка параметров, таких как скорость передачи и количество
8.3. Функция fcntl(): блокировки и другие операции над файлами
8.3. Функция fcntl(): блокировки и другие операции над файлами Функция fcntl() — это точка доступа к нескольким особым операциям над файлами. Первым аргументом функции является дескриптор файла, вторым указывается код операции. Для некоторых операций требуется также
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book
Функция uni()
Функция uni() Поиск/замена символа по его юникодному номеру также может быть сделана при помощи функции uni().Пример функции uni(): Boouni(107,32)Designer найдет слово Book