Skip to content

Commit 8a94ea8

Browse files
committed
revert back to raw libc syscalls
1 parent 8ec6cd2 commit 8a94ea8

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/mv/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ windows-sys = { workspace = true, features = [
4040

4141
[target.'cfg(unix)'.dependencies]
4242
libc = { workspace = true }
43-
nix = { workspace = true, features = ["fs"] }
4443

4544
[[bin]]
4645
name = "mv"

src/uu/mv/src/mv.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -356,37 +356,56 @@ fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode {
356356
/// Atomically exchange two files using renameat2 with `RENAME_EXCHANGE`
357357
#[cfg(target_os = "linux")]
358358
fn exchange_files(path1: &Path, path2: &Path, opts: &Options) -> UResult<()> {
359-
use nix::fcntl::{AT_FDCWD, RenameFlags, renameat2};
359+
use std::ffi::CString;
360+
use std::os::unix::ffi::OsStrExt;
361+
362+
// Convert paths to C strings
363+
let c_path1 = CString::new(path1.as_os_str().as_bytes()).unwrap();
364+
let c_path2 = CString::new(path2.as_os_str().as_bytes()).unwrap();
365+
366+
// RENAME_EXCHANGE flag for renameat2
367+
const RENAME_EXCHANGE: libc::c_int = 2;
360368

361369
// Use renameat2 to atomically exchange the files
362-
match renameat2(
363-
AT_FDCWD,
364-
path1,
365-
AT_FDCWD,
366-
path2,
367-
RenameFlags::RENAME_EXCHANGE,
368-
) {
369-
Ok(()) => {
370-
if opts.verbose {
371-
println!("exchanged '{}' <-> '{}'", path1.display(), path2.display());
372-
}
373-
Ok(())
370+
let result = unsafe {
371+
libc::syscall(
372+
libc::SYS_renameat2,
373+
libc::AT_FDCWD,
374+
c_path1.as_ptr(),
375+
libc::AT_FDCWD,
376+
c_path2.as_ptr(),
377+
RENAME_EXCHANGE,
378+
)
379+
};
380+
381+
if result == 0 {
382+
if opts.verbose {
383+
println!("exchanged '{}' <-> '{}'", path1.display(), path2.display());
374384
}
375-
Err(err) => match err {
376-
nix::Error::ENOTSUP | nix::Error::EINVAL => Err(USimpleError::new(
385+
Ok(())
386+
} else {
387+
let errno = unsafe { *libc::__errno_location() };
388+
match errno {
389+
libc::ENOTSUP | libc::EINVAL => Err(USimpleError::new(
377390
1,
378391
translate!("--exchange is not supported on this filesystem"),
379392
)),
380-
nix::Error::ENOENT => {
393+
libc::ENOENT => {
381394
let missing_path = if path1.exists() { path2 } else { path1 };
382395
Err(MvError::NoSuchFile(missing_path.display().to_string()).into())
383396
}
384-
nix::Error::EXDEV => Err(USimpleError::new(
397+
libc::EXDEV => Err(USimpleError::new(
385398
1,
386399
translate!("--exchange cannot exchange files across different filesystems"),
387400
)),
388-
_ => Err(USimpleError::new(1, format!("exchange failed: {err}"))),
389-
},
401+
_ => {
402+
let error_msg = io::Error::from_raw_os_error(errno);
403+
Err(USimpleError::new(
404+
1,
405+
format!("exchange failed: {error_msg}"),
406+
))
407+
}
408+
}
390409
}
391410
}
392411

0 commit comments

Comments
 (0)