Previously calling poll() on a file not supporting epoll would propagate
the -EPERM error from epoll(); this is contrary to behavior on Linux,
where poll immediately returns with POLLIN|POLLOUT masked with the
requested events.
This change fixes this behavior, correctly handling unpollable files.
Checkpatch-Ignore: ENOSYS
Signed-off-by: Andrei Tatar <andrei@unikraft.io>
Reviewed-by: Ioan-Teodor Teugea <ioan_teodor.teugea@stud.acs.upb.ro>
Reviewed-by: Mihnea Firoiu <mihneafiroiu0@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1258
r = uk_sys_epoll_ctl(ef, EPOLL_CTL_ADD, p->fd, &ev);
monitored++;
}
- if (unlikely(r))
- switch (r) {
- case -EBADF:
- p->revents = POLLNVAL;
- ret++;
- break;
- case -EEXIST:
- uk_pr_warn("Duplicate fd in poll: %d\n", p->fd);
- ret = -ENOSYS;
- goto out;
- default:
- ret = r;
- goto out;
- }
- else
+ switch (r) {
+ case 0:
p->revents = 0;
+ break;
+ case -EBADF:
+ p->revents = POLLNVAL;
+ ret++;
+ break;
+ case -EPERM:
+ /* Files without epoll support always return in|out */
+ p->revents = (POLLIN|POLLOUT) & p->events;
+ if (p->revents)
+ ret++;
+ break;
+ case -EEXIST:
+ uk_pr_warn("Duplicate fd in poll: %d\n", p->fd);
+ ret = -ENOSYS;
+ goto out;
+ default:
+ ret = r;
+ goto out;
+ }
}
if (!monitored)
monitored = 1; /* Need at least 1 return entry */