Reputation: 1565
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?
Upvotes: 15
Views: 7732
Reputation: 1
I think there is.
This is my test demo.
When using ev.data.fd = STDIN_FILENO
In the terminal, you press the Enter button to end the input and printf “welcome...”
When using ev.data.ptr = stdin
You need to press ctrl+d to end the input and printf “welcome...”
Does it mean that ev.data is not only used for recording?
int main()
{
int epfd, nfds;
struct epoll_event ev, events[5];
epfd = epoll_create(1);
//ev.data.fd = STDIN_FILENO;
ev.data.ptr = stdin;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
for (;;)
{
nfds = epoll_wait(epfd, events, 5, -1);
for (int i = 0; i < nfds; i++)
{
// if (events[i].data.fd == STDIN_FILENO)
if (events[i].data.ptr == stdin)
printf("welcome to epoll's word!\n");
}
}
}
Upvotes: 0
Reputation: 182744
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.
Upvotes: 21