diff --git a/src/unistd.rs b/src/unistd.rs index 908e9b94bb..f422f09198 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1154,8 +1154,10 @@ pub enum UnlinkatFlags { /// 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. If flag is UnlinkatFlags::RemoveDir -/// then remove the directory entry specified by dirfd and path is performed. +/// 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) diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 39a9b7d403..04161b9a29 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -579,16 +579,12 @@ fn test_symlinkat() { #[test] -fn test_unlinkat() { +#[should_panic] +fn test_unlinkat_dir_noremovedir() { let tempdir = tempfile::tempdir().unwrap(); - let filename = "foo.txt"; let dirname = "foo_dir"; - let filepath = tempdir.path().join(filename); let dirpath = tempdir.path().join(dirname); - // Create file - File::create(&filepath).unwrap(); - // Create dir DirBuilder::new().recursive(true).create(&dirpath).unwrap(); @@ -596,20 +592,45 @@ fn test_unlinkat() { let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); // Attempt unlink dir at relative path without proper flag - panic::set_hook(Box::new(|_info| {})); - let result = std::panic::catch_unwind(|| unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap()); - assert!(result.is_err()); + unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap(); assert!(dirpath.exists()); + } + +#[test] +fn test_unlinkat_dir_removedir() { + let tempdir = tempfile::tempdir().unwrap(); + let dirname = "foo_dir"; + let dirpath = tempdir.path().join(dirname); + + // Create dir + DirBuilder::new().recursive(true).create(&dirpath).unwrap(); + + // Get file descriptor for base directory + let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); // Attempt unlink dir at relative path with proper flag unlinkat(Some(dirfd), dirname, UnlinkatFlags::RemoveDir).unwrap(); assert!(!dirpath.exists()); + } + +#[test] +fn test_unlinkat_file() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = "foo.txt"; + let filepath = tempdir.path().join(filename); + + // Create file + File::create(&filepath).unwrap(); + + // Get file descriptor for base directory + let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); // Attempt unlink file at relative path unlinkat(Some(dirfd), filename, UnlinkatFlags::NoRemoveDir).unwrap(); assert!(!filepath.exists()); } + #[test] fn test_access_not_existing() { let tempdir = tempfile::tempdir().unwrap();