Как проверить, есть ли у файла определенный режим в Rust? - PullRequest
0 голосов
/ 26 апреля 2018

Я ожидаю, что это сработает:

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

Очевидно, что есть некоторая другая информация, закодированная в поле mode, когда она передается в файловую систему.

Есть ли хороший способ проверить, является ли файл -rwx------, кроме использования побитовых операторов в восьмеричном представлении (маскируя ненужные части)?

1 Ответ

0 голосов
/ 26 апреля 2018

Если вы собираетесь использовать низкоуровневые примитивы разрешений для конкретной ОС, вам нужно разобраться с этими деталями:

#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.

Выполнение побитового И - самое простое исправление:

assert_eq!(f_mode & 0o777, MODE);

Конечно, вы можете создавать свои собственные функции доступа в расширении и реализовывать их, чтобы они имели приятный смысл, или может быть ящик, который уже сделал это.

...