2016-01-04 15:58:49 +00:00
|
|
|
use common::util::*;
|
2016-05-22 07:46:54 +00:00
|
|
|
use std::fs::{metadata, OpenOptions, set_permissions};
|
|
|
|
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
2016-01-04 15:58:49 +00:00
|
|
|
|
2016-06-19 14:52:56 +00:00
|
|
|
extern crate libc;
|
|
|
|
use self::libc::umask;
|
|
|
|
|
2016-01-04 15:58:49 +00:00
|
|
|
static UTIL_NAME: &'static str = "chmod";
|
2016-07-29 21:26:32 +00:00
|
|
|
fn at_and_ucmd() -> (AtPath, UCommand) {
|
|
|
|
let ts = TestScenario::new(UTIL_NAME);
|
|
|
|
let ucmd = ts.ucmd();
|
|
|
|
(ts.fixtures, ucmd)
|
|
|
|
}
|
|
|
|
|
2016-01-04 15:58:49 +00:00
|
|
|
static TEST_FILE: &'static str = "file";
|
2016-03-10 19:34:49 +00:00
|
|
|
static REFERENCE_FILE: &'static str = "reference";
|
2016-05-22 07:46:54 +00:00
|
|
|
static REFERENCE_PERMS: u32 = 0o247;
|
2016-01-04 15:58:49 +00:00
|
|
|
|
|
|
|
struct TestCase {
|
|
|
|
args: Vec<&'static str>,
|
2016-05-22 07:46:54 +00:00
|
|
|
before: u32,
|
|
|
|
after: u32
|
2016-01-04 15:58:49 +00:00
|
|
|
}
|
|
|
|
|
2016-05-22 07:46:54 +00:00
|
|
|
fn mkfile(file: &str, mode: u32) {
|
|
|
|
OpenOptions::new().mode(mode).create(true).write(true).open(file).unwrap();
|
|
|
|
let mut perms = metadata(file).unwrap().permissions();
|
2016-01-04 15:58:49 +00:00
|
|
|
perms.set_mode(mode);
|
2016-05-22 07:46:54 +00:00
|
|
|
set_permissions(file, perms).unwrap();
|
2016-01-04 15:58:49 +00:00
|
|
|
}
|
|
|
|
|
2016-03-11 18:35:03 +00:00
|
|
|
fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) {
|
2016-01-04 15:58:49 +00:00
|
|
|
mkfile(&at.plus_as_string(TEST_FILE), test.before);
|
|
|
|
let perms = at.metadata(TEST_FILE).permissions().mode();
|
2016-05-22 07:46:54 +00:00
|
|
|
if perms != test.before {
|
2016-01-04 15:58:49 +00:00
|
|
|
panic!(format!("{}: expected: {:o} got: {:o}", "setting permissions failed", test.after, perms));
|
|
|
|
}
|
|
|
|
|
2016-03-11 18:35:03 +00:00
|
|
|
for arg in &test.args {
|
2016-01-04 15:58:49 +00:00
|
|
|
ucmd.arg(arg);
|
|
|
|
}
|
|
|
|
let r = ucmd.run();
|
|
|
|
if !r.success {
|
|
|
|
println!("{}", r.stderr);
|
|
|
|
panic!(format!("{:?}: failed", ucmd.raw));
|
|
|
|
}
|
|
|
|
|
|
|
|
let perms = at.metadata(TEST_FILE).permissions().mode();
|
|
|
|
if perms != test.after {
|
|
|
|
panic!(format!("{:?}: expected: {:o} got: {:o}", ucmd.raw, test.after, perms));
|
|
|
|
}
|
2016-03-11 18:35:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn run_tests(tests: Vec<TestCase>) {
|
|
|
|
for test in tests {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, ucmd) = at_and_ucmd();
|
2016-03-11 18:35:03 +00:00
|
|
|
run_single_test(&test, at, ucmd);
|
2016-01-04 15:58:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_chmod_octal() {
|
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"0700", TEST_FILE}, before: 0o000, after: 0o700},
|
|
|
|
TestCase{args: vec!{"0070", TEST_FILE}, before: 0o000, after: 0o070},
|
|
|
|
TestCase{args: vec!{"0007", TEST_FILE}, before: 0o000, after: 0o007},
|
2016-03-15 13:18:39 +00:00
|
|
|
TestCase{args: vec!{"-0700", TEST_FILE}, before: 0o700, after: 0o000},
|
|
|
|
TestCase{args: vec!{"-0070", TEST_FILE}, before: 0o060, after: 0o000},
|
|
|
|
TestCase{args: vec!{"-0007", TEST_FILE}, before: 0o001, after: 0o000},
|
2016-01-05 03:48:03 +00:00
|
|
|
TestCase{args: vec!{"+0100", TEST_FILE}, before: 0o600, after: 0o700},
|
|
|
|
TestCase{args: vec!{"+0020", TEST_FILE}, before: 0o050, after: 0o070},
|
|
|
|
TestCase{args: vec!{"+0004", TEST_FILE}, before: 0o003, after: 0o007},
|
2016-01-04 15:58:49 +00:00
|
|
|
};
|
|
|
|
run_tests(tests);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_chmod_ugoa() {
|
2016-06-19 14:52:56 +00:00
|
|
|
let last = unsafe {
|
|
|
|
umask(0)
|
|
|
|
};
|
2016-01-04 15:58:49 +00:00
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"u=rwx", TEST_FILE}, before: 0o000, after: 0o700},
|
|
|
|
TestCase{args: vec!{"g=rwx", TEST_FILE}, before: 0o000, after: 0o070},
|
|
|
|
TestCase{args: vec!{"o=rwx", TEST_FILE}, before: 0o000, after: 0o007},
|
|
|
|
TestCase{args: vec!{"a=rwx", TEST_FILE}, before: 0o000, after: 0o777},
|
2016-03-15 13:18:39 +00:00
|
|
|
TestCase{args: vec!{"-r", TEST_FILE}, before: 0o777, after: 0o333},
|
|
|
|
TestCase{args: vec!{"-w", TEST_FILE}, before: 0o777, after: 0o555},
|
|
|
|
TestCase{args: vec!{"-x", TEST_FILE}, before: 0o777, after: 0o666},
|
2016-01-04 15:58:49 +00:00
|
|
|
};
|
|
|
|
run_tests(tests);
|
2016-06-19 14:52:56 +00:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
umask(0o022);
|
|
|
|
}
|
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"u=rwx", TEST_FILE}, before: 0o000, after: 0o700},
|
|
|
|
TestCase{args: vec!{"g=rwx", TEST_FILE}, before: 0o000, after: 0o070},
|
|
|
|
TestCase{args: vec!{"o=rwx", TEST_FILE}, before: 0o000, after: 0o007},
|
|
|
|
TestCase{args: vec!{"a=rwx", TEST_FILE}, before: 0o000, after: 0o777},
|
|
|
|
TestCase{args: vec!{"+rw", TEST_FILE}, before: 0o000, after: 0o644},
|
|
|
|
TestCase{args: vec!{"=rwx", TEST_FILE}, before: 0o000, after: 0o755},
|
|
|
|
TestCase{args: vec!{"-w", TEST_FILE}, before: 0o777, after: 0o577},
|
|
|
|
TestCase{args: vec!{"-x", TEST_FILE}, before: 0o777, after: 0o666},
|
|
|
|
};
|
|
|
|
run_tests(tests);
|
|
|
|
unsafe {
|
|
|
|
umask(last);
|
|
|
|
}
|
2016-01-04 15:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_chmod_ugo_copy() {
|
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"u=g", TEST_FILE}, before: 0o070, after: 0o770},
|
|
|
|
TestCase{args: vec!{"g=o", TEST_FILE}, before: 0o005, after: 0o055},
|
|
|
|
TestCase{args: vec!{"o=u", TEST_FILE}, before: 0o200, after: 0o202},
|
|
|
|
TestCase{args: vec!{"u-g", TEST_FILE}, before: 0o710, after: 0o610},
|
|
|
|
TestCase{args: vec!{"u+g", TEST_FILE}, before: 0o250, after: 0o750},
|
|
|
|
};
|
|
|
|
run_tests(tests);
|
|
|
|
}
|
2016-03-10 19:34:49 +00:00
|
|
|
|
2016-03-15 13:20:11 +00:00
|
|
|
#[test]
|
|
|
|
fn test_chmod_many_options() {
|
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"-r,a+w", TEST_FILE}, before: 0o444, after: 0o222},
|
|
|
|
};
|
|
|
|
run_tests(tests);
|
|
|
|
}
|
|
|
|
|
2016-03-10 19:34:49 +00:00
|
|
|
#[test]
|
|
|
|
fn test_chmod_reference_file() {
|
|
|
|
let tests = vec!{
|
|
|
|
TestCase{args: vec!{"--reference", REFERENCE_FILE, TEST_FILE}, before: 0o070, after: 0o247},
|
2016-03-24 18:01:40 +00:00
|
|
|
TestCase{args: vec!{"a-w", "--reference", REFERENCE_FILE, TEST_FILE}, before: 0o070, after: 0o247},
|
2016-03-10 19:34:49 +00:00
|
|
|
};
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, ucmd) = at_and_ucmd();
|
2016-03-11 18:35:03 +00:00
|
|
|
mkfile(&at.plus_as_string(REFERENCE_FILE), REFERENCE_PERMS);
|
|
|
|
run_single_test(&tests[0], at, ucmd);
|
2016-03-10 19:34:49 +00:00
|
|
|
}
|