diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65a19a7..0ea14a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,3 +102,21 @@ jobs: - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - run: cargo hack build --rust-version + target-compatibility: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [nightly] + target: + - aarch64-unknown-nto-qnx800 + - x86_64-pc-nto-qnx800 + steps: + - uses: actions/checkout@v4 + - name: Install Rust + run: | + rustup update ${{ matrix.rust }} --no-self-update + rustup default ${{ matrix.rust }} + rustup component add rust-src --toolchain nightly + - name: Cargo check + run: cargo +nightly check -Zbuild-std --target ${{ matrix.target }} diff --git a/src/unix.rs b/src/unix.rs index 66d8356..7fc16bd 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -4,8 +4,26 @@ use std::ffi::OsStr; use std::io; use std::os::unix::process::CommandExt as _; +use cfg_if::cfg_if; + use crate::Command; +cfg_if! { + if #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita"))] { + type UserId = u16; + type GroupId = u16; + } else if #[cfg(target_os = "nto")] { + // Both IDs are signed, see `sys/target_nto.h` of the QNX Neutrino SDP. + // Only positive values should be used, see e.g. + // https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/s/setuid.html + type UserId = i32; + type GroupId = i32; + } else { + type UserId = u32; + type GroupId = u32; + } +} + /// Unix-specific extensions to the [`Command`] builder. /// /// This trait is sealed: it cannot be implemented outside `async-process`. @@ -14,11 +32,11 @@ pub trait CommandExt: crate::sealed::Sealed { /// Sets the child process's user ID. This translates to a /// `setuid` call in the child process. Failure in the `setuid` /// call will cause the spawn to fail. - fn uid(&mut self, id: u32) -> &mut Command; + fn uid(&mut self, id: UserId) -> &mut Command; /// Similar to `uid`, but sets the group ID of the child process. This has /// the same semantics as the `uid` field. - fn gid(&mut self, id: u32) -> &mut Command; + fn gid(&mut self, id: GroupId) -> &mut Command; /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -60,12 +78,12 @@ pub trait CommandExt: crate::sealed::Sealed { impl crate::sealed::Sealed for Command {} impl CommandExt for Command { - fn uid(&mut self, id: u32) -> &mut Command { + fn uid(&mut self, id: UserId) -> &mut Command { self.inner.uid(id); self } - fn gid(&mut self, id: u32) -> &mut Command { + fn gid(&mut self, id: GroupId) -> &mut Command { self.inner.gid(id); self }