mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
chmod: handle -octal and -[rwx]
The main issue is that -octal or -[rwx] is interpreted as an option by getopts. Search the args for such a pattern, remove it before parsing and manually handle it afterwards. Fixes #788.
This commit is contained in:
parent
9005ae7dbf
commit
2686ea75d7
2 changed files with 35 additions and 7 deletions
|
@ -29,7 +29,7 @@ use walker::Walker;
|
|||
const NAME: &'static str = "chmod";
|
||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
pub fn uumain(args: Vec<String>) -> i32 {
|
||||
pub fn uumain(mut args: Vec<String>) -> i32 {
|
||||
let mut opts = Options::new();
|
||||
opts.optflag("c", "changes", "like verbose but report only when a change is made (unimplemented)");
|
||||
opts.optflag("f", "quiet", "suppress most error messages (unimplemented)"); // TODO: support --silent
|
||||
|
@ -40,7 +40,27 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
opts.optflag("R", "recursive", "change files and directories recursively");
|
||||
opts.optflag("h", "help", "display this help and exit");
|
||||
opts.optflag("V", "version", "output version information and exit");
|
||||
// TODO: sanitize input for - at beginning (e.g. chmod -x testfile). Solution is to add a to -x, making a-x
|
||||
// sanitize input for - at beginning (e.g. chmod -x testfile). Remove
|
||||
// the option and save it for later, after parsing is finished.
|
||||
let mut negative_option = None;
|
||||
for i in 0..args.len() {
|
||||
if let Some(first) = args[i].chars().nth(0) {
|
||||
if first != '-' {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(second) = args[i].chars().nth(1) {
|
||||
match second {
|
||||
'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0' ... '7' => {
|
||||
negative_option = Some(args.remove(i));
|
||||
break;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut matches = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(f) => { crash!(1, "{}", f) }
|
||||
|
@ -86,7 +106,13 @@ Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.",
|
|||
});
|
||||
let cmode =
|
||||
if fmode.is_none() {
|
||||
// If there was a negative option, now it's a good time to
|
||||
// use it.
|
||||
if negative_option.is_some() {
|
||||
negative_option
|
||||
} else {
|
||||
Some(matches.free.remove(0))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -59,10 +59,9 @@ fn test_chmod_octal() {
|
|||
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},
|
||||
// Known failues: #788
|
||||
// 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},
|
||||
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},
|
||||
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},
|
||||
|
@ -77,6 +76,9 @@ fn test_chmod_ugoa() {
|
|||
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!{"-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},
|
||||
};
|
||||
run_tests(tests);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue