diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 35078d296be..2860be64956 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -64,7 +64,10 @@ fn get_mode(matches: &ArgMatches, mode_had_minus_prefix: bool) -> Result Ok(DEFAULT_PERM), + None => { + // If no mode argument is specified return the mode derived from umask + Ok(!mode::get_umask() & 0o0777) + } } } @@ -115,7 +118,7 @@ pub fn uu_app<'a>() -> Command<'a> { .short('m') .long(options::MODE) .help("set file mode (not implemented on windows)") - .default_value("755"), + .takes_value(true), ) .arg( Arg::new(options::PARENTS) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 675ca6bea41..be7a95af2e7 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -1,6 +1,10 @@ use crate::common::util::*; #[cfg(not(windows))] use std::os::unix::fs::PermissionsExt; +#[cfg(not(windows))] +extern crate libc; +#[cfg(not(windows))] +use self::libc::{mode_t, umask}; static TEST_DIR1: &str = "mkdir_test1"; static TEST_DIR2: &str = "mkdir_test2"; @@ -13,6 +17,8 @@ static TEST_DIR8: &str = "mkdir_test8/mkdir_test8_1/mkdir_test8_2"; static TEST_DIR9: &str = "mkdir_test9/../mkdir_test9_1/../mkdir_test9_2"; static TEST_DIR10: &str = "mkdir_test10/."; static TEST_DIR11: &str = "mkdir_test11/.."; +#[cfg(not(windows))] +static TEST_DIR12: &str = "mkdir_test12"; #[test] fn test_mkdir_mkdir() { @@ -151,3 +157,26 @@ fn test_mkdir_trailing_dot() { let result = scene2.cmd("ls").arg("-al").run(); println!("ls dest {}", result.stdout_str()); } + +#[test] +#[cfg(not(windows))] +fn test_umask_compliance() { + fn test_single_case(umask_set: mode_t) { + let (at, mut ucmd) = at_and_ucmd!(); + + let original_umask = unsafe { umask(umask_set) }; + + ucmd.arg(TEST_DIR12).succeeds(); + let perms = at.metadata(TEST_DIR12).permissions().mode() as mode_t; + + assert_eq!(perms, (!umask_set & 0o0777) + 0o40000); // before compare, add the set GUID, UID bits + unsafe { + umask(original_umask); + } // set umask back to original + } + + for i in 0o0..0o027 { + // tests all permission combinations + test_single_case(i as mode_t); + } +} diff --git a/tests/by-util/test_pwd.rs b/tests/by-util/test_pwd.rs index bc08ddbb0df..950a148a306 100644 --- a/tests/by-util/test_pwd.rs +++ b/tests/by-util/test_pwd.rs @@ -26,7 +26,7 @@ fn test_deleted_dir() { let output = Command::new("sh") .arg("-c") .arg(format!( - "cd '{}'; mkdir foo; cd foo; rmdir ../foo; exec {} {}", + "cd '{}'; mkdir foo; cd foo; rmdir ../foo; exec '{}' {}", at.root_dir_resolved(), ts.bin_path.to_str().unwrap(), ts.util_name,