@@ -15,12 +15,35 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
1515 size_t maxevents = 2 * nfds + 1 ;
1616 __wasi_subscription_t subscriptions [maxevents ];
1717 size_t nsubscriptions = 0 ;
18+
19+ // POLLPRI (exceptional/out-of-band data) is not supported in WASI.
20+ // If all requested events across all fds are POLLPRI, return ENOSYS.
21+ // Otherwise, remove POLLPRI so it never fires (same as no OOB data).
22+ {
23+ bool has_pri_only = false;
24+ bool has_non_pri = false;
25+ for (size_t i = 0 ; i < nfds ; ++ i ) {
26+ if (fds [i ].fd < 0 || fds [i ].events == 0 )
27+ continue ;
28+ if (fds [i ].events & ~POLLPRI )
29+ has_non_pri = true;
30+ else
31+ has_pri_only = true;
32+ }
33+ if (has_pri_only && !has_non_pri ) {
34+ errno = ENOSYS ;
35+ return -1 ;
36+ }
37+ }
38+
1839 for (size_t i = 0 ; i < nfds ; ++ i ) {
1940 struct pollfd * pollfd = & fds [i ];
2041 if (pollfd -> fd < 0 )
2142 continue ;
43+ // Strip POLLPRI as it is never reported in WASI.
44+ short events = pollfd -> events & ~POLLPRI ;
2245 bool created_events = false;
23- if ((pollfd -> events & POLLRDNORM ) != 0 ) {
46+ if ((events & POLLRDNORM ) != 0 ) {
2447 __wasi_subscription_t * subscription = & subscriptions [nsubscriptions ++ ];
2548 * subscription = (__wasi_subscription_t ){
2649 .userdata = (uintptr_t )pollfd ,
@@ -29,7 +52,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
2952 };
3053 created_events = true;
3154 }
32- if ((pollfd -> events & POLLWRNORM ) != 0 ) {
55+ if ((events & POLLWRNORM ) != 0 ) {
3356 __wasi_subscription_t * subscription = & subscriptions [nsubscriptions ++ ];
3457 * subscription = (__wasi_subscription_t ){
3558 .userdata = (uintptr_t )pollfd ,
@@ -42,8 +65,9 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
4265 // As entries are decomposed into separate read/write subscriptions,
4366 // we cannot detect POLLERR, POLLHUP and POLLNVAL if POLLRDNORM and
4467 // POLLWRNORM are not specified. Disallow this for now.
45- // Ignore fd entries that have no events requested.
46- if (!created_events && pollfd -> events != 0 ) {
68+ // Ignore fd entries that have no events requested (including
69+ // entries that only had POLLPRI which was stripped above).
70+ if (!created_events && events != 0 ) {
4771 errno = ENOSYS ;
4872 return -1 ;
4973 }
@@ -176,6 +200,26 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
176200 fds [i ].revents = 0 ;
177201 }
178202
203+ // POLLPRI (exceptional/out-of-band data) is not supported in WASI.
204+ // If all requested events across all fds are exclusively POLLPRI,
205+ // return ENOSYS. Otherwise, strip POLLPRI and proceed.
206+ {
207+ bool has_pri_only = false;
208+ bool has_non_pri = false;
209+ for (size_t i = 0 ; i < nfds ; ++ i ) {
210+ if (fds [i ].fd < 0 || fds [i ].events == 0 )
211+ continue ;
212+ if (fds [i ].events & ~POLLPRI )
213+ has_non_pri = true;
214+ else
215+ has_pri_only = true;
216+ }
217+ if (has_pri_only && !has_non_pri ) {
218+ errno = ENOSYS ;
219+ return -1 ;
220+ }
221+ }
222+
179223 size_t max_pollables = (2 * nfds ) + 1 ;
180224 state_t states [max_pollables ];
181225 poll_borrow_pollable_t pollables [max_pollables ];
@@ -207,14 +251,17 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
207251 continue ;
208252 }
209253
254+ // Strip POLLPRI, it is never reported in WASI (no OOB data).
255+ short events = pollfd -> events & ~POLLPRI ;
256+
210257 // Without a custom registration handle read/write readiness
211258 // below, but everything else is unsupported.
212- if (pollfd -> events & ~(POLLRDNORM | POLLWRNORM )) {
259+ if (events & ~(POLLRDNORM | POLLWRNORM )) {
213260 errno = EOPNOTSUPP ;
214261 return -1 ;
215262 }
216263
217- if (pollfd -> events & POLLRDNORM ) {
264+ if (events & POLLRDNORM ) {
218265 if (entry -> vtable -> get_read_stream ) {
219266 wasi_read_t read ;
220267 if (entry -> vtable -> get_read_stream (entry -> data , & read ) < 0 )
@@ -227,7 +274,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) {
227274 }
228275 }
229276
230- if (pollfd -> events & POLLWRNORM ) {
277+ if (events & POLLWRNORM ) {
231278 if (entry -> vtable -> get_write_stream ) {
232279 wasi_write_t write ;
233280 if (entry -> vtable -> get_write_stream (entry -> data , & write ) < 0 )
0 commit comments