Skip to content

Commit a152687

Browse files
authored
Merge pull request #6971 from sylvestre/mkfifo
mkfifo: better handle the mode + umask
2 parents 609eee6 + 31ffc3a commit a152687

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

src/uu/mkfifo/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ path = "src/mkfifo.rs"
1919
[dependencies]
2020
clap = { workspace = true }
2121
libc = { workspace = true }
22-
uucore = { workspace = true }
22+
uucore = { workspace = true, features = ["fs"] }
2323

2424
[[bin]]
2525
name = "mkfifo"

src/uu/mkfifo/src/mkfifo.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use clap::{crate_version, Arg, ArgAction, Command};
77
use libc::mkfifo;
88
use std::ffi::CString;
9+
use std::fs;
10+
use std::os::unix::fs::PermissionsExt;
911
use uucore::display::Quotable;
1012
use uucore::error::{UResult, USimpleError};
1113
use uucore::{format_usage, help_about, help_usage, show};
@@ -32,11 +34,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
3234
}
3335

3436
let mode = match matches.get_one::<String>(options::MODE) {
37+
// if mode is passed, ignore umask
3538
Some(m) => match usize::from_str_radix(m, 8) {
3639
Ok(m) => m,
3740
Err(e) => return Err(USimpleError::new(1, format!("invalid mode: {e}"))),
3841
},
39-
None => 0o666,
42+
// Default value + umask if present
43+
None => 0o666 & !(uucore::mode::get_umask() as usize),
4044
};
4145

4246
let fifos: Vec<String> = match matches.get_many::<String>(options::FIFO) {
@@ -47,12 +51,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
4751
for f in fifos {
4852
let err = unsafe {
4953
let name = CString::new(f.as_bytes()).unwrap();
50-
mkfifo(name.as_ptr(), mode as libc::mode_t)
54+
mkfifo(name.as_ptr(), 0o666)
5155
};
5256
if err == -1 {
5357
show!(USimpleError::new(
5458
1,
55-
format!("cannot create fifo {}: File exists", f.quote())
59+
format!("cannot create fifo {}: File exists", f.quote()),
60+
));
61+
}
62+
63+
// Explicitly set the permissions to ignore umask
64+
if let Err(e) = fs::set_permissions(&f, fs::Permissions::from_mode(mode as u32)) {
65+
return Err(USimpleError::new(
66+
1,
67+
format!("cannot set permissions on {}: {}", f.quote(), e),
5668
));
5769
}
5870
}
@@ -71,7 +83,6 @@ pub fn uu_app() -> Command {
7183
.short('m')
7284
.long(options::MODE)
7385
.help("file permissions for the fifo")
74-
.default_value("0666")
7586
.value_name("MODE"),
7687
)
7788
.arg(

tests/by-util/test_mkfifo.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,50 @@ fn test_create_one_fifo_already_exists() {
5252
.fails()
5353
.stderr_is("mkfifo: cannot create fifo 'abcdef': File exists\n");
5454
}
55+
56+
#[test]
57+
fn test_create_fifo_with_mode_and_umask() {
58+
use uucore::fs::display_permissions;
59+
let scene = TestScenario::new(util_name!());
60+
let at = &scene.fixtures;
61+
62+
let test_fifo_creation = |mode: &str, umask: u16, expected: &str| {
63+
scene
64+
.ucmd()
65+
.arg("-m")
66+
.arg(mode)
67+
.arg(format!("fifo_test_{mode}"))
68+
.umask(libc::mode_t::from(umask))
69+
.succeeds();
70+
71+
let metadata = std::fs::metadata(at.subdir.join(format!("fifo_test_{mode}"))).unwrap();
72+
let permissions = display_permissions(&metadata, true);
73+
assert_eq!(permissions, expected.to_string());
74+
};
75+
76+
test_fifo_creation("734", 0o077, "prwx-wxr--"); // spell-checker:disable-line
77+
test_fifo_creation("706", 0o777, "prwx---rw-"); // spell-checker:disable-line
78+
}
79+
80+
#[test]
81+
fn test_create_fifo_with_umask() {
82+
use uucore::fs::display_permissions;
83+
let scene = TestScenario::new(util_name!());
84+
let at = &scene.fixtures;
85+
86+
let test_fifo_creation = |umask: u16, expected: &str| {
87+
scene
88+
.ucmd()
89+
.arg("fifo_test")
90+
.umask(libc::mode_t::from(umask))
91+
.succeeds();
92+
93+
let metadata = std::fs::metadata(at.subdir.join("fifo_test")).unwrap();
94+
let permissions = display_permissions(&metadata, true);
95+
assert_eq!(permissions, expected.to_string());
96+
at.remove("fifo_test");
97+
};
98+
99+
test_fifo_creation(0o022, "prw-r--r--"); // spell-checker:disable-line
100+
test_fifo_creation(0o777, "p---------"); // spell-checker:disable-line
101+
}

0 commit comments

Comments
 (0)