首页 > 数据库 > 数据库开发技术 > Rust FFI 编程 - nix crate
在 Rust 中使用 nix 这个库,在某些情况下可以简化 Unix 系统编程。本文主要包括以下内容:
// Re-exported external cratespub extern crate libc;它通过使用强制合法或安全的类型对 libc 库进行了一次封装,相对于 libc 库
暴露的unsafeAPI,它具有两个特点:
unsafegethostname 为例,我们来看一下,libc 和 nix 之间的区别:// libc api (unsafe, requires handling return code/errno)pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int;// nix api (returns a nix::Result<CStr>)pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>;
std::fs::ReadDir更底层的目录接口。getifaddrs获取网络接口及地址列表。mount和umount。unistd.h头文件中函数的 safe 封装。[dependencies]nix = "0.17.0"
use nix::unistd::*;fn main() {match fork() {Ok(ForkResult::Parent { child }) => {// 在父进程中println!("Hello, I am parent thread: {}", getpid());}Ok(ForkResult::Child) => {// 在子进程中println!("Hello, I am child thread: {}", getpid());println!("My parent thread: {}", getppid());}Err(errno) => {// fork 创建子进程失败println!("Fork creation failed!");}}}
fork/kill示例fork()函数可以用来创建一个新的进程(子进程),而kill()函数可以用来向一个或一组进程发送信号。我们来看如下的一段 C 语言代码:int main(void){pid_t child = fork();if (child){sleep(5);kill(child, SIGKILL);}else{for (;;)// 循环直到被 kill 掉;}return 0;}
fork()函数如果执行成功,则向子进程返回 0,并将子进程的进程 ID 返回给父进程。否则,将向父进程返回 -1,不创建子进程,并设置errno来标识错误。fork()函数失败时的逻辑,这样则可能将 -1(fork的错误结果)视为子进程的进程 ID。这时在随后的程序中关闭子进程kill(child, SIGKILL);,你知道进程 ID 为 -1 时会发生什么吗?If pid is -1, sig shall be sent to all processes (excluding an unspecified set of system processes) for which the process has permission to send that signal.
如果进程 ID 等于 -1,则将信号发送到调用进程有权发送信号的每个进程,一些系统进程(如 init)除外。
kill(-1, SIGKILL);等效于 kill 你有权发送信号的所有其他进程。fork()函数,其返回值为Result<ForkResult, Errno>类型,相比 C 语言中的fork()函数,它有两个优点:Result区分成功和失败的情况ForkResult区分返回父/子进程use nix::sys::signal::*;use nix::unistd::*;fn main() {match fork().expect("fork failed") {ForkResult::Parent{ child } => {sleep(5);kill(child, SIGKILL).expect("kill failed");}ForkResult::Child => {// 直到被 kill 掉loop {}}}}
unsafe API 进行封装,为 libc 库支持的某些平台提供了一种 safe 的替代方案。原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。