Implement renameat, renameat2

Like the other "at" functions, renameat renames files with respect with
a directory descriptor. "renameat2" is Linux specific but really nice -
it adds a flag which supports atomically swapping two files or failing
if the target already exists. The latter is easily supported in relibc.
The former requires redoxfs support.

Besides the impl itself, I refactored "cap_path_at" into what it really
is: a mini openat2-like function.
This commit is contained in:
Josh Megnauth
2025-10-03 22:09:55 -04:00
parent 56386f1e26
commit f5d432644f
12 changed files with 401 additions and 31 deletions
+33
View File
@@ -686,6 +686,39 @@ impl Pal for Sys {
.map(|_| ())
}
fn renameat(old_dir: c_int, old_path: CStr, new_dir: c_int, new_path: CStr) -> Result<()> {
e_raw(unsafe {
syscall!(
RENAMEAT,
old_dir,
old_path.as_ptr(),
new_dir,
new_path.as_ptr()
)
})
.map(|_| ())
}
fn renameat2(
old_dir: c_int,
old_path: CStr,
new_dir: c_int,
new_path: CStr,
flags: c_uint,
) -> Result<()> {
e_raw(unsafe {
syscall!(
RENAMEAT2,
old_dir,
old_path.as_ptr(),
new_dir,
new_path.as_ptr(),
flags
)
})
.map(|_| ())
}
fn rmdir(path: CStr) -> Result<()> {
e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), AT_REMOVEDIR) }).map(|_| ())
}