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

时间:2015-02-01 12:04:17

标签: 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值?

1 个答案:

答案 0 :(得分:0)

这是一个有效的例子:

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().as_nt_str()。在致电&[u8]之前,您还需要从&str获取as_nt_str(),因为AsNTStr已针对&[u8]实施,但&str未实施*const i8特征。我还将广告素材提取到&[u8]并添加了从&strres的转换。

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

上面的代码为我打印了正确的{{1}}目录。