Skip to content

Commit 0ab0f1d

Browse files
committed
fix: PseudoNs fallback subtleties
1 parent 30af57e commit 0ab0f1d

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

src/os/unix/uds_local_socket.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,10 @@ fn dispatch_name<T>(
6161
NameInner::UdSocketPseudoNs(name) => {
6262
let name = name.as_bytes();
6363
write_run_user(&mut addr, name)?;
64-
let addrt = addr.write_terminator();
65-
match create(addrt) {
66-
Err(e) if listen_fail_is_benign(&e) => {
67-
if is_listener {
68-
let path = Path::new(OsStr::from_bytes(addrt.inner().path()));
69-
if let Some(p) = path.parent() {
70-
if !p.as_os_str().is_empty() {
71-
if let Ok(ok) =
72-
std::fs::create_dir_all(p).and_then(|()| create(addrt))
73-
{
74-
return Ok(ok);
75-
}
76-
}
77-
}
78-
}
64+
match with_missing_dir_creation(is_listener, addr.write_terminator(), &mut create) {
65+
Err(e) if fail_is_benign(&e) => {
7966
write_prefixed(&mut addr, TMPDIR, name)?;
80-
create(addr.write_terminator())
67+
with_missing_dir_creation(is_listener, addr.write_terminator(), &mut create)
8168
}
8269
otherwise => otherwise,
8370
}
@@ -91,6 +78,29 @@ fn dispatch_name<T>(
9178
}
9279
}
9380

81+
fn with_missing_dir_creation<T>(
82+
create: bool,
83+
addr: TerminatedUdAddr<'_>,
84+
mut f: impl FnMut(TerminatedUdAddr<'_>) -> io::Result<T>,
85+
) -> io::Result<T> {
86+
match f(addr) {
87+
Err(e) if create && fail_is_benign(&e) && create_missing_dirs(addr) => f(addr),
88+
otherwise => otherwise,
89+
}
90+
}
91+
92+
fn create_missing_dirs(addr: TerminatedUdAddr<'_>) -> bool {
93+
let path = Path::new(OsStr::from_bytes(addr.inner().path()));
94+
if let Some(p) = path.parent() {
95+
if !p.as_os_str().is_empty() {
96+
if let Ok(()) = std::fs::create_dir_all(p) {
97+
return true;
98+
}
99+
}
100+
}
101+
false
102+
}
103+
94104
#[allow(clippy::as_conversions)]
95105
const MAX_RUN_USER: usize = "/run/user//".len() + uid_t::MAX.ilog10() as usize + 1;
96106
const RUN_USER_BUF: usize = MAX_RUN_USER + 1;
@@ -156,7 +166,7 @@ fn escape_nuls(b: &mut [u8]) {
156166
b.iter_mut().filter(|c| **c == 0).for_each(|c| *c = b'_');
157167
}
158168

159-
fn listen_fail_is_benign(e: &io::Error) -> bool {
169+
fn fail_is_benign(e: &io::Error) -> bool {
160170
use io::ErrorKind::*;
161171
matches!(e.kind(), NotFound | Unsupported) || e.raw_os_error() == Some(libc::ENOTDIR)
162172
}

0 commit comments

Comments
 (0)