Skip to content

Commit 2f78ec2

Browse files
bors[bot]asomers
andauthored
Merge #1242
1242: Don't implement `NixPath` for `Option<&P> where P: NixPath` r=asomers a=asomers Most Nix functions that accept `NixPath` arguments can't do anything useful with `None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly optional arguments. Also, this changes the behavior of `mount` with `None` arguments. Previously, it would call mount(2) with empty strings for those arguments. Now, it will use null pointers. Co-authored-by: Alan Somers <asomers@gmail.com>
2 parents 2ae94eb + 9d8c8c9 commit 2f78ec2

File tree

4 files changed

+33
-33
lines changed

4 files changed

+33
-33
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5959
- Removed `sys::socket::addr::from_libc_sockaddr` from the public API.
6060
(#[1215](https://github.com/nix-rust/nix/pull/1215))
6161

62+
- Nix no longer implements `NixPath` for `Option<P> where P: NixPath`. Most
63+
Nix functions that accept `NixPath` arguments can't do anything useful with
64+
`None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly
65+
optional arguments.
66+
(#[1242](https://github.com/nix-rust/nix/pull/1242))
67+
6268
## [0.17.0] - 3 February 2020
6369
### Added
6470
- Add `CLK_TCK` to `SysconfVar`

src/lib.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -283,22 +283,3 @@ impl NixPath for PathBuf {
283283
self.as_os_str().with_nix_path(f)
284284
}
285285
}
286-
287-
/// Treats `None` as an empty string.
288-
impl<'a, NP: ?Sized + NixPath> NixPath for Option<&'a NP> {
289-
fn is_empty(&self) -> bool {
290-
self.map_or(true, NixPath::is_empty)
291-
}
292-
293-
fn len(&self) -> usize {
294-
self.map_or(0, NixPath::len)
295-
}
296-
297-
fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
298-
if let Some(nix_path) = *self {
299-
nix_path.with_nix_path(f)
300-
} else {
301-
unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) }
302-
}
303-
}
304-
}

src/mount.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,33 @@ pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P
6161
flags: MsFlags,
6262
data: Option<&P4>) -> Result<()> {
6363

64-
let res =
65-
source.with_nix_path(|source| {
66-
target.with_nix_path(|target| {
67-
fstype.with_nix_path(|fstype| {
68-
data.with_nix_path(|data| {
69-
unsafe {
70-
libc::mount(source.as_ptr(),
71-
target.as_ptr(),
72-
fstype.as_ptr(),
73-
flags.bits,
74-
data.as_ptr() as *const libc::c_void)
75-
}
76-
})
64+
fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
65+
where P: ?Sized + NixPath,
66+
F: FnOnce(*const libc::c_char) -> T
67+
{
68+
match p {
69+
Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
70+
None => Ok(f(std::ptr::null()))
71+
}
72+
}
73+
74+
let res = with_opt_nix_path(source, |s| {
75+
target.with_nix_path(|t| {
76+
with_opt_nix_path(fstype, |ty| {
77+
with_opt_nix_path(data, |d| {
78+
unsafe {
79+
libc::mount(
80+
s,
81+
t.as_ptr(),
82+
ty,
83+
flags.bits,
84+
d as *const libc::c_void
85+
)
86+
}
7787
})
7888
})
79-
})????;
89+
})
90+
})????;
8091

8192
Errno::result(res).map(drop)
8293
}

src/sys/quota.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ pub fn quotactl_off<P: ?Sized + NixPath>(which: QuotaType, special: &P) -> Resul
253253
}
254254

255255
/// Update the on-disk copy of quota usages for a filesystem.
256+
///
257+
/// If `special` is `None`, then all file systems with active quotas are sync'd.
256258
pub fn quotactl_sync<P: ?Sized + NixPath>(which: QuotaType, special: Option<&P>) -> Result<()> {
257259
quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut())
258260
}

0 commit comments

Comments
 (0)