-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support
opcode::RenameAt
(#289)
Signed-off-by: lzzzt <liuzitao0123@gmail.com>
- Loading branch information
Showing
5 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use std::{ffi::CString, path::Path}; | ||
|
||
use super::{Op, OpAble}; | ||
use crate::driver::util::cstr; | ||
|
||
pub(crate) struct Rename { | ||
from: CString, | ||
to: CString, | ||
} | ||
|
||
impl Op<Rename> { | ||
pub(crate) fn rename(from: &Path, to: &Path) -> std::io::Result<Self> { | ||
let from = cstr(from)?; | ||
let to = cstr(to)?; | ||
|
||
Op::submit_with(Rename { from, to }) | ||
} | ||
} | ||
|
||
impl OpAble for Rename { | ||
#[cfg(all(target_os = "linux", feature = "iouring"))] | ||
fn uring_op(&mut self) -> io_uring::squeue::Entry { | ||
use io_uring::{opcode::RenameAt, types}; | ||
use libc::AT_FDCWD; | ||
|
||
RenameAt::new( | ||
types::Fd(AT_FDCWD), | ||
self.from.as_ptr(), | ||
types::Fd(AT_FDCWD), | ||
self.to.as_ptr(), | ||
) | ||
.build() | ||
} | ||
|
||
fn legacy_interest(&self) -> Option<(crate::driver::ready::Direction, usize)> { | ||
None | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), unix))] | ||
fn legacy_call(&mut self) -> std::io::Result<u32> { | ||
use crate::syscall_u32; | ||
|
||
syscall_u32!(renameat( | ||
libc::AT_FDCWD, | ||
self.from.as_ptr(), | ||
libc::AT_FDCWD, | ||
self.to.as_ptr() | ||
)) | ||
} | ||
|
||
#[cfg(all(any(feature = "legacy", feature = "poll-io"), windows))] | ||
fn legacy_call(&mut self) -> io::Result<u32> { | ||
unimplemented!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#![cfg(all(unix, feature = "renameat"))] | ||
|
||
use std::{fs::Permissions, os::unix::fs::PermissionsExt}; | ||
|
||
#[monoio::test_all] | ||
async fn rename_file_in_the_same_directory() { | ||
let temp_dir = tempfile::tempdir().unwrap(); | ||
let file = tempfile::NamedTempFile::new_in(temp_dir.path()).unwrap(); | ||
|
||
let old_file_path = file.path(); | ||
let new_file_path = temp_dir.path().join("test-file"); | ||
|
||
let result = monoio::fs::rename(old_file_path, &new_file_path).await; | ||
assert!(result.is_ok()); | ||
|
||
assert!(new_file_path.exists()); | ||
assert!(!old_file_path.exists()); | ||
} | ||
|
||
#[monoio::test_all] | ||
async fn rename_file_in_different_directory() { | ||
let temp_dir1 = tempfile::tempdir().unwrap(); | ||
let temp_dir2 = tempfile::tempdir().unwrap(); | ||
let file = tempfile::NamedTempFile::new_in(temp_dir1.path()).unwrap(); | ||
|
||
let old_file_path = file.path(); | ||
let new_file_path = temp_dir2.path().join("test-file"); | ||
|
||
let result = monoio::fs::rename(old_file_path, &new_file_path).await; | ||
assert!(result.is_ok()); | ||
|
||
assert!(new_file_path.exists()); | ||
assert!(!old_file_path.exists()); | ||
} | ||
|
||
#[monoio::test_all] | ||
async fn mv_file_in_different_directory() { | ||
let temp_dir1 = tempfile::tempdir().unwrap(); | ||
let temp_dir2 = tempfile::tempdir().unwrap(); | ||
let file = tempfile::NamedTempFile::new_in(temp_dir1.path()).unwrap(); | ||
|
||
let old_file_path = file.path(); | ||
let old_file_name = old_file_path.file_name().unwrap(); | ||
let new_file_path = temp_dir2.path().join(old_file_name); | ||
|
||
let result = monoio::fs::rename(old_file_path, &new_file_path).await; | ||
assert!(result.is_ok()); | ||
|
||
assert!(new_file_path.exists()); | ||
assert!(!old_file_path.exists()); | ||
} | ||
|
||
#[monoio::test_all] | ||
async fn rename_inexist_file() { | ||
let temp_dir = tempfile::tempdir().unwrap(); | ||
|
||
let old_file_path = temp_dir.path().join("inexist.txt"); | ||
let new_file_path = temp_dir.path().join("renamed.txt"); | ||
|
||
let result = monoio::fs::rename(old_file_path, new_file_path).await; | ||
|
||
assert!(result.is_err()); | ||
} | ||
|
||
#[monoio::test_all] | ||
async fn rename_file_without_permission() { | ||
let temp_dir = tempfile::tempdir().unwrap(); | ||
let temp_file = tempfile::NamedTempFile::new_in(&temp_dir).unwrap(); | ||
|
||
std::fs::set_permissions(temp_dir.path(), Permissions::from_mode(0o0)).unwrap(); | ||
|
||
let old_file_path = temp_file.path(); | ||
let new_file_path = temp_dir.path().join("test-file"); | ||
|
||
let result = monoio::fs::rename(old_file_path, &new_file_path).await; | ||
|
||
assert!(result.is_err()); | ||
} |