最近用到了libc这个包,调用其中的statfs
函数,用于查询指定路径挂载的磁盘占用。可以看到
pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
statfs
第二个参数是一个C语言结构体statfs
,其定义如下
pub struct statfs {
pub f_type: ::__fsword_t,
pub f_bsize: ::__fsword_t,
pub f_blocks: ::fsblkcnt_t,
pub f_bfree: ::fsblkcnt_t,
pub f_bavail: ::fsblkcnt_t,
pub f_files: ::fsfilcnt_t,
pub f_ffree: ::fsfilcnt_t,
pub f_fsid: ::fsid_t,
pub f_namelen: ::__fsword_t,
pub f_frsize: ::__fsword_t,
f_spare: [::__fsword_t; 5],
}
如果用常规的rust初始化方法,必须填充结构体的各字段
let x = statfs{
...,
f_spare: ...,
}
可以看到其中f_spare
字段是一个数组,属于复杂类型,用rust的初始化方式,需要一个个字段的填充,而且需要填充为初始值0,将会非常复杂。其实有一种简单方法,使用std::mem::zeroed
函数即可。举例如下
fn statfs(&mut self, mount_path: String) -> String {
let x = CString::new(mount_path.as_bytes()).expect("covert cstring failed");
let mut info = String::from("");
let mut statfs_buf = unsafe { std::mem::zeroed() };
let ret = unsafe { libc::statfs(x.as_ptr(), &mut statfs_buf) };
if ret == 0 {
info = format!(
"{} {} {} {}",
statfs_buf.f_bsize, statfs_buf.f_blocks, statfs_buf.f_bfree, statfs_buf.f_bavail
);
}
return info;
}
可以看到std::mem::zeroed()
方法,直接能够初始化一段0值的内存空间,这段空间具体大小,直接由下一行libc::statfs(...)
调用的第二个参数类型决定,由这一行直接能推导出该申请多大的0空间。