xushaohua / nc Goto Github PK
View Code? Open in Web Editor NEWRun *nix system calls directly in Rust
License: Apache License 2.0
Run *nix system calls directly in Rust
License: Apache License 2.0
I note that the *statfs64 functions are missing for some architectures, and the docs look wrong referring to 'stat63', and st_mode, which would relate to a stat not a statfs.
Version: 0.8.20
Steps to reproduce:
$ uname -ar
Linux shrimp-paste 6.8.9-300.fc40.ppc64le #1 SMP Thu May 2 18:35:21 UTC 2024 ppc64le GNU/Linux (Fedora 40)
$ rustc --version
rustc 1.77.0 (aedd173a2 2024-03-17)
$ cargo build --release
Updating crates.io index
Downloaded cc v1.0.98
Downloaded 1 crate (76.8 KB) in 0.15s
Compiling cc v1.0.98
Compiling nc v0.8.20 (/home/tle/Work/nc)
error[E0412]: cannot find type `ucontext_t` in this scope
--> src/platform/linux-ppc64/call.rs:7103:41
|
7103 | pub unsafe fn swapcontext(old_ctx: &mut ucontext_t, ctx: &ucontext_t) -> Result<(), Errno> {
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `ucontext_t` in this scope
--> src/platform/linux-ppc64/call.rs:7103:59
|
7103 | pub unsafe fn swapcontext(old_ctx: &mut ucontext_t, ctx: &ucontext_t) -> Result<(), Errno> {
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `ucontext_t` in this scope
--> src/platform/linux-ppc64/call.rs:7104:39
|
7104 | let old_ctx_ptr = old_ctx as *mut ucontext_t as usize;
| ^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `ucontext_t` in this scope
--> src/platform/linux-ppc64/call.rs:7105:33
|
7105 | let ctx_ptr = ctx as *const ucontext_t as usize;
| ^^^^^^^^^^ not found in this scope
For more information about this error, try `rustc --explain E0412`.
error: could not compile `nc` (lib) due to 4 previous errors
I've just ran make
in the ci
folder while on 094c8c7 and was greeted with this:
$ make
cross build --target aarch64-unknown-linux-gnu
info: downloading component 'rust-std' for 'aarch64-unknown-linux-gnu'
info: installing component 'rust-std' for 'aarch64-unknown-linux-gnu'
32.3 MiB / 32.3 MiB (100 %) 15.1 MiB/s in 2s ETA: 0s
Unable to find image 'ghcr.io/cross-rs/aarch64-unknown-linux-gnu:0.2.5' locally
0.2.5: Pulling from cross-rs/aarch64-unknown-linux-gnu
58690f9b18fc: Pull complete
b51569e7c507: Pull complete
da8ef40b9eca: Pull complete
fb15d46c38dc: Pull complete
9d5962c83f5f: Pull complete
9cccf86b8f43: Pull complete
4c6d73517e75: Pull complete
4afe128e6862: Pull complete
2765f54cfdee: Pull complete
40c841a9d0e8: Pull complete
70c492706cd4: Pull complete
b376264cc3c9: Pull complete
f94a42110e99: Pull complete
29835156cc05: Pull complete
d48b139772fe: Pull complete
55ba4d0a0c25: Pull complete
5f4fa2c62d4d: Pull complete
6bc43a1e4611: Pull complete
Digest: sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
Status: Downloaded newer image for ghcr.io/cross-rs/aarch64-unknown-linux-gnu:0.2.5
Compiling libc v0.2.148
Compiling cc v1.0.83
Compiling nc v0.8.17 (/project)
error: ambiguous glob re-exports
--> src/platform/linux-types/mod.rs:14:9
|
14 | pub use arch::*;
| ^^^^^^^ the name `MINSIGSTKSZ` in the value namespace is first re-exported here
...
66 | pub use uapi::*;
| ------- but the name `MINSIGSTKSZ` in the value namespace is also re-exported here
|
note: the lint level is defined here
--> src/lib.rs:126:5
|
126 | warnings,
| ^^^^^^^^
= note: `#[deny(ambiguous_glob_reexports)]` implied by `#[deny(warnings)]`
error: ambiguous glob re-exports
--> src/platform/linux-types/mod.rs:14:9
|
14 | pub use arch::*;
| ^^^^^^^ the name `SIGSTKSZ` in the value namespace is first re-exported here
...
66 | pub use uapi::*;
| ------- but the name `SIGSTKSZ` in the value namespace is also re-exported here
error: could not compile `nc` (lib) due to 2 previous errors
make: *** [Makefile:16: cross-aarch64] Error 101
I've also tried to test for the mips
target (as that is what I am actually using) but there it fails with a ton of errors about my rustup setup.
youki-static-armv7l-unknown-linux-musleabihf> error: failed to run custom build command for `nc v0.8.18`
youki-static-armv7l-unknown-linux-musleabihf> Caused by:
youki-static-armv7l-unknown-linux-musleabihf> process didn't exit successfully: `/build/source/target/release/build/nc-178a23c026e3da3b/build-script-build` (exit status: 101)
youki-static-armv7l-unknown-linux-musleabihf> --- stdout
youki-static-armv7l-unknown-linux-musleabihf> TARGET = Some("armv7-unknown-linux-musleabihf")
youki-static-armv7l-unknown-linux-musleabihf> OPT_LEVEL = Some("3")
youki-static-armv7l-unknown-linux-musleabihf> HOST = Some("x86_64-unknown-linux-gnu")
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CC_armv7-unknown-linux-musleabihf
youki-static-armv7l-unknown-linux-musleabihf> CC_armv7-unknown-linux-musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CC_armv7_unknown_linux_musleabihf
youki-static-armv7l-unknown-linux-musleabihf> CC_armv7_unknown_linux_musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=TARGET_CC
youki-static-armv7l-unknown-linux-musleabihf> TARGET_CC = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CC
youki-static-armv7l-unknown-linux-musleabihf> CC = Some("armv7l-unknown-linux-musleabihf-gcc")
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
youki-static-armv7l-unknown-linux-musleabihf> CRATE_CC_NO_DEFAULTS = None
youki-static-armv7l-unknown-linux-musleabihf> DEBUG = Some("false")
youki-static-armv7l-unknown-linux-musleabihf> CARGO_CFG_TARGET_FEATURE = Some("crt-static")
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CFLAGS_armv7-unknown-linux-musleabihf
youki-static-armv7l-unknown-linux-musleabihf> CFLAGS_armv7-unknown-linux-musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CFLAGS_armv7_unknown_linux_musleabihf
youki-static-armv7l-unknown-linux-musleabihf> CFLAGS_armv7_unknown_linux_musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=TARGET_CFLAGS
youki-static-armv7l-unknown-linux-musleabihf> TARGET_CFLAGS = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=CFLAGS
youki-static-armv7l-unknown-linux-musleabihf> CFLAGS = None
youki-static-armv7l-unknown-linux-musleabihf> running: "armv7l-unknown-linux-musleabihf-gcc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-static" "-march=armv7-a" "-mfpu=vfpv3-d16" "-Wall" "-Wextra" "-o" "/build/source/target/armv7-unknown-linux-musleabihf/release/build/nc-620b6e8a187d501c/out/src/syscalls/syscall_arm.o" "-c" "src/syscalls/syscall_arm.c"
youki-static-armv7l-unknown-linux-musleabihf> exit status: 0
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=AR_armv7-unknown-linux-musleabihf
youki-static-armv7l-unknown-linux-musleabihf> AR_armv7-unknown-linux-musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=AR_armv7_unknown_linux_musleabihf
youki-static-armv7l-unknown-linux-musleabihf> AR_armv7_unknown_linux_musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=TARGET_AR
youki-static-armv7l-unknown-linux-musleabihf> TARGET_AR = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=AR
youki-static-armv7l-unknown-linux-musleabihf> AR = Some("armv7l-unknown-linux-musleabihf-ar")
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=ARFLAGS_armv7-unknown-linux-musleabihf
youki-static-armv7l-unknown-linux-musleabihf> ARFLAGS_armv7-unknown-linux-musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=ARFLAGS_armv7_unknown_linux_musleabihf
youki-static-armv7l-unknown-linux-musleabihf> ARFLAGS_armv7_unknown_linux_musleabihf = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=TARGET_ARFLAGS
youki-static-armv7l-unknown-linux-musleabihf> TARGET_ARFLAGS = None
youki-static-armv7l-unknown-linux-musleabihf> cargo:rerun-if-env-changed=ARFLAGS
youki-static-armv7l-unknown-linux-musleabihf> ARFLAGS = None
youki-static-armv7l-unknown-linux-musleabihf> running: ZERO_AR_DATE="1" "armv7l-unknown-linux-musleabihf-ar" "cq" "/build/source/target/armv7-unknown-linux-musleabihf/release/build/nc-620b6e8a187d501c/out/libsyscall.a" "/build/source/target/armv7-unknown-linux-musleabihf/release/build/nc-620b6e8a187d501c/out/src/syscalls/syscall_arm.o"
youki-static-armv7l-unknown-linux-musleabihf> exit status: 0
youki-static-armv7l-unknown-linux-musleabihf> running: "armv7l-unknown-linux-musleabihf-ar" "s" "/build/source/target/armv7-unknown-linux-musleabihf/release/build/nc-620b6e8a187d501c/out/libsyscall.a"
youki-static-armv7l-unknown-linux-musleabihf> exit status: 0
youki-static-armv7l-unknown-linux-musleabihf> cargo:rustc-link-lib=static=syscall
youki-static-armv7l-unknown-linux-musleabihf> cargo:rustc-link-search=native=/build/source/target/armv7-unknown-linux-musleabihf/release/build/nc-620b6e8a187d501c/out
youki-static-armv7l-unknown-linux-musleabihf> --- stderr
youki-static-armv7l-unknown-linux-musleabihf> thread 'main' panicked at /build/youki-0.3.2-vendor.tar.gz/nc/build.rs:20:10:
youki-static-armv7l-unknown-linux-musleabihf> Failed to run getconf: Os { code: 2, kind: NotFound, message: "No such file or directory" }
youki-static-armv7l-unknown-linux-musleabihf> note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
The example shown on the README didn't pass any args:
let pid = unsafe { nc::fork() };
match pid {
Ok(pid) => {
if pid == 0 {
println!("child process: {}", pid);
let args = [""];
let env = [""];
match unsafe { nc::execve("/bin/ls", &args, &env) } {
Ok(_) => {},
Err(errno) => eprintln!("`ls` got err: {}", errno),
}
} else if pid < 0 {
eprintln!("fork() error!");
} else {
println!("parent process!");
}
},
Err(errno) => eprintln!("errno: {}", errno),
}
If we did, the syscall will fail with EFAULT:
$ cat src/main.rs
fn main() {
let cmd = "/usr/bin/echo";
let args = ["hello"];
let env = [""];
match unsafe { nc::execve(cmd, &args, &env) } {
Ok(_) => {},
Err(errno) => eprintln!("`{}` got err: {}", cmd, errno),
}
}
dell ~/src/nc-test ⑂master* $ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/nc-test`
`/usr/bin/echo` got err: 14
Looking at strace I don't immediately see a fix.
execve("/usr/bin/echo", ["hello", 0x6, "", 0x1, "`` got err: \n/home/fam/.cargo/re"...], 0x7ffecc544af8 /* 1 var */) = -1 EFAULT (Bad address)
llvm_asm
has been removed in rust-lang/rust#92816 and the crate no longer compiles with the latest nightly.
I've modified a little the original example in order to make sure. The handle_sigterm
function doesn't seem to be called ever. I've also tried other signals like SIGWINCH and other flags, and nothing changes. Tested on Linux 5.15 and 6.1, x86_64.
use std::{mem::size_of, thread::sleep, time::Duration};
fn handle_sigterm(sig: i32) {
assert_eq!(sig, nc::SIGINT);
println!("received sigint");
unsafe {
nc::exit(2);
}
}
fn main() {
let sa = nc::sigaction_t {
sa_handler: handle_sigterm as nc::sighandler_t,
sa_mask: (nc::SA_RESTART | nc::SA_SIGINFO | nc::SA_ONSTACK).into(),
..nc::sigaction_t::default()
};
let mut old_sa = nc::sigaction_t::default();
let ret = unsafe { nc::rt_sigaction(nc::SIGINT, &sa, &mut old_sa, size_of::<nc::sigset_t>()) };
// NOTE: when setting the handler, this doesn't kill the program
// but if sending the signal again (e.g. with CTRL+C) it segfaults,
// and the handler doesn't seem to ever run...
let ret = unsafe { nc::kill(nc::getpid(), nc::SIGINT) };
assert!(ret.is_ok());
sleep(Duration::from_secs(2));
}
For example, on x86_64:
nc/src/platform/linux-x86_64/call.rs
Lines 22 to 26 in 00ab8d9
From the manpage:
RETURN VALUE
Upon successful completion, accept() shall return the non-negative file descriptor of the accepted socket. Otherwise, -1 shall be returned, errno shall be set to indicate the error, and any object pointed to by address_len shall remain unchanged.
Virtually none of these APIs are safe to call. It is possible to trigger segfaults with many of them if they're used incorrectly.
It seems that the kernel uses a different value when defining constants for platforms such as arm
.
For example, for the value of O_NOFOLLOW
:
When compile for arm target, 0100000
is used:
https://elixir.bootlin.com/linux/latest/source/arch/arm/include/uapi/asm/fcntl.h#L6
#define O_NOFOLLOW 0100000
However for some "generic" architectures, O_NOFOLLOW
is defined as 00400000
.
https://elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/fcntl.h#L56
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 00400000 /* don't follow links */
#endif
nc
does not appear to be dealing with such a situation at this time.
nc/src/platform/linux-types/fcntl.rs
Line 31 in 767c815
This is a field you need to be able to read/write to use poll
.
nc/src/platform/linux-types/uapi/asm_generic/poll.rs
Lines 31 to 37 in ac659c6
On 00ab8d9:
$ rg 'fn fork'
src/platform/netbsd-x86_64/call.rs
673:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/netbsd-x86/call.rs
6:pub fn fork() {
src/platform/linux-x86_64/call.rs
1381:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-x86/call.rs
1429:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-mips/call.rs
1418:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-mips64/call.rs
1382:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-ppc64/call.rs
1387:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-s390x/call.rs
1375:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/freebsd-x86/call.rs
11:pub fn fork() {
src/platform/freebsd-x86_64/call.rs
678:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/darwin-x86_64/call.rs
621:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/platform/linux-arm/call.rs
1359:pub unsafe fn fork() -> Result<pid_t, Errno> {
src/calls/fork.rs
11:pub unsafe fn fork() -> Result<pid_t, Errno> {
I also note that it looks like functions aren't consistently marked unsafe.
Hi, having issues building nc with --target=i686-unknown-linux-gnu, tried building youki and ran in to this error, cloned nc itself and built, and reproduced the same build error, default target builds fine. Am I missing something?
nc on main is 📦 v0.8.19 via 🦀 v1.75.0
❯ cargo build --target=i686-unknown-linux-gnu
Compiling nc v0.8.19 (/home/kha/src/rust/nc)
error: invalid register `ebp`: the frame pointer cannot be used as an operand for inline asm
--> src/syscalls/syscall_x86.rs:120:10
|
120 | in("ebp") a6,
| ^^^^^^^^^^^^
error: cannot use register `si`: esi is used internally by LLVM and cannot be used as an operand for inline asm
--> src/syscalls/syscall_x86.rs:73:10
|
73 | in("esi") a4,
| ^^^^^^^^^^^^
error: cannot use register `si`: esi is used internally by LLVM and cannot be used as an operand for inline asm
--> src/syscalls/syscall_x86.rs:94:10
|
94 | in("esi") a4,
| ^^^^^^^^^^^^
error: cannot use register `si`: esi is used internally by LLVM and cannot be used as an operand for inline asm
--> src/syscalls/syscall_x86.rs:118:10
|
118 | in("esi") a4,
|
Here:
https://docs.rs/nc/latest/nc/index.html
It still says
[dependencies]
nc = "0.7"
while the latest release is 0.8.
Hi, I'm trying to use one of the syscalls but I'm having trouble because of the type of the arguments.
pub fn get_resource_hard_limit(pid: Pid) -> usize {
let mut old_limit: nc::rlimit_t = default_rlimit_t();
let new_limit: nc::rlimit_t = default_rlimit_t();
match nc::prlimit64(pid as nc::pid_t, nc::RLIMIT_RTTIME, &new_limit, &mut old_limit) {
Ok(_) => { println!("ok") },
Err(_) => { println!("err") },
}
return old_limit.rlim_max;
}
The signature for this syscall is:
prlimit64(
pid: pid_t,
resource: i32,
new_limit: &rlimit_t,
old_limit: &mut rlimit_t,
)
This syscall can both set and get resource limits of a process, depending on which argument is a NULL. Here, to get the limits &new_limit
would need to be NULL, but because these calls don't accept raw pointers I have no idea how to pass a NULL pointer as argument. Is there a workaround for this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.