Skip to content

emscripten: add pthread_sigmask, sigwait, faccessat, pthread_kill, se…#5270

Open
guybedford wants to merge 1 commit into
rust-lang:mainfrom
guybedford:emscripten-apis
Open

emscripten: add pthread_sigmask, sigwait, faccessat, pthread_kill, se…#5270
guybedford wants to merge 1 commit into
rust-lang:mainfrom
guybedford:emscripten-apis

Conversation

@guybedford

@guybedford guybedford commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Comment thread src/unix/linux_like/emscripten/mod.rs Outdated
@guybedford guybedford force-pushed the emscripten-apis branch 2 times, most recently from 5255c2d to bf4b9fe Compare July 10, 2026 01:51

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgross35 tgross35 added the stable-nominated This PR should be considered for cherry-pick to libc's stable release branch label Jul 10, 2026
Comment thread libc-test/build.rs
@rustbot

rustbot commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

guybedford added a commit to guybedford/nix that referenced this pull request Jul 11, 2026
Adds wasm32-unknown-emscripten as a target for nix, plus a CI job that runs the
full test suite under Node.

Source changes to compile on emscripten (which behaves like a Linux/musl libc):

* ioctl: use the Linux ioctl module and a c_int ioctl_num_type on emscripten
  (src/sys/ioctl, src/sys/mod.rs).
* resource: enable getrlimit/setrlimit and the Resource enum via libc::rlimit.
* socket: include emscripten in the SockaddrStorage AF_UNIX (pathname/unnamed)
  decode arms.
* unistd: sethostname is unavailable on emscripten, so gate it out.

The suite spawns OS threads (signal and socket-peer tests), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).

Genuinely-unsupported operations are ignored with
#[cfg_attr(target_os = "emscripten", ignore)] rather than cfg'd out, covering
fork/wait, pty/termios, mkfifo, getpwnam/setgroups/acct, flock, if_nametoindex,
pipe2 FD_CLOEXEC, AF_UNIX SCM_RIGHTS/datagram, thread signal masking, and
setrlimit; a few tests are cfg'd out where the feature is entirely absent
(raw signal actions, socketpair) or the host differs (linkat symlink follow).

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#libc-0.2-emscripten for the
  emscripten externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the NODEFS/socket/blocking patches this target depends on
  (emscripten-core/emscripten#27305, #27306).

Suite result: 148 passed, 0 failed, 35 ignored under Node - green on Linux CI.
guybedford added a commit to guybedford/nix that referenced this pull request Jul 11, 2026
Adds wasm32-unknown-emscripten as a target for nix, plus a CI job that runs the
full test suite under Node.

Source changes to compile on emscripten (which behaves like a Linux/musl libc):

* ioctl: use the Linux ioctl module and a c_int ioctl_num_type on emscripten
  (src/sys/ioctl, src/sys/mod.rs).
* resource: enable getrlimit/setrlimit and the Resource enum via libc::rlimit.
* socket: include emscripten in the SockaddrStorage AF_UNIX (pathname/unnamed)
  decode arms.
* unistd: sethostname is unavailable on emscripten, so gate it out.

The suite spawns OS threads (signal and socket-peer tests), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).

Genuinely-unsupported operations are ignored with
#[cfg_attr(target_os = "emscripten", ignore)] rather than cfg'd out, covering
fork/wait, pty/termios, mkfifo, getpwnam/setgroups/acct, flock, if_nametoindex,
pipe2 FD_CLOEXEC, AF_UNIX SCM_RIGHTS/datagram, thread signal masking, and
setrlimit; a few tests are cfg'd out where the feature is entirely absent
(raw signal actions, socketpair) or the host differs (linkat symlink follow).

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#libc-0.2-emscripten for the
  emscripten externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the NODEFS/socket/blocking patches this target depends on
  (emscripten-core/emscripten#27305, #27306).

Suite result: 148 passed, 0 failed, 35 ignored under Node - green on Linux CI.
guybedford added a commit to guybedford/nix that referenced this pull request Jul 11, 2026
Adds wasm32-unknown-emscripten as a target for nix, plus a CI job that runs the
full test suite under Node.

Source changes to compile on emscripten (which behaves like a Linux/musl libc):

* ioctl: use the Linux ioctl module and a c_int ioctl_num_type on emscripten
  (src/sys/ioctl, src/sys/mod.rs).
* resource: enable getrlimit/setrlimit and the Resource enum via libc::rlimit.
* socket: include emscripten in the SockaddrStorage AF_UNIX (pathname/unnamed)
  decode arms.
* unistd: sethostname is unavailable on emscripten, so gate it out.

The suite spawns OS threads (signal and socket-peer tests), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).

Genuinely-unsupported operations are ignored with
#[cfg_attr(target_os = "emscripten", ignore)] rather than cfg'd out, covering
fork/wait, pty/termios, mkfifo, getpwnam/setgroups/acct, flock, if_nametoindex,
pipe2 FD_CLOEXEC, AF_UNIX SCM_RIGHTS/datagram, thread signal masking, and
setrlimit; a few tests are cfg'd out where the feature is entirely absent
(raw signal actions, socketpair) or the host differs (linkat symlink follow).

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#libc-0.2-emscripten for the
  emscripten externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the NODEFS/socket/blocking patches this target depends on
  (emscripten-core/emscripten#27305, #27306).

Suite result: 148 passed, 0 failed, 35 ignored under Node - green on Linux CI.
guybedford added a commit to guybedford/nix that referenced this pull request Jul 11, 2026
Adds wasm32-unknown-emscripten as a target for nix, plus a CI job that runs the
full test suite under Node.

Source changes to compile on emscripten (which behaves like a Linux/musl libc):

* ioctl: use the Linux ioctl module and a c_int ioctl_num_type on emscripten
  (src/sys/ioctl, src/sys/mod.rs).
* resource: enable getrlimit/setrlimit and the Resource enum via libc::rlimit.
* socket: include emscripten in the SockaddrStorage AF_UNIX (pathname/unnamed)
  decode arms.
* unistd: sethostname is unavailable on emscripten, so gate it out.

The suite spawns OS threads (signal and socket-peer tests), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).

Genuinely-unsupported operations are ignored with
fork/wait, pty/termios, mkfifo, getpwnam/setgroups/acct, flock, if_nametoindex,
pipe2 FD_CLOEXEC, AF_UNIX SCM_RIGHTS/datagram, thread signal masking, and
setrlimit; a few tests are cfg'd out where the feature is entirely absent
(raw signal actions, socketpair) or the host differs (linkat symlink follow).

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#libc-0.2-emscripten for the
  emscripten externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the NODEFS/socket/blocking patches this target depends on
  (emscripten-core/emscripten#27305, #27306).

Suite result: 148 passed, 0 failed, 35 ignored under Node - green on Linux CI.
guybedford added a commit to guybedford/nix that referenced this pull request Jul 11, 2026
Adds wasm32-unknown-emscripten as a target for nix, plus a CI job that runs the
full test suite under Node.

Source changes to compile on emscripten (which behaves like a Linux/musl libc):

* ioctl: use the Linux ioctl module and a c_int ioctl_num_type on emscripten
  (src/sys/ioctl, src/sys/mod.rs).
* resource: enable getrlimit/setrlimit and the Resource enum via libc::rlimit.
* socket: include emscripten in the SockaddrStorage AF_UNIX (pathname/unnamed)
  decode arms.
* unistd: sethostname is unavailable on emscripten, so gate it out.

The suite spawns OS threads (signal and socket-peer tests), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).

Unsupported operations are ignored with #[cfg_attr(target_os = "emscripten",
ignore)] rather than cfg'd out wherever they still compile, covering fork/wait,
pty/termios, mkfifo, getpwnam/setgroups/acct, flock, if_nametoindex, pipe2
FD_CLOEXEC, AF_UNIX SCM_RIGHTS/datagram, getsockname, socketpair, setrlimit, and
the linkat symlink-follow host check. The signal-delivery tests (signal, killpg,
thread mask) and the AF_ROUTE test are cfg'd out instead: compiling their
extern "C" handlers in perturbs the wasm indirect function table and aborts the
runtime.

Temporary, until the dependencies land upstream:

* the emscripten CI job injects a libc patch (guybedford/libc#libc-0.2-emscripten,
  rust-lang/libc#5270) via `cargo --config`, so other targets and CI jobs are
  unaffected.
* it also builds against the guybedford/emscripten `cf` fork, which carries the
  NODEFS/socket/blocking patches this target depends on
  (emscripten-core/emscripten#27305, #27306).

Suite result: 148 passed, 0 failed, 38 ignored under Node - green on Linux CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 11, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, two
non-blocking readiness paths are added alongside the normal `Poll::poll`:

* `Poll::new_with_callback` arms a persistent callback on the epoll fd via the
  runtime's `emscripten_epoll_set_callback`, delivering ready events on a fresh
  host tick whenever the set makes progress. The callback state is boxed, owned
  by the arming selector, and disarmed on drop; it may freely re-enter mio to
  (de)register sources.
* `Registry::poll_ready` does a zero-timeout drain of the same epoll set as a
  readiness probe where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).
Doctests are skipped on this target: rustdoc does not apply the emcc link args,
so the examples cannot be linked with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the epoll callback (emscripten-core/emscripten#27207), AF_UNIX pathname
  stream sockets, and multicast getsockopt patches this target depends on.

Suite result: 148 passed, 0 failed, 3 ignored under Node - green on CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 11, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, two
non-blocking readiness paths are added alongside the normal `Poll::poll`:

* `Poll::new_with_callback` arms a persistent callback on the epoll fd via the
  runtime's `emscripten_epoll_set_callback`, delivering ready events on a fresh
  host tick whenever the set makes progress. The callback state is boxed, owned
  by the arming selector, and disarmed on drop; it may freely re-enter mio to
  (de)register sources.
* `Registry::poll_ready` does a zero-timeout drain of the same epoll set as a
  readiness probe where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).
Doctests are skipped on this target: rustdoc does not apply the emcc link args,
so the examples cannot be linked with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the epoll callback (emscripten-core/emscripten#27207), AF_UNIX pathname
  stream sockets, and multicast getsockopt patches this target depends on.

Suite result: 148 passed, 0 failed, 3 ignored under Node - green on CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 13, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, the
epoll fd is exposed via `AsRawFd` on `Poll`/`Registry` so the runtime driving
mio can arm emscripten's `emscripten_epoll_set_callback` on it directly,
delivering ready events on a fresh host tick whenever the set makes progress. A
zero-timeout `Poll::poll` remains available as a synchronous readiness probe
where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).
Doctests are skipped on this target: rustdoc does not apply the emcc link args,
so the examples cannot be linked with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  AF_UNIX pathname stream sockets and multicast getsockopt patches this target
  depends on.

Suite result: 146 passed, 0 failed, 3 ignored under Node - green on CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 13, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, the
epoll fd is exposed via `AsRawFd` on `Poll`/`Registry` so the runtime driving
mio can arm emscripten's `emscripten_epoll_set_callback` on it directly,
delivering ready events on a fresh host tick whenever the set makes progress. A
zero-timeout `Poll::poll` remains available as a synchronous readiness probe
where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).
Doctests are skipped on this target: rustdoc does not apply the emcc link args,
so the examples cannot be linked with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  AF_UNIX pathname stream sockets and multicast getsockopt patches this target
  depends on.

Suite result: 146 passed, 0 failed, 3 ignored under Node - green on CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 13, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, the
epoll fd is exposed via `AsRawFd` on `Poll`/`Registry` so the runtime driving
mio can arm emscripten's `emscripten_epoll_set_callback` on it directly,
delivering ready events on a fresh host tick whenever the set makes progress. A
zero-timeout `Poll::poll` remains available as a synchronous readiness probe
where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD so the
main thread can block; JSPI (-sJSPI) provides the return-to-host suspension for
blocking reads/writes, and NODERAWFS/NODERAWSOCKETS back the filesystem and
sockets with node's. This needs nightly + rust-src and a JSPI-capable Node
(26+, or 22 with --experimental-wasm-jspi). No custom target spec is required:
nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937).
Doctests are skipped on this target: rustdoc does not apply the emcc link args,
so the examples cannot be linked with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  AF_UNIX pathname stream sockets and multicast getsockopt patches this target
  depends on.

The two `reconnect_udp_socket_*` tests are ignored on emscripten: libuv does
not re-associate a connected UDP socket when it is reconnected to a new peer,
so no readiness is delivered for the new peer.

Suite result: 144 passed, 0 failed, 5 ignored under Node - green on CI.
guybedford added a commit to guybedford/mio that referenced this pull request Jul 14, 2026
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs
the suite under Node. Resolves tokio-rs#642.

Emscripten exposes a real epoll backed by its runtime event loop, so the
existing Linux epoll selector is reused rather than adding a new backend. The
wasm `compile_error!` guard is relaxed to let emscripten through, and the
`epoll`/`eventfd`/pipe-waker cfg lists gain emscripten.

Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, the
epoll fd is exposed via `AsRawFd` on `Poll`/`Registry` so the runtime driving
mio can arm emscripten's `emscripten_epoll_set_callback` on it directly,
signalling on a fresh host tick whenever the set has ready events. A
zero-timeout `Poll::poll` remains available as a synchronous readiness probe
where a blocking wait is impossible.

AF_UNIX support is stream-only: emscripten's node-backed sockets have no
datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are
not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's
`socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`.

The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt
with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD.
Blocking harness socket ops (accept/recv) block their pthread through
emscripten's sync-proxy wait primitive (`_emscripten_fd_wait`) - no JSPI or
stack suspension is involved anywhere in the suite. NODERAWFS/NODERAWSOCKETS
back the filesystem and sockets with node's. This needs nightly + rust-src.
No custom target spec is required: nightly now emits the __main_argc_argv
entry point (rust-lang/rust#158937). Doctests are skipped on this target:
rustdoc does not apply the emcc link args, so the examples cannot be linked
with the socket/thread runtime.

Temporary, until the dependencies land upstream:

* Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten
  epoll/pthread externs (rust-lang/libc#5270).
* the CI job builds against the guybedford/emscripten `cf` fork, which carries
  the epoll callback, `_emscripten_fd_wait` blocking-ops, AF_UNIX pathname
  stream socket, and multicast getsockopt patches this target depends on.

The two `reconnect_udp_socket_*` tests are ignored on emscripten: libuv does
not re-associate a connected UDP socket when it is reconnected to a new peer,
so no readiness is delivered for the new peer.

Suite result: 144 passed, 0 failed, 5 ignored under Node - green on CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-linux O-linux-like O-unix S-waiting-on-review stable-nominated This PR should be considered for cherry-pick to libc's stable release branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants