summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/fs/syscalls.rs')
-rw-r--r--vendor/rustix/src/backend/linux_raw/fs/syscalls.rs168
1 files changed, 161 insertions, 7 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs
index 8bd9ccc27..d0d855cc1 100644
--- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs
+++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs
@@ -10,7 +10,7 @@
use super::super::c;
use super::super::conv::{
by_ref, c_int, c_uint, dev_t, oflags_for_open_how, opt_mut, pass_usize, raw_fd, ret, ret_c_int,
- ret_c_uint, ret_infallible, ret_owned_fd, ret_usize, size_of, slice_mut, zero,
+ ret_c_uint, ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, zero,
};
#[cfg(target_pointer_width = "64")]
use super::super::conv::{loff_t, loff_t_from_u64, ret_u64};
@@ -26,7 +26,7 @@ use crate::ffi::CStr;
use crate::fs::{
inotify, Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, MemfdFlags, Mode,
OFlags, RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatVfs, StatVfsMountFlags,
- StatxFlags, Timestamps,
+ StatxFlags, Timestamps, XattrFlags,
};
use crate::io::{self, SeekFrom};
use crate::process::{Gid, Uid};
@@ -1392,6 +1392,30 @@ pub(crate) fn accessat(
access: Access,
flags: AtFlags,
) -> io::Result<()> {
+ if !flags
+ .difference(AtFlags::EACCESS | AtFlags::SYMLINK_NOFOLLOW)
+ .is_empty()
+ {
+ return Err(io::Errno::INVAL);
+ }
+
+ // Linux's `faccessat` syscall doesn't have a flags argument, so if we have
+ // any flags, use the newer `faccessat2` which does. Unless we're on
+ // Android where using newer system calls can cause seccomp to abort the
+ // process.
+ #[cfg(not(target_os = "android"))]
+ if !flags.is_empty() {
+ return unsafe {
+ ret(syscall_readonly!(
+ __NR_faccessat2,
+ dirfd,
+ path,
+ access,
+ flags
+ ))
+ };
+ }
+
// Linux's `faccessat` doesn't have a flags parameter. If we have
// `AT_EACCESS` and we're not setuid or setgid, we can emulate it.
if flags.is_empty()
@@ -1402,11 +1426,6 @@ pub(crate) fn accessat(
return unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) };
}
- if flags.bits() != AT_EACCESS {
- return Err(io::Errno::INVAL);
- }
-
- // TODO: Use faccessat2 in newer Linux versions.
Err(io::Errno::NOSYS)
}
@@ -1510,3 +1529,138 @@ pub(crate) fn inotify_add_watch(
pub(crate) fn inotify_rm_watch(infd: BorrowedFd<'_>, wfd: i32) -> io::Result<()> {
unsafe { ret(syscall_readonly!(__NR_inotify_rm_watch, infd, c_int(wfd))) }
}
+
+#[inline]
+pub(crate) fn getxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> {
+ let (value_addr_mut, value_len) = slice_mut(value);
+ unsafe {
+ ret_usize(syscall!(
+ __NR_getxattr,
+ path,
+ name,
+ value_addr_mut,
+ value_len
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn lgetxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> {
+ let (value_addr_mut, value_len) = slice_mut(value);
+ unsafe {
+ ret_usize(syscall!(
+ __NR_lgetxattr,
+ path,
+ name,
+ value_addr_mut,
+ value_len
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn fgetxattr(fd: BorrowedFd<'_>, name: &CStr, value: &mut [u8]) -> io::Result<usize> {
+ let (value_addr_mut, value_len) = slice_mut(value);
+ unsafe {
+ ret_usize(syscall!(
+ __NR_fgetxattr,
+ fd,
+ name,
+ value_addr_mut,
+ value_len
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn setxattr(
+ path: &CStr,
+ name: &CStr,
+ value: &[u8],
+ flags: XattrFlags,
+) -> io::Result<()> {
+ let (value_addr, value_len) = slice(value);
+ unsafe {
+ ret(syscall_readonly!(
+ __NR_setxattr,
+ path,
+ name,
+ value_addr,
+ value_len,
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn lsetxattr(
+ path: &CStr,
+ name: &CStr,
+ value: &[u8],
+ flags: XattrFlags,
+) -> io::Result<()> {
+ let (value_addr, value_len) = slice(value);
+ unsafe {
+ ret(syscall_readonly!(
+ __NR_lsetxattr,
+ path,
+ name,
+ value_addr,
+ value_len,
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn fsetxattr(
+ fd: BorrowedFd<'_>,
+ name: &CStr,
+ value: &[u8],
+ flags: XattrFlags,
+) -> io::Result<()> {
+ let (value_addr, value_len) = slice(value);
+ unsafe {
+ ret(syscall_readonly!(
+ __NR_fsetxattr,
+ fd,
+ name,
+ value_addr,
+ value_len,
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn listxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> {
+ let (list_addr_mut, list_len) = slice_mut(list);
+ unsafe { ret_usize(syscall!(__NR_listxattr, path, list_addr_mut, list_len)) }
+}
+
+#[inline]
+pub(crate) fn llistxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> {
+ let (list_addr_mut, list_len) = slice_mut(list);
+ unsafe { ret_usize(syscall!(__NR_llistxattr, path, list_addr_mut, list_len)) }
+}
+
+#[inline]
+pub(crate) fn flistxattr(fd: BorrowedFd<'_>, list: &mut [c::c_char]) -> io::Result<usize> {
+ let (list_addr_mut, list_len) = slice_mut(list);
+ unsafe { ret_usize(syscall!(__NR_flistxattr, fd, list_addr_mut, list_len)) }
+}
+
+#[inline]
+pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> {
+ unsafe { ret(syscall!(__NR_removexattr, path, name)) }
+}
+
+#[inline]
+pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> {
+ unsafe { ret(syscall!(__NR_lremovexattr, path, name)) }
+}
+
+#[inline]
+pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> {
+ unsafe { ret(syscall!(__NR_fremovexattr, fd, name)) }
+}