ИМЯ
epoll_ctl -
    интерфейс
    управления
    файловым
    дескриптором
    epoll
ОБЗОР
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int
    fd, struct epoll_event *event);
ОПИСАНИЕ
Данный
    системный
    вызов,
    используется
    для
    добавления,
    изменения
    или
    удаления
    записей в
    списке interest
    экземпляра
    epoll(7), на
    который
    указывает
    файловый
    дескриптор
    epfd. Он
    запрашивает
    выполнение
    операции op
    для
    файлового
    дескриптора
    назначения
    fd.
Допустимые
    значения
    аргумента
    op:
  - EPOLL_CTL_ADD
- Добавить fd
      в список interest
      и связать
      настройки,
      указанные
      в event, с
      внутренним
      файлом,
      связанным
      с fd.
- EPOLL_CTL_MOD
- Изменить
      настройки,
      связанные
      с fd в
      списке interest,
      на новые,
      указанные
      в event.
- EPOLL_CTL_DEL
- Удалить
      (отменить
      регистрацию)
      файлового
      дескриптора
      назначения
      fd из
      списка interest.
      Значение
      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
    является
    битовой
    маской,
    составляемой
    из
    объединяемых
    (OR) нуля и
    более
    следующих
    возможных
    типов
    событий:
  - EPOLLIN
- Связанный
      файл
      доступен
      для чтения
      с помощью
      read(2).
- EPOLLOUT
- Связанный
      файл
      доступен
      для записи
      с помощью
      write(2).
- EPOLLRDHUP
    (начиная с Linux
    2.6.17)
- Одна из
      сторон
      потокового
      сокета
      закрыла
      соединение
      или
      выключила
      записывающую
      часть
      соединения
      (этот флаг
      особенно
      полезен
      при
      написании
      простого
      кода для
      обнаружения
      отключения
      стороны с
      помощью
      слежения Edge
      Triggered).
- EPOLLPRI
- Исключительное
      состояние
      файлового
      дескриптора.
      Смотрите
      описание
      POLLPRI в poll(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. Также
      смотрите
      ДЕФЕКТЫ.
- EPOLLEXCLUSIVE
    (начиная с Linux
    4.5)
- Установить
      единоличный
      режим
      пробуждения
      файлового
      дескриптора
      epoll,
      присоединённого
      к целевому
      файловому
      дескриптору
      fd. При
      появлении
      события
      пробуждения
      и к
      целевому
      файлу
      присоединены
      несколько
      файловых
      дескрипторов
      epoll с помощью
      EPOLLEXCLUSIVE, то
      события
      получат
      один или
      несколько
      файловых
      дескрипторов
      epoll через epoll_wait(2).
      По
      умолчанию
      в этом
      случае
      (если EPOLLEXCLUSIVE не
      установлен)
      все
      файловые
      дескрипторы
      epoll получают
      событие.
      Таким
      образом
      EPOLLEXCLUSIVE в
      некоторых
      случаях
      помогает
      избежать
      проблем
      стадной
      работы.
  
  - Если один
      файловый
      дескриптор
      указан в
      нескольких
      экземплярах
      epoll, и одни
      имеют флаг
      EPOLLEXCLUSIVE, а
      другие нет,
      то события
      получат
      все
      экземпляры
      epoll, у которых
      не указан
      EPOLLEXCLUSIVE, и, как
      минимум,
      один
      экземпляр
      epoll, у
      которого
      есть задан
      EPOLLEXCLUSIVE.
- Следующие
      значения
      можно
      указывать
      вместе с
      EPOLLEXCLUSIVE: EPOLLIN, EPOLLOUT, EPOLLWAKEUP
      и EPOLLET. Также
      можно
      указывать
      EPOLLHUP и EPOLLERR, но
      они не
      обязательны:
      как обычно,
      события
      всегда
      приходят,
      если они
      возникают,
      независимо
      указаны ли
      они в events. При
      указании
      других
      значений в
      events
      возникает
      ошибка EINVAL.
- EPOLLEXCLUSIVE можно
      использовать
      только в
      операции
      EPOLL_CTL_ADD;
      попытка
      использовать
      его в EPOLL_CTL_MOD
      вызывает
      ошибку.
      Если EPOLLEXCLUSIVE
      установлен
      с помощью
      epoll_ctl(), то
      последующая
      EPOLL_CTL_MOD с той же
      парой epfd, fd
      вызывает
      ошибку.
      Вызов epoll_ctl(), в
      котором
      указан EPOLLEXCLUSIVE
      в events и
      целевой
      файловый
      дескриптор
      fd в
      качестве
      экземпляра
      epoll, также
      вызывает
      ошибку. Во
      всех
      случаях
      возникает
      ошибка EINVAL.
ВОЗВРАЩАЕМОЕ
  ЗНАЧЕНИЕ
При
    успешном
    выполнении
    epoll_ctl()
    возвращается
    ноль. При
    возникновении
    ошибок epoll_ctl()
    возвращает
    -1 и
    устанавливает
    errno в
    соответствующее
    значение.
ОШИБКИ
  - EBADF
- Значение
      epfd или fd не
      является
      правильным
      файловым
      дескриптором.
- EEXIST
- Значение op
      равно EPOLL_CTL_ADD, и
      указанный
      файловый
      дескриптор
      fd уже
      зарегистрирован
      в данном
      экземпляре
      epoll.
- EINVAL
- Значение
      epfd не
      является
      файловым
      дескриптором
      epoll, или
      значение fd
      равно epfd,
      или
      запрашиваемая
      операция op
      не
      поддерживается
      данным
      интерфейсом.
- EINVAL
- Указан
      недопустимый
      тип
      события,
      так как в events
      установлен
      EPOLLEXCLUSIVE.
- EINVAL
- Значение op
      равно EPOLL_CTL_MOD и
      events
      содержит
      EPOLLEXCLUSIVE.
- EINVAL
- Значение op
      равно EPOLL_CTL_MOD, а
      ранее для
      этой пары
      epfd, fd был
      применён
      флаг EPOLLEXCLUSIVE.
- EINVAL
- Флаг EPOLLEXCLUSIVE
      указан в event
      и fd
      ссылается
      на
      экземпляр
      epoll.
- ELOOP
- Значение fd
      ссылается
      на
      экземпляр
      epoll и эта
      операция
      EPOLL_CTL_ADD
      привела бы
      к
      зацикливанию
      экземпляров
      epoll,
      отслеживающих
      один
      другого.
- 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.