BUGS

在2.6.9之前的内核版本中,即使忽略了此参数,EPOLL_CTL_DEL操作在事件中也需要非空指针。从Linux 2.6.9开始,使用EPOLL_CTL_DEL时可以将event指定为NULL。需要在2.6.9之前移植到内核的应用程序应在事件中指定非空指针。

如果在标志中指定了EPOLLWAKEUP,但是调用者没有CAP_BLOCK_SUSPEND功能,则将默默地忽略EPOLLWAKEUP标志。这种不幸的行为是必要的,因为在原始实现中未对flags参数执行有效性检查,并且如果调用者没有CAP_BLOCK_SUSPEND功能,则添加的EPOLLWAKEUP带有导致调用失败的检查,至少会导致中断一个现有的用户空间应用程序恰好随机(且无用)地指定了该位。因此,如果尝试使用EPOLLWAKEUP标志,则健壮的应用程序应仔细检查其是否具有CAP_BLOCK_SUSPEND功能。

名称

epoll_ctl-epoll文件描述符的控制接口

语法

#包括

int epoll_ctl(int epfd,int op,int fd,struct epoll_event * event);

EPOLL_CTL - Linux手册页

Linux程序员手册 第2部分
更新日期: 2020-04-11

错误说明

EBADF
epfd或fd不是有效的文件描述符。
EEXIST
op为EPOLL_CTL_ADD,并且提供的文件描述符fd已在此epoll实例中注册。
EINVAL
epfd不是epoll文件描述符,或者fd与epfd相同,或者此接口不支持请求的操作op。
EINVAL
在事件中与EPOLLEXCLUSIVE一起指定了无效的事件类型。
EINVAL
op是EPOLL_CTL_MOD,事件包括EPOLLEXCLUSIVE。
EINVAL
op是EPOLL_CTL_MOD,并且EPOLLEXCLUSIVE标志先前已应用于此epfd,fd对。
EINVAL
在事件中指定了EPOLLEXCLUSIVE,而fd引用了epoll实例。
ELOOP
fd引用一个epoll实例,并且此EPOLL_CTL_ADD操作将导致epoll实例的一个循环循环,彼此监视。
ENOENT
op是EPOLL_CTL_MOD或EPOLL_CTL_DEL,并且fd未在该epoll实例中注册。
ENOMEM
没有足够的内存来处理请求的操作控制操作。
ENOSPC
尝试在epoll实例上注册(EPOLL_CTL_ADD)新文件描述符时,遇到了/ proc / sys / fs / epoll / max_user_watches施加的限制。有关更多详细信息,请参见epoll(7)。
EPERM
目标文件fd不支持epoll。如果fd引用了例如常规文件或目录,则可能发生此错误。

备注

epoll接口支持所有支持poll(2)的文件描述符。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

说明

此系统调用用于添加,修改或删除文件描述符epfd所引用的epoll(7)实例的兴趣列表中的条目。它要求对目标文件描述符fd执行操作op。

op参数的有效值为:

EPOLL_CTL_ADD
将一个条目添加到epoll文件描述符epfd的兴趣列表中。该条目包括文件描述符fd,对相应打开文件描述的引用(请参阅epoll(7)和open(2)),以及在event中指定的设置。
EPOLL_CTL_MOD
将与兴趣列表中的fd相关的设置更改为事件中指定的新设置。
EPOLL_CTL_DEL
从兴趣列表中删除(注销)目标文件描述符fd。事件参数将被忽略,并且可以为NULL(但请参见下面的BUGS)。

事件参数描述链接到文件描述符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 events */
    epoll_data_t data;        /* User data variable */
};

epoll_event结构的数据成员指定内核应保存的数据,然后在该文件描述符准备就绪时返回(通过epoll_wait(2))。

epoll_event结构的事件成员是一个位掩码,它通过对以下零个或多个可用事件类型进行"或"运算而构成:

EPOLLIN
关联的文件可用于read(2)操作。
EPOLLOUT
关联的文件可用于write(2)操作。
EPOLLRDHUP(since Linux 2.6.17)
流套接字对等方关闭连接,或关闭写入一半连接。 (此标志对于编写简单的代码以使用边沿触发的监视来检测对等设备关闭特别有用。)
EPOLLPRI
文件描述符上有特殊情况。参见poll(2)中有关POLLPRI的讨论。
EPOLLERR
错误情况发生在关联的文件描述符上。当读取端已关闭时,也会针对管道的写入端报告此事件。
epoll_wait(2)将始终报告此事件;调用epoll_ctl()时不必在事件中进行设置。
EPOLLHUP
挂断发生在关联的文件描述符上。
epoll_wait(2)将始终等待此事件;调用epoll_ctl()时不必在事件中进行设置。
请注意,当从管道(例如管道或流套接字)读取时,此事件仅指示对等方关闭了其通道的末端。仅在使用完该通道中的所有未完成数据之后,从该通道进行的后续读取将返回0(文件末尾)。
EPOLLET
请求关联文件描述符的边缘触发通知。 epoll的默认行为是级别触发。有关边缘触发和级别触发通知的更多详细信息,请参见epoll(7)。
调用epoll_ctl();时,此标志是event.events字段的输入标志。它永远不会由epoll_wait(2)返回。
EPOLLONESHOT(since Linux 2.6.2)
请求关联文件描述符的一键式通知。这意味着,在epoll_wait(2)通知了文件描述符的事件之后,文件描述符在兴趣列表中被禁用,并且epoll接口不会报告其他事件。用户必须使用EPOLL_CTL_MOD调用epoll_ctl()才能使用新的事件掩码重新配置文件描述符。
调用epoll_ctl();时,此标志是event.events字段的输入标志。它永远不会由epoll_wait(2)返回。
EPOLLWAKEUP(since Linux 3.5)
如果清除EPOLLONESHOT和EPOLLET并且该进程具有CAP_BLOCK_SUSPEND功能,请确保在此事件挂起或正在处理时,系统不会输入"挂起"或"休眠"。从调用epoll_wait(2)返回该事件开始,直到对该同一个epoll(7)文件描述符进行下一次调用epoll_wait(2)的事件被视为"已处理",该文件描述符的关闭,使用EPOLL_CTL_DEL删除事件文件描述符,或使用EPOLL_CTL_MOD清除事件文件描述符的EPOLLWAKEUP。另请参阅错误。
调用epoll_ctl();时,此标志是event.events字段的输入标志。它永远不会由epoll_wait(2)返回。
EPOLLEXCLUSIVE(since Linux 4.5)
为附加到目标文件描述符fd的epoll文件描述符设置排他唤醒模式。当发生唤醒事件并且使用EPOLLEXCLUSIVE将多个epoll文件描述符附加到同一目标文件时,一个或多个epoll文件描述符将收到epoll_wait(2)事件。在这种情况下(未设置EPOLLEXCLUSIVE时)的默认值是所有epoll文件描述符都接收事件。因此,EPOLLEXCLUSIVE在避免某些情况下的雷电群问题方面很有用。
如果同一文件描述符存在于多个epoll实例中,有些带有EPOLLEXCLUSIVE标志,而另一些没有,则将向所有未指定EPOLLEXCLUSIVE的epoll实例以及至少一个指定EPOLLEXCLUSIVE的epoll实例提供事件。
可以与EPOLLEXCLUSIVE一起指定以下值:EPOLLINEPOLLOUT,EPOLLWAKEUP和EPOLLET。也可以指定EPOLLHUP和EPOLLERR,但这不是必需的:通常,无论是否在事件中指定了这些事件,都始终报告这些事件。尝试在事件中指定其他值会产生错误EINVAL。
EPOLLEXCLUSIVE只能在EPOLL_CTL_ADD操作中使用;尝试将其与EPOLL_CTL_MOD一起使用会产生错误。如果已使用epoll_ctl()设置了EPOLLEXCLUSIVE,则在同一epfd,fd对上的后续EPOLL_CTL_MOD会产生错误。调用epoll_ctl()会在事件中指定EPOLLEXCLUSIVE并将目标文件描述符fd指定为epoll实例,这同样会失败。在所有这些情况下,错误均为EINVAL。
当调用epoll_ctl();时,EPOLLEXCLUSIVE标志是event.events字段的输入标志。它永远不会由epoll_wait(2)返回。

返回值

成功时,epoll_ctl()返回零。发生错误时,epoll_ctl()返回-1并正确设置了errno。

另外参见

epoll_create(2),epoll_wait(2),poll(2),epoll(7)

版本

epoll_ctl()已在2.6版中添加到内核中。

遵循规范

epoll_ctl()是特定于Linux的。从版本2.3.2开始,glibc提供了库支持。

日期:2019-08-20 17:58:37 来源:oir作者:oir