add unlinkat(2), symlinkat(2), linkat(2) and expose openat(2)

`linkat(2)` doesn't have `AT_EMPTY_PATH` as a valid flag in this
implementation because it isn't POSIX. We have it (and have
support for it), but it is more effort to add it. If we need it at some
point, it can be added in about 3 lines.

`openat(2)` previously wasn't exposed, and William was not aware of
`Sys::openat`'s existence. We use it under the hood for `mkfifoat(2)`
and friends, so expose it as a libc API. This helps to pass more os-test tests.

Lastly, the 3 implemented syscalls here help pass some os-test tests.
This commit is contained in:
Connor-GH
2026-04-20 10:58:25 -05:00
parent aa8d1386a9
commit 0ff79b80a2
6 changed files with 116 additions and 18 deletions
+16 -13
View File
@@ -487,17 +487,12 @@ impl Pal for Sys {
}
fn link(path1: CStr, path2: CStr) -> Result<()> {
e_raw(unsafe {
syscall!(
LINKAT,
AT_FDCWD,
path1.as_ptr(),
AT_FDCWD,
path2.as_ptr(),
0
)
})
.map(|_| ())
Sys::linkat(AT_FDCWD, path1, AT_FDCWD, path2, 0)
}
fn linkat(fd1: c_int, path1: CStr, fd2: c_int, path2: CStr, flags: c_int) -> Result<()> {
e_raw(unsafe { syscall!(LINKAT, fd1, path1.as_ptr(), fd2, path2.as_ptr(), flags) })
.map(|_| ())
}
fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> Result<off_t> {
@@ -817,7 +812,11 @@ impl Pal for Sys {
}
fn symlink(path1: CStr, path2: CStr) -> Result<()> {
e_raw(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }).map(|_| ())
Sys::symlinkat(path1, AT_FDCWD, path2)
}
fn symlinkat(path1: CStr, fd: c_int, path2: CStr) -> Result<()> {
e_raw(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), fd, path2.as_ptr()) }).map(|_| ())
}
fn sync() -> Result<()> {
@@ -874,7 +873,11 @@ impl Pal for Sys {
}
fn unlink(path: CStr) -> Result<()> {
e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }).map(|_| ())
Sys::unlinkat(AT_FDCWD, path, 0)
}
fn unlinkat(fd: c_int, path: CStr, flags: c_int) -> Result<()> {
e_raw(unsafe { syscall!(UNLINKAT, fd, path.as_ptr(), flags) }).map(|_| ())
}
fn waitpid(pid: pid_t, stat_loc: Option<Out<c_int>>, options: c_int) -> Result<pid_t> {