when using epoll_ctl(), I found that the third parameter "fd" is another file descriptor besides the epoll file descriptor "epfd". And I saw an example like this:
event.data.fd = sfd; //sfd is a fd for listening
event.events = EPOLLIN | EPOLLET;
s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
As I saw, file descriptor in event.data.fd is the same as the third parameter in epoll_ctl, why need to pass this descriptor twice? is there any difference?
Actually you don't have to set event.data.fd
. It's a union, you can set other members. When epoll_wait
returns you get the event.data
associated with the descriptor that became interesting:
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
Which means you're completely free not to put anything in fd
and put something in ptr
instead (for example).
In conclusion, epoll_ctl
can't rely on the fact you'll fill fd
in, that's why it has a separate explicit parameter.