Skip to content

Commit

Permalink
Merge #1097
Browse files Browse the repository at this point in the history
1097: Add renameat, AT_FDCWD r=asomers a=scottlamb



Co-authored-by: Scott Lamb <slamb@slamb.org>
  • Loading branch information
bors[bot] and scottlamb committed Jul 18, 2019
2 parents 500036a + 6454a06 commit 38de042
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -19,6 +19,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#1091](https://github.com/nix-rust/nix/pull/1091))
- Add `unlinkat`
([#1058](https://github.com/nix-rust/nix/pull/1058))
- Add `renameat`.
([#1097](https://github.com/nix-rust/nix/pull/1097))

### Changed
- Support for `ifaddrs` now present when building for Android.
Expand Down
12 changes: 12 additions & 0 deletions src/fcntl.rs
Expand Up @@ -165,6 +165,18 @@ pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: M
Errno::result(fd)
}

pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(old_dirfd: Option<RawFd>, old_path: &P1,
new_dirfd: Option<RawFd>, new_path: &P2)
-> Result<()> {
let res = old_path.with_nix_path(|old_cstr| {
new_path.with_nix_path(|new_cstr| unsafe {
libc::renameat(at_rawfd(old_dirfd), old_cstr.as_ptr(),
at_rawfd(new_dirfd), new_cstr.as_ptr())
})
})??;
Errno::result(res).map(drop)
}

fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> {
match Errno::result(res) {
Err(err) => Err(err),
Expand Down
21 changes: 20 additions & 1 deletion test/test_fcntl.rs
@@ -1,7 +1,10 @@
use nix::fcntl::{openat, open, OFlag, readlink, readlinkat};
use nix::Error;
use nix::errno::*;
use nix::fcntl::{openat, open, OFlag, readlink, readlinkat, renameat};
use nix::sys::stat::Mode;
use nix::unistd::{close, read};
use tempfile::{self, NamedTempFile};
use std::fs::File;
use std::io::prelude::*;
use std::os::unix::fs;

Expand All @@ -27,6 +30,22 @@ fn test_openat() {
close(dirfd).unwrap();
}

#[test]
fn test_renameat() {
let old_dir = tempfile::tempdir().unwrap();
let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
let old_path = old_dir.path().join("old");
File::create(&old_path).unwrap();
let new_dir = tempfile::tempdir().unwrap();
let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap();
assert_eq!(renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(),
Error::Sys(Errno::ENOENT));
close(old_dirfd).unwrap();
close(new_dirfd).unwrap();
assert!(new_dir.path().join("new").exists());
}

#[test]
fn test_readlink() {
let tempdir = tempfile::tempdir().unwrap();
Expand Down

0 comments on commit 38de042

Please sign in to comment.