Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -634,3 +634,55 @@ jobs:
- name: before_cache_script
run: rm -rf $CARGO_HOME/registry/index

# Runs the test suite against wasm32-unknown-emscripten under Node.
emscripten:
runs-on: ubuntu-latest
timeout-minutes: 20
# TEMPORARY: builds against the guybedford/emscripten `cf` fork, which
# carries the NODEFS/socket/blocking patches this target depends on. Once
# those land upstream the fork checkout can be dropped for a released emsdk.
steps:
- name: checkout
uses: actions/checkout@v4

- name: setup Rust
uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src

# JSPI is the return-to-host bridge for blocking reads/writes; it needs a
# Node with JSPI on by default (V8 13.x+), not the one bundled with emsdk.
- name: setup Node
uses: actions/setup-node@v4
with:
node-version: 26

- name: record JSPI-capable node
run: echo "JSPI_NODE=$(which node)" >> "$GITHUB_ENV"

- name: install emsdk
run: |
git clone --depth 1 https://github.com/emscripten-core/emsdk.git
./emsdk/emsdk install latest
./emsdk/emsdk activate latest

- name: overlay guybedford/emscripten (cf) fork
run: |
git clone --branch cf https://github.com/guybedford/emscripten.git em-fork
python3 em-fork/bootstrap.py
rm -rf ./emsdk/upstream/emscripten
ln -s "$(pwd)/em-fork" ./emsdk/upstream/emscripten

- name: test
run: |
source ./emsdk/emsdk_env.sh
export EM_CONFIG="$EMSDK/.emscripten"
CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER="$JSPI_NODE" \
RUSTFLAGS="-A linker_messages -C target-feature=+atomics,+bulk-memory,+mutable-globals -C link-arg=-pthread -C link-arg=-sPROXY_TO_PTHREAD -C link-arg=-sNODERAWSOCKETS -C link-arg=-sNODERAWFS -C link-arg=-sALLOW_MEMORY_GROWTH=1 -C link-arg=-sEXIT_RUNTIME=1 -C link-arg=-sJSPI" \
cargo +nightly test --target wasm32-unknown-emscripten -Zbuild-std=std,panic_abort --test test \
--config 'patch.crates-io.libc.git="https://github.com/guybedford/libc"' \
--config 'patch.crates-io.libc.branch="libc-0.2-emscripten"'

- name: before_cache_script
run: rm -rf $CARGO_HOME/registry/index

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ The following targets are supported by `nix`:
<li>x86_64-unknown-openbsd</li>
<li>x86_64-unknown-redox</li>
<li>i686-unknown-hurd-gnu</li>
<li>wasm32-unknown-emscripten</li>
</td>
</tr>
</table>
Expand Down
2 changes: 2 additions & 0 deletions src/sys/ioctl/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use cfg_if::cfg_if;
target_os = "android",
target_os = "fuchsia",
target_os = "cygwin",
target_os = "emscripten",
target_env = "musl",
target_env = "ohos"
))]
Expand All @@ -14,6 +15,7 @@ pub type ioctl_num_type = ::libc::c_int;
target_os = "android",
target_os = "fuchsia",
target_os = "cygwin",
target_os = "emscripten",
target_env = "musl",
target_env = "ohos"
)))]
Expand Down
6 changes: 4 additions & 2 deletions src/sys/ioctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ use cfg_if::cfg_if;
linux_android,
target_os = "fuchsia",
target_os = "redox",
target_os = "cygwin"
target_os = "cygwin",
target_os = "emscripten"
))]
#[macro_use]
mod linux;
Expand All @@ -240,7 +241,8 @@ mod linux;
linux_android,
target_os = "fuchsia",
target_os = "redox",
target_os = "cygwin"
target_os = "cygwin",
target_os = "emscripten"
))]
pub use self::linux::*;

Expand Down
1 change: 1 addition & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ feature! {
target_os = "haiku",
target_os = "redox",
target_os = "cygwin",
target_os = "emscripten",
))]
#[cfg(feature = "ioctl")]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
Expand Down
2 changes: 2 additions & 0 deletions src/sys/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ cfg_if! {
target_os = "aix",
target_os = "illumos",
all(target_os = "linux", not(target_env = "gnu")),
target_os = "emscripten",
target_os = "cygwin"
))]{
use libc::rlimit;
Expand Down Expand Up @@ -53,6 +54,7 @@ libc_enum! {
target_os = "aix",
target_os = "illumos",
all(target_os = "linux", not(any(target_env = "gnu", target_env = "uclibc"))),
target_os = "emscripten",
target_os = "cygwin"
), repr(i32))]
#[non_exhaustive]
Expand Down
14 changes: 11 additions & 3 deletions src/sys/socket/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
solarish,
target_os = "haiku",
target_os = "fuchsia",
target_os = "emscripten",
target_os = "aix",
))]
#[cfg(feature = "net")]
Expand Down Expand Up @@ -448,6 +449,7 @@ impl UnixAddr {
target_os = "fuchsia",
solarish,
target_os = "redox",
target_os = "emscripten",
target_os = "cygwin",
))]
{
Expand Down Expand Up @@ -513,6 +515,7 @@ impl UnixAddr {
target_os = "fuchsia",
solarish,
target_os = "redox",
target_os = "emscripten",
target_os = "cygwin",
))]
{
Expand All @@ -531,6 +534,7 @@ impl SockaddrLike for UnixAddr {
target_os = "fuchsia",
solarish,
target_os = "redox",
target_os = "emscripten",
target_os = "cygwin",
))]
fn len(&self) -> libc::socklen_t {
Expand Down Expand Up @@ -561,6 +565,7 @@ impl SockaddrLike for UnixAddr {
target_os = "fuchsia",
solarish,
target_os = "redox",
target_os = "emscripten",
target_os = "cygwin",
))] {
let su_len = len.unwrap_or(
Expand Down Expand Up @@ -1172,6 +1177,7 @@ impl SockaddrLike for SockaddrStorage {
linux_android,
target_os = "fuchsia",
solarish,
target_os = "emscripten",
target_os = "cygwin",
))]
if i32::from(ss.ss_family) == libc::AF_UNIX {
Expand Down Expand Up @@ -1229,7 +1235,7 @@ impl SockaddrLike for SockaddrStorage {
}
}

#[cfg(any(linux_android, target_os = "fuchsia", solarish, target_os = "cygwin"))]
#[cfg(any(linux_android, target_os = "fuchsia", solarish, target_os = "emscripten", target_os = "cygwin"))]
fn len(&self) -> libc::socklen_t {
match self.as_unix_addr() {
// The UnixAddr type knows its own length
Expand Down Expand Up @@ -1291,6 +1297,7 @@ impl SockaddrStorage {
if #[cfg(any(linux_android,
target_os = "fuchsia",
solarish,
target_os = "emscripten",
target_os = "cygwin",
))]
{
Expand Down Expand Up @@ -1321,6 +1328,7 @@ impl SockaddrStorage {
if #[cfg(any(linux_android,
target_os = "fuchsia",
solarish,
target_os = "emscripten",
target_os = "cygwin",
))]
{
Expand Down Expand Up @@ -1834,7 +1842,7 @@ pub mod sys_control {
}
}

#[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(any(linux_android, target_os = "fuchsia", target_os = "emscripten"))]
mod datalink {
feature! {
#![feature = "net"]
Expand Down Expand Up @@ -2312,7 +2320,7 @@ mod tests {
fn size() {
#[cfg(any(bsd, target_os = "aix", solarish, target_os = "haiku"))]
let l = mem::size_of::<libc::sockaddr_dl>();
#[cfg(any(linux_android, target_os = "fuchsia"))]
#[cfg(any(linux_android, target_os = "fuchsia", target_os = "emscripten"))]
let l = mem::size_of::<libc::sockaddr_ll>();
assert_eq!(LinkAddr::size() as usize, l);
}
Expand Down
2 changes: 1 addition & 1 deletion src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,7 @@ feature! {
/// On some systems, the host name is limited to as few as 64 bytes. An error
/// will be returned if the name is not valid or the current process does not
/// have permissions to update the host name.
#[cfg(not(target_os = "redox"))]
#[cfg(not(any(target_os = "redox", target_os = "emscripten")))]
pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
// Handle some differences in type of the len arg across platforms.
cfg_if! {
Expand Down
1 change: 1 addition & 0 deletions test/sys/test_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use nix::sys::resource::{getrusage, UsageWho};
/// been updated.
#[test]
#[cfg_attr(target_os = "cygwin", ignore)]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_resource_limits_nofile() {
let (mut soft_limit, hard_limit) =
getrlimit(Resource::RLIMIT_NOFILE).unwrap();
Expand Down
11 changes: 8 additions & 3 deletions test/sys/test_signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use nix::errno::Errno;
use nix::sys::signal::*;
use nix::unistd::*;
use std::hash::{Hash, Hasher};
#[cfg_attr(target_os = "emscripten", allow(unused_imports))]
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(target_os = "redox"))]
use std::thread;
Expand All @@ -12,7 +13,7 @@ fn test_kill_none() {
}

#[test]
#[cfg(not(target_os = "fuchsia"))]
#[cfg(not(any(target_os = "fuchsia", target_os = "emscripten")))]
fn test_killpg_none() {
killpg(getpgrp(), None)
.expect("Should be able to send signal to my process group.");
Expand Down Expand Up @@ -79,8 +80,10 @@ fn test_sigprocmask() {
.expect("expect to be able to block signals");
}

#[cfg(not(target_os = "emscripten"))]
static SIGNALED: AtomicBool = AtomicBool::new(false);

#[cfg(not(target_os = "emscripten"))]
extern "C" fn test_sigaction_handler(signal: libc::c_int) {
let signal = Signal::try_from(signal).unwrap();
SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
Expand All @@ -107,6 +110,7 @@ fn test_signal_sigaction() {
}

#[test]
#[cfg(not(target_os = "emscripten"))]
fn test_signal() {
let _m = crate::SIGNAL_MTX.lock();

Expand Down Expand Up @@ -186,7 +190,7 @@ fn test_extend() {
}

#[test]
#[cfg(not(target_os = "redox"))]
#[cfg(not(any(target_os = "redox", target_os = "emscripten")))]
fn test_thread_signal_set_mask() {
thread::spawn(|| {
let prev_mask = SigSet::thread_get_mask()
Expand All @@ -211,7 +215,7 @@ fn test_thread_signal_set_mask() {
}

#[test]
#[cfg(not(target_os = "redox"))]
#[cfg(not(any(target_os = "redox", target_os = "emscripten")))]
fn test_thread_signal_block() {
thread::spawn(|| {
let mut mask = SigSet::empty();
Expand Down Expand Up @@ -242,6 +246,7 @@ fn test_thread_signal_unblock() {

#[test]
#[cfg(not(target_os = "redox"))]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_thread_signal_swap() {
thread::spawn(|| {
let mut mask = SigSet::empty();
Expand Down
10 changes: 9 additions & 1 deletion test/sys/test_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ pub fn test_unnamed_uds_addr() {
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_getsockname() {
use nix::sys::socket::bind;
use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType};
Expand All @@ -308,6 +309,7 @@ pub fn test_getsockname() {
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_socketpair() {
use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
use nix::unistd::{read, write};
Expand All @@ -328,6 +330,7 @@ pub fn test_socketpair() {

#[test]
#[cfg_attr(target_os = "cygwin", ignore)]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_recvmsg_sockaddr_un() {
use nix::sys::socket::{
self, bind, socket, AddressFamily, MsgFlags, SockFlag, SockType,
Expand Down Expand Up @@ -421,6 +424,7 @@ mod recvfrom {
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn stream() {
let (fd2, fd1) = socketpair(
AddressFamily::Unix,
Expand Down Expand Up @@ -843,6 +847,7 @@ pub fn test_recvmsg_ebadf() {
#[cfg_attr(qemu, ignore)]
#[test]
#[cfg_attr(target_os = "cygwin", ignore)]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_scm_rights() {
use nix::sys::socket::{
recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
Expand Down Expand Up @@ -1346,6 +1351,7 @@ pub fn test_sendmsg_ipv4sendsrcaddr() {
#[cfg_attr(qemu, ignore)]
#[test]
#[cfg_attr(target_os = "cygwin", ignore)]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_scm_rights_single_cmsg_multiple_fds() {
use nix::sys::socket::{
recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags,
Expand Down Expand Up @@ -1404,6 +1410,7 @@ fn test_scm_rights_single_cmsg_multiple_fds() {
// msg_control field and a msg_controllen of 0 when calling into the
// raw `sendmsg`.
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
pub fn test_sendmsg_empty_cmsgs() {
use nix::sys::socket::{
recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag,
Expand Down Expand Up @@ -3265,7 +3272,8 @@ fn can_use_cmsg_space() {
linux_android,
target_os = "redox",
target_os = "haiku",
target_os = "cygwin"
target_os = "cygwin",
target_os = "emscripten"
)))]
#[test]
fn can_open_routing_socket() {
Expand Down
1 change: 1 addition & 0 deletions test/sys/test_sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ fn can_get_peerpidfd_on_unix_socket() {
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn is_socket_type_unix() {
use nix::sys::socket::{socketpair, sockopt, SockFlag, SockType};

Expand Down
3 changes: 3 additions & 0 deletions test/sys/test_termios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fn test_baudrate_try_from() {

// Test tcgetattr on a terminal
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_tcgetattr_pty() {
// openpty uses ptname(3) internally
let _m = crate::PTSNAME_MTX.lock();
Expand All @@ -43,6 +44,7 @@ fn test_tcgetattr_enotty() {

// Test modifying output flags
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_output_flags() {
// openpty uses ptname(3) internally
let _m = crate::PTSNAME_MTX.lock();
Expand Down Expand Up @@ -81,6 +83,7 @@ fn test_output_flags() {
// Test modifying local flags
#[test]
#[cfg(not(target_os = "solaris"))]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_local_flags() {
// openpty uses ptname(3) internally
let _m = crate::PTSNAME_MTX.lock();
Expand Down
Loading
Loading