summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohnnie Birch <45402135+jlb6740@users.noreply.github.com>2019-05-15 22:18:21 -0700
committerJohnnie Birch <45402135+jlb6740@users.noreply.github.com>2019-07-14 14:58:17 -0700
commit273fb635cc3a97ab09e412e813783469ca436a33 (patch)
tree8582fb060ac2cac41ea613efbf080520d4a98e1a /src
parentdb72b7ea35c8200d79f4af324349fc3b49074079 (diff)
downloadnix-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.rs1
-rw-r--r--src/unistd.rs36
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| {