在 Rust 里调用 Linux 系统 API(也就是 Linux 的 syscall / libc 函数),常见有几种方式,从底层到高层依次是:
Linux 的 API 大多在 libc 里,Rust 通过 libc crate 调用。
[dependencies]
libc = "0.2"
getpid()use libc::getpid;
fn main() {
let pid = unsafe { getpid() };
println!("PID = {}", pid);
}
⚠️ 所有 libc 调用都是
unsafe的
如果你想绕过 libc,直接进内核(比如写玩具 OS、安全研究):
libc::syscalluse libc::{syscall, SYS_getpid};
fn main() {
let pid = unsafe { syscall(SYS_getpid) };
println!("PID = {}", pid);
}
或者更原始(x86_64):
unsafe fn syscall0(n: u64) -> u64 {
let ret: u64;
core::arch::asm!(
"syscall",
in("rax") n,
lateout("rax") ret,
options(nomemory, nostack)
);
ret
}
nix 是对 libc 的安全封装,少写 unsafe。
[dependencies]
nix = "0.27"
use nix::unistd::getpid;
fn main() {
println!("PID = {}", getpid());
}
use std::fs::File;
use std::os::unix::io::AsRawFd;
use nix::fcntl::{open, OFlag};
use nix::sys::stat::Mode;
fn main() {
let fd = open("/etc/hostname", OFlag::O_RDONLY, Mode::empty()).unwrap();
println!("fd = {}", fd);
}
| Linux API | Rust 方式 |
|---|---|
| fork / exec | nix::unistd |
| socket | nix::sys::socket |
| epoll | mio / epoll crate |
| mmap | nix::sys::mman |
| ptrace | nix::sys::ptrace |
| ioctl | nix / ioctl macro |
use libc::{c_char, getcwd};
fn main() {
let mut buf = [0 as c_char; 256];
unsafe {
getcwd(buf.as_mut_ptr(), buf.len());
}
let cwd = std::ffi::CStr::from_ptr(buf.as_ptr());
println!("cwd = {:?}", cwd);
}
如果你有具体想调用的 Linux API(比如 epoll、fork、io_uring、ptrace),我可以给你完整示例。