74 releases

0.9.5 Oct 18, 2024
0.9.3 Aug 25, 2024
0.8.23 Jul 23, 2024
0.8.20 Mar 18, 2024
0.1.0 Jul 26, 2019

#109 in Operating systems

Download history 758/week @ 2024-08-19 584/week @ 2024-08-26 609/week @ 2024-09-02 1015/week @ 2024-09-09 597/week @ 2024-09-16 868/week @ 2024-09-23 583/week @ 2024-09-30 990/week @ 2024-10-07 944/week @ 2024-10-14 657/week @ 2024-10-21 1005/week @ 2024-10-28 898/week @ 2024-11-04 1183/week @ 2024-11-11 1312/week @ 2024-11-18 483/week @ 2024-11-25 1496/week @ 2024-12-02

4,540 downloads per month
Used in 6 crates (3 directly)

Apache-2.0

5.5MB
74K SLoC

nc

Build status Latest version Documentation Minimum rustc version License

Access system calls directly without std or libc.

Features:

  • No glibc or musl required
  • Access syscalls directly, via assembly
  • No global errno variable, every function returns an errno instead
  • Support latest kernel APIs, like io-uring and pidfd, introduced in linux 5.0+

Usage

Add this to Cargo.toml:

[dependencies]
nc = "0.9"

Examples

Get file stat:

let mut statbuf = nc::stat_t::default();
match unsafe { nc::stat("/etc/passwd", &mut statbuf) } {
    Ok(_) => println!("s: {:?}", statbuf),
    Err(errno) => eprintln!("Failed to get file status, got errno: {}", errno),
}

Get human-readable error string:

let errno = nc::EPERM;
println!("err: {:?}", nc::strerror(errno);

Fork process:

let pid = unsafe { nc::fork() };
match pid {
    Err(errno) => eprintln!("Failed to call fork(), err: {}", nc::strerror(errno)),
    Ok(0) => {
        // Child process
        println!("[child] pid: {}", unsafe { nc::getpid() });
        let args = ["ls", "-l", "-a"];
        let env = ["DISPLAY=wayland"];
        let ret = unsafe { nc::execve("/bin/ls", &args, &env) };
        assert!(ret.is_ok());
    }
    Ok(child_pid) => {
        // Parent process
        println!("[main] child pid is: {child_pid}");
    }
}

Kill self:

let pid = unsafe { nc::getpid() };
let ret = unsafe { nc::kill(pid, nc::SIGTERM) };
// Never reach here.
println!("ret: {:?}", ret);

Or handle signals:

fn handle_alarm(signum: i32) {
    assert_eq!(signum, nc::SIGALRM);
}

fn main() {
    let sa = nc::sigaction_t {
        sa_handler: handle_alarm as nc::sighandler_t,
        #[cfg(not(nc_has_sa_restorer))]
        sa_flags: nc::SA_RESTART,
        #[cfg(nc_has_sa_restorer)]
        sa_flags: nc::SA_RESTART | nc::SA_RESTORER,
        #[cfg(nc_has_sa_restorer)]
        sa_restorer: nc::restore::get_sa_restorer(),
        ..nc::sigaction_t::default()
    };
    let ret = unsafe { nc::rt_sigaction(nc::SIGALRM, Some(&sa), None) };
    assert!(ret.is_ok());
    let remaining = unsafe { nc::alarm(1) };
    let mask = nc::sigset_t::default();
    let ret = unsafe { nc::rt_sigsuspend(&mask) };
    assert!(ret.is_err());
    assert_eq!(ret, Err(nc::EINTR));
    assert_eq!(remaining, Ok(0));
}

Supported Operating Systems and Architectures

  • linux
    • aarch64
    • arm
    • loongarch64
    • mips
    • mips64
    • mips64el
    • mipsel
    • powerpc64
    • powerpc64el
    • riscv64
    • s390x
    • x86
    • x86-64
  • android
    • aarch64
  • freebsd
    • x86-64
  • netbsd
    • x86-64
  • mac os
    • x86-64

License

This library is govered by Apache-2.0 License.

No runtime deps