如何在Rust中检查文件是否具有某种模式?

时间:2018-04-26 13:58:55

标签: rust file-permissions

我希望这可行:

use std::fs::OpenOptions;
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};

const MODE: u32 = 0o700;

fn main() {
    let f = OpenOptions::new()
        .write(true)
        .create_new(true)
        .mode(MODE)
        .open("myfile")
        .unwrap();
    let f_mode = f.metadata().unwrap().permissions().mode();
    assert_eq!(f_mode, MODE);
}

跑步时,我得到:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `33216`,
 right: `448`', src/main.rs:14:5

如果我检查ls的输出:

$ ls -al myfile 
-rwx------  1 edd  edd  0 Apr 26 14:50 myfile

显然,一旦提交到文件系统,模式字段中就会编码一些其他信息。

除了在八进制表示的基础上使用按位运算符(掩盖不相关的部分)之外,还有一种检查文件是否为-rwx------的好方法吗?

1 个答案:

答案 0 :(得分:2)

如果要使用特定于操作系统的权限的低级原语,则需要处理这些详细信息:

#define S_IFMT   0170000  /* type of file */
#define S_IFIFO  0010000  /* named pipe (fifo) */
#define S_IFCHR  0020000  /* character special */
#define S_IFDIR  0040000  /* directory */
#define S_IFBLK  0060000  /* block special */
#define S_IFREG  0100000  /* regular */
#define S_IFLNK  0120000  /* symbolic link */
#define S_IFSOCK 0140000  /* socket */
#define S_IFWHT  0160000  /* whiteout */
#define S_ISUID  0004000  /* set user id on execution */
#define S_ISGID  0002000  /* set group id on execution */
#define S_ISVTX  0001000  /* save swapped text even after use */
#define S_IRUSR  0000400  /* read permission, owner */
#define S_IWUSR  0000200  /* write permission, owner */
#define S_IXUSR  0000100  /* execute/search permission, owner */

当您获得该模式时,您还可以获得有关该文件类型的信息。在这里,您有S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR

按位进行AND是最简单的修复:

assert_eq!(f_mode & 0o777, MODE);

当然,您可以在扩展特征中创建自己的访问器函数并实现它们具有良好的含义,或者可能有一个已经完成的包。