summaryrefslogtreecommitdiff
path: root/src/fcntl.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-07-08 22:11:11 +0000
committerGitHub <noreply@github.com>2021-07-08 22:11:11 +0000
commitd9d447db42a16d7f946177e093b5990fba52561e (patch)
tree2a8b1952cf03ca0dec9235d6640dfb29875ad3e4 /src/fcntl.rs
parent865c7488b8d9d0909b03d8312073976ee6514757 (diff)
parent1a23312c77b74e0e896700733a189f8ecfdcbc1f (diff)
downloadnix-d9d447db42a16d7f946177e093b5990fba52561e.zip
Merge #1458
1458: Added support for renameat2 on linux r=asomers a=tomboland Hi, please find my PR for adding the linux-specific `renameat2` syscall. It's largely similar to `renameat`, with an additional flags parameter: The flags are: * RENAME_REPLACE - performs an atomic swap. * RENAME_NOREPLACE - returns EEXIST if the target already exists. * RENAME_WHITEOUT - specific to overly/union filesystems, and I haven't added a test-case for this one. PLEASE NOTE: It looks like my formatter has made numerous changes. If you have a preferred formatting config then please let me know, and I can push up changes consistent with the accepted style. I'm not all that experienced with rust, and this is my first time looking at the nix project, so I'm more than happy to receive guidance on improving my submission. Cheers! Co-authored-by: Tom Boland <tom@t0mb.net>
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r--src/fcntl.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs
index ec6db00a..f8f1372a 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -210,6 +210,43 @@ pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
Errno::result(res).map(drop)
}
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+))]
+libc_bitflags! {
+ pub struct RenameFlags: u32 {
+ RENAME_EXCHANGE;
+ RENAME_NOREPLACE;
+ RENAME_WHITEOUT;
+ }
+}
+
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+))]
+pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
+ old_dirfd: Option<RawFd>,
+ old_path: &P1,
+ new_dirfd: Option<RawFd>,
+ new_path: &P2,
+ flags: RenameFlags,
+) -> Result<()> {
+ let res = old_path.with_nix_path(|old_cstr| {
+ new_path.with_nix_path(|new_cstr| unsafe {
+ libc::renameat2(
+ at_rawfd(old_dirfd),
+ old_cstr.as_ptr(),
+ at_rawfd(new_dirfd),
+ new_cstr.as_ptr(),
+ flags.bits(),
+ )
+ })
+ })??;
+ Errno::result(res).map(drop)
+}
+
fn wrap_readlink_result(mut v: Vec<u8>, len: ssize_t) -> Result<OsString> {
unsafe { v.set_len(len as usize) }
v.shrink_to_fit();