posix - 从 posix::pwd::getpwnam_r 中提取 pw_dir

标签 posix rust ffi

尝试读取 Rust fn 中任意用户的主目录,并使用 posix::pwd crate。

不幸的是,我找不到任何使用 FFI 的好例子,并且一直在处理关于指针和类型可变性的各种类型错误。

我的(非编译)示例代码在这里:

let uname = "root";
let mut pwbuf = [0u8;4096];
let mut res : usize = 0;
let mut pwd = posix::pwd::passwd::new();
posix::pwd::getpwnam_r(uname.as_nt_str(), &mut pwd, &mut pwbuf, &mut res);
let hd = unsafe{ ffi::c_str_to_bytes(&pwd.pw_dir as &*const i8) };
if res == 0 {
    println!("root home dir is {}", hd);
} else {
    println!("getpwnam_r error {}", res);
}

有人有一些示例代码可以将 homedir 提取到 &str 值中吗?

最佳答案

这是一个工作示例:

extern crate posix;

use std::ffi;
use std::str;

use posix::AsNTStr;

fn main() {
    let uname = "root";

    let mut pwbuf = [0u8; 4096];
    let mut res: usize = 0;
    let mut pwd = posix::pwd::passwd::new();
    let rv = posix::pwd::getpwnam_r(&uname.as_bytes().as_nt_str(), &mut pwd, &mut pwbuf, &mut res);

    let p = pwd.pw_dir as *const _;
    let hd = unsafe{ ffi::c_str_to_bytes(&p) };
    let hd_str = str::from_utf8(hd).unwrap();
    if rv == 0 {
        println!("root home dir is {}", hd_str);
    } else {
        println!("getpwnam_r error {}", res);
    }
}

首先,我修复了几个与类型相关的错误。例如,getpwnam_r 期望引用实现NTStr 特征的内容,因此在uname.as_bytes() 之前有一个&。作为_nt_str()。您还需要在调用 as_nt_str() 之前从 &str 获取 &[u8] 因为 AsNTStr 特性是为&[u8] 但不适用于 &str。我还将转换提取到 *const i8 并添加了从 &[u8]&str 的转换。

其次,res 参数不是您应该检查错误的值。我不确定为什么 posix 的作者选择将其表示为 usize,但 res 实际上是指向结果 的指针>passwd结构。您可以在 man getpwnam_r 手册页中找到它。您需要检查 getpwnam_r 调用的实际返回值以确定是否发生任何错误。

上面的代码为我打印了正确的 /root 目录。

关于posix - 从 posix::pwd::getpwnam_r 中提取 pw_dir,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28262485/

相关文章:

c++ - 尼姆 FFI : Using existing type to wrap a C++ type

java - 如何在 Eclipse 中使用 JPL(swi-prolog 的 java prolog 接口(interface))?

c - 返回字符串指针

posix - 自适应 AUTOSAR 基于什么 POSIX PSE51?

c - 为什么 POSIX 将 wctomb 指定为非线程安全的,而不是 mbtowc?

rust - 为什么 println! f32 和 f64 打印不同的输出?

c - Kill() 错误 : no such process?

macros - 生成具有由宏确定的参数的函数的宏

rust - 如何将 collect() 的结果限制为一定数量的项目?

rust - 我需要任何 *variantType 标记吗?