diff options
author | Johnnie Birch <45402135+jlb6740@users.noreply.github.com> | 2019-05-15 22:18:21 -0700 |
---|---|---|
committer | Johnnie Birch <45402135+jlb6740@users.noreply.github.com> | 2019-07-14 14:58:17 -0700 |
commit | 273fb635cc3a97ab09e412e813783469ca436a33 (patch) | |
tree | 8582fb060ac2cac41ea613efbf080520d4a98e1a /src | |
parent | db72b7ea35c8200d79f4af324349fc3b49074079 (diff) | |
download | nix-273fb635cc3a97ab09e412e813783469ca436a33.zip |
Implement unlinkat
This adds the unlinkat function, which is part of POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html
and widely implmented on Unix-family platforms.
Implement unlinkat - Update comments to unlink at and breakup tests
Changes made based on comments from pull request #1058
Implement unlinkat - Update should_panic for more precise check
Updae should_panic attribute for more precise check. Also remove
some dead code and note the pull request ID.
Implement unlinkat - Update error handling to use unwrap_err
The previous patch failed testing on two targets that returned EPERM
as the Sys error instead of EISDIR. This patch changes from using the
should_panic attribute to using the unwrap_err and matching against
the result.
Implement Unlinkat - Passing tests should not print anything. Fix.
Implement unlinkat - Update location of commit comment in the CHANGELOG
Implement unlinkat - Remove newline
Diffstat (limited to 'src')
-rw-r--r-- | src/fcntl.rs | 1 | ||||
-rw-r--r-- | src/unistd.rs | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index 2201873a..d99c2c1a 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -23,6 +23,7 @@ pub use self::posix_fadvise::*; libc_bitflags!{ pub struct AtFlags: c_int { + AT_REMOVEDIR; AT_SYMLINK_NOFOLLOW; #[cfg(any(target_os = "android", target_os = "linux"))] AT_NO_AUTOMOUNT; diff --git a/src/unistd.rs b/src/unistd.rs index 96d8ace7..f422f091 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1144,6 +1144,42 @@ pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> { Errno::result(res).map(drop) } +/// Flags for `unlinkat` function. +#[derive(Clone, Copy, Debug)] +pub enum UnlinkatFlags { + RemoveDir, + NoRemoveDir, +} + +/// Remove a directory entry +/// +/// In the case of a relative path, the directory entry to be removed is determined relative to +/// the directory associated with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. In the case of an absolute `path` `dirfd` is ignored. If `flag` is +/// `UnlinkatFlags::RemoveDir` then removal of the directory entry specified by `dirfd` and `path` +/// is performed. +/// +/// # References +/// See also [unlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html) +pub fn unlinkat<P: ?Sized + NixPath>( + dirfd: Option<RawFd>, + path: &P, + flag: UnlinkatFlags, +) -> Result<()> { + let atflag = + match flag { + UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR, + UnlinkatFlags::NoRemoveDir => AtFlags::empty(), + }; + let res = path.with_nix_path(|cstr| { + unsafe { + libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int) + } + })?; + Errno::result(res).map(drop) +} + + #[inline] pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> { let res = path.with_nix_path(|cstr| { |