ОБЗОР
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
ОПИСАНИЕ
Данный системный вызов выполняет операции управления экземпляром
epoll(7), на который указывает файловый дескриптор epfd. Он
запрашивает выполнение операции op для файлового дескриптора назначения
fd.
Допустимые значения аргумента op:
EPOLL_CTL_ADD Зарегистрировать файловый дескриптор назначения fd в экземпляре epoll, на который указывает файловый дескриптор epfd, и связать событие event с внутренним файлом, указывающим на fd.
EPOLL_CTL_MOD Изменить событие event, связанное с файловым дескриптором назначения fd.
EPOLL_CTL_DEL Удалить (отменить регистрацию) файлового дескриптора назначения fd из экземпляра epoll, на который указывает epfd. Значение event игнорируется и может быть NULL (но см. ДЕФЕКТЫ далее).
Аргумент event описывает объект, связанный с файловым дескриптором fd. Структура struct epoll_event определена так:
typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* События epoll */ epoll_data_t data; /* Переменная для данных пользователя */ };
Поле events является битовой маской, составляемой из следующих возможных типов событий:
EPOLLIN Связанный файл доступен для чтения с помощью read(2).
EPOLLOUT Связанный файл доступен для записи с помощью write(2).
EPOLLRDHUP (начиная с Linux 2.6.17) Одна из сторон потокового сокета закрыла соединение, или выключила записывающую часть соединения. (Этот флаг особенно полезен при написании простого кода для обнаружения отключения стороны с помощью слежения Edge Triggered.)
EPOLLPRI Для операций read(2) есть срочные данные.
EPOLLERR Произошла ошибка со связанным файловым дескриптором. epoll_wait(2) всегда будет ждать этого события; его не нужно устанавливать в events.
EPOLLHUP Произошло зависание связанного файлового дескриптора. Вызов epoll_wait(2) будет всегда ждать этого события; его не нужно указывать в events. Заметим, что при чтении из канала, такого как канал (pipe) или потоковый сокет, это событие всего-навсего показывает, что партнёр закрыл канал со своего конца. Дальнейшее чтение из канала будет возвращать 0 (конец файла) только после потребления всех неполученных данных в канале.
EPOLLET Установить поведение Edge Triggered для связанного файлового дескриптора. Поведение по умолчанию для epoll равно Level Triggered. Более подробное описание архитектуры распределения событий Edge и Level Triggered смотрите в epoll(7).
EPOLLONESHOT (начиная с Linux 2.6.2) Установить однократное получение для связанного файлового дескриптора. Это означает, что после извлечения события с помощью epoll_wait(2) со связанным дескриптором приём отключается и о других событиях интерфейс epoll сообщать не будет. Пользователь должен вызвать epoll_ctl() с операцией EPOLL_CTL_MOD для переустановки новой маски событий для файлового дескриптора.
EPOLLWAKEUP (начиная с Linux 3.5) Если флаги EPOLLONESHOT и EPOLLET сброшены и процесс имеет мандат CAP_BLOCK_SUSPEND, то убедитесь, что система не находится в режиме «suspend» или «hibernate», пока это событие ожидает обработки или обрабатывается. Событие считается «обрабатывающимся» начиная с момента, когда оно возвращается вызовом epoll_wait(2) и до следующего вызова epoll_wait(2) для того же файлового дескриптора epoll(7), закрытия этого файлового дескриптора, удаление файлового дескриптора события с помощью EPOLL_CTL_DEL или сброс EPOLLWAKEUP для файлового дескриптора события с помощью EPOLL_CTL_MOD. Также смотрите ДЕФЕКТЫ.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении epoll_ctl() возвращается ноль. При возникновении
ошибок epoll_ctl() возвращает -1 и устанавливает errno в
соответствующее значение.
ОШИБКИ
EBADF Значение epfd или fd не является правильным файловым дескриптором.
EEXIST Значение op равно EPOLL_CTL_ADD, и указанный файловый дескриптор fd уже зарегистрирован в данном экземпляре epoll.
EINVAL Значение epfd не является файловым дескриптором epoll, или значение fd равно epfd, или запрашиваемая операция op не поддерживается данным интерфейсом.
ENOENT В op было указано EPOLL_CTL_MOD или EPOLL_CTL_DEL, а fd не было зарегистрировано в данном экземпляре epoll.
ENOMEM Недостаточно памяти для обработки запрошенной управляющей операции op.
ENOSPC При попытке регистрации (EPOLL_CTL_ADD) нового файлового дескриптора в экземпляре достигнут предел, накладываемый /proc/sys/fs/epoll/max_user_watches. Подробней см. в epoll(7).
EPERM Файл назначения fd не поддерживает epoll. Эта ошибка может возникнуть, если fd ссылается на, например, обычный файл или каталог.
ВЕРСИИ
Системный вызов epoll_ctl() был добавлен в ядро версии 2.6.
СООТВЕТСТВИЕ СТАНДАРТАМ
Вызов epoll_ctl() есть только в Linux. В glibc соответствующая функция
появилась в версии 2.3.2.
ЗАМЕЧАНИЯ
Интерфейс epoll поддерживает все файловые дескрипторы, которые
поддерживает poll(2).
ДЕФЕКТЫ
В ядрах до версии 2.6.9 для операции EPOLL_CTL_DEL в event требовался указатель со значением не равным null, хотя этот аргумент игнорировался. Начиная с Linux 2.6.9, при EPOLL_CTL_DEL в event можно указывать NULL. В переносимых приложениях, которые должны быть работоспособными в системах на ядрах до 2.6.9, в event нужно указывать указатель со значением не равным null.Если в flags указан EPOLLWAKEUP, но вызывающий не имеет мандата CAP_BLOCK_SUSPEND, то флаг EPOLLWAKEUP просто игнорируется. Такое неуместное поведение необходимо, так как в первоначальной реализации не выполнялась проверка корректности аргумента flags, и добавление EPOLLWAKEUP с проверкой того, что вызов завершился с ошибкой, если вызывающий не имеет мандата CAP_BLOCK_SUSPEND, привело к поломке не одного существующего пользовательского приложения, которое произвольно устанавливало (и зря) этот бит. Корректное приложение должно дважды проверить, что имеет мандат CAP_BLOCK_SUSPEND, если пытается использовать флаг EPOLLWAKEUP.