简体   繁体   中英

How do I check if a file has a certain mode in Rust?

I'd expect this to work:

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);
}

When run, I get:

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

If I check the output of ls :

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

Clearly there's some other information encoded in the mode field once it gets committed to the file-system.

Is there a good way to check if the file is -rwx------ besides using bitwise operators on underlying the octal representation (masking off the irrelevant parts)?

If you are going to use the low-level primitives of OS-specific permissions, you need to deal with those details:

#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 */

When you get the mode, you also get information on what kind of file it is. Here, you have S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR .

Doing a bitwise AND is the simplest fix:

assert_eq!(f_mode & 0o777, MODE);

Of course, you can create your own accessor functions in an extension trait and implement them to have nice meaning, or there may be a crate which has already done so.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM