On a listening socket I set the EPOLLIN bit however on client connections I set EPOLLIN | EPOLLOUT bits to struct epoll_event like so:

struct epoll_event ev;

ev.data.fd = fd;
ev.events = EPOLLIN | EPOLLOUT;
if (epoll_ctl(evs->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
     ...

And this is how I test bits:

if ((events & EPOLLIN) == EPOLLIN)
     ...
if ((events & EPOLLOUT) == EPOLLOUT)
     ...

I've also tried like:

if (events & EPOLLIN)
     ...
if (events & EPOLLOUT)
     ...

Both ways are ALWAYS true!

However, whenever I call epoll_wait on my epoll fd, the active file descriptor returned ALWAYS has both bits set even though send() didn't return EAGAIN but when I try to recv() it returns EAGAIN.

I have no idea what am I supposed to do when recv() returns EAGAIN, am I supposed to remove the EPOLLOUT flag or what?

More code as requested by @Nikolai N Fetissov:

static int get_active_fd(events *evs, int index, sstate_t *flags)
{
    uint32_t events = evs->events[index].events;
    int fd = evs->events[index].data.fd;;

    if ((events & EPOLLERR) == EPOLLERR || (events & EPOLLHUP) == EPOLLHUP) {
        close(fd);
        return -1;
    }

    if (events & EPOLLIN)
        *flags |= DATA_IN;

    return fd;
}

void sockset_add(events *evs, int fd)
{
    struct epoll_event ev;
    ...
    ev.data.fd = fd;
    ev.events = EPOLLIN;
    if (epoll_ctl(evs->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
        eprintf("sockset_add(): epoll_ctl(%d) returned an error %d(%s)\n",
                fd, errno, strerror(errno));
}

Then later where I call epoll_wait():

if (flags & DATA_IN) {
       /* try to read which is impossible because this is never set.  */
Edit
Report