Skip to content

Commit

Permalink
feat: add ioctl_getflags and ioctl_setflags
Browse files Browse the repository at this point in the history
  • Loading branch information
fsavy-tehtris committed Dec 15, 2023
1 parent 8539ad6 commit f2504be
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 1 deletion.
29 changes: 29 additions & 0 deletions src/backend/libc/io/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use crate::backend::c;
#[cfg(not(target_os = "wasi"))]
use crate::backend::conv::ret_discarded_fd;
use crate::backend::conv::{borrowed_fd, ret, ret_c_int, ret_owned_fd, ret_usize};
#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::backend::io::types::IFlags;
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
#[cfg(not(any(
target_os = "aix",
Expand Down Expand Up @@ -217,6 +219,33 @@ pub(crate) unsafe fn ioctl_readonly(
ioctl(fd, request, arg)
}

#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
let mut result = std::mem::MaybeUninit::<IFlags>::uninit();

#[cfg(target_pointer_width = "32")]
let get_flags = c::FS_IOC32_GETFLAGS;
#[cfg(target_pointer_width = "64")]
let get_flags = c::FS_IOC_GETFLAGS;

unsafe {
ret(c::ioctl(borrowed_fd(fd), get_flags, result.as_mut_ptr()))?;
Ok(result.assume_init() as IFlags)
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
#[cfg(target_pointer_width = "32")]
let set_flags = c::FS_IOC32_SETFLAGS;
#[cfg(target_pointer_width = "64")]
let set_flags = c::FS_IOC_SETFLAGS;

unsafe { ret(c::ioctl(borrowed_fd(fd), set_flags, flags.bits())) }
}

#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
#[cfg(all(feature = "fs", feature = "net"))]
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
Expand Down
34 changes: 34 additions & 0 deletions src/backend/libc/io/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,37 @@ bitflags! {
const _ = !0;
}
}

bitflags! {
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
pub struct IFlags: c::c_uint {
/// `FS_APPEND_FL`
const APPEND = linux_raw_sys::general::FS_APPEND_FL;
/// `FS_COMPR_FL`
const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
/// `FS_DIRSYNC_FL`
const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
/// `FS_IMMUTABLE_FL`
const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
/// `FS_JOURNAL_DATA_FL`
const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
/// `FS_NOATIME_FL`
const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
/// `FS_NOCOW_FL`
const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
/// `FS_NODUMP_FL`
const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
/// `FS_NOTAIL_FL`
const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
/// `FS_PROJINHERIT_FL`
const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
/// `FS_SECRM_FL`
const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
/// `FS_SYNC_FL`
const SYNC = linux_raw_sys::general::FS_SYNC_FL;
/// `FS_TOPDIR_FL`
const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
/// `FS_UNRM_FL`
const UNRM = linux_raw_sys::general::FS_UNRM_FL;
}
}
36 changes: 35 additions & 1 deletion src/backend/linux_raw/io/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ use crate::backend::conv::loff_t_from_u64;
))]
use crate::backend::conv::zero;
use crate::backend::conv::{
c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd,
by_ref, c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd,
ret_usize, slice,
};
#[cfg(target_pointer_width = "32")]
use crate::backend::conv::{hi, lo};
#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::backend::io::types::IFlags;
use crate::backend::{c, MAX_IOV};
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags};
Expand All @@ -27,6 +29,10 @@ use crate::ioctl::{IoctlOutput, RawOpcode};
use crate::net::{RecvFlags, SendFlags};
use core::cmp;
use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD};
#[cfg(target_pointer_width = "32")]
use linux_raw_sys::ioctl::{FS_IOC32_GETFLAGS, FS_IOC32_SETFLAGS};
#[cfg(target_pointer_width = "64")]
use linux_raw_sys::ioctl::{FS_IOC_GETFLAGS, FS_IOC_SETFLAGS};

#[inline]
pub(crate) unsafe fn read(fd: BorrowedFd<'_>, buf: *mut u8, len: usize) -> io::Result<usize> {
Expand Down Expand Up @@ -259,6 +265,34 @@ pub(crate) unsafe fn ioctl_readonly(
ret_c_int(syscall_readonly!(__NR_ioctl, fd, c_uint(request), arg))
}

#[inline]
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
let mut result = core::mem::MaybeUninit::<IFlags>::uninit();

#[cfg(target_pointer_width = "32")]
let get_flags = c_uint(FS_IOC32_GETFLAGS);
#[cfg(target_pointer_width = "64")]
let get_flags = c_uint(FS_IOC_GETFLAGS);

unsafe {
ret(syscall!(__NR_ioctl, fd, get_flags, &mut result))?;
Ok(result.assume_init() as IFlags)
}
}

#[inline]
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
// ioctl expect a *const c_uint, we thus need to convert it and pass it by reference
let attr = flags.bits();

#[cfg(target_pointer_width = "32")]
let set_flags = c_uint(FS_IOC32_SETFLAGS);
#[cfg(target_pointer_width = "64")]
let set_flags = c_uint(FS_IOC_SETFLAGS);

unsafe { ret(syscall_readonly!(__NR_ioctl, fd, set_flags, by_ref(&attr))) }
}

#[cfg(all(feature = "fs", feature = "net"))]
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;
Expand Down
34 changes: 34 additions & 0 deletions src/backend/linux_raw/io/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,37 @@ bitflags! {
const _ = !0;
}
}

bitflags! {
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
pub struct IFlags: c::c_uint {
/// `FS_APPEND_FL`
const APPEND = linux_raw_sys::general::FS_APPEND_FL;
/// `FS_COMPR_FL`
const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
/// `FS_DIRSYNC_FL`
const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
/// `FS_IMMUTABLE_FL`
const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
/// `FS_JOURNAL_DATA_FL`
const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
/// `FS_NOATIME_FL`
const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
/// `FS_NOCOW_FL`
const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
/// `FS_NODUMP_FL`
const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
/// `FS_NOTAIL_FL`
const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
/// `FS_PROJINHERIT_FL`
const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
/// `FS_SECRM_FL`
const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
/// `FS_SYNC_FL`
const SYNC = linux_raw_sys::general::FS_SYNC_FL;
/// `FS_TOPDIR_FL`
const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
/// `FS_UNRM_FL`
const UNRM = linux_raw_sys::general::FS_UNRM_FL;
}
}
23 changes: 23 additions & 0 deletions src/io/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ use crate::{backend, io, ioctl};
use backend::c;
use backend::fd::AsFd;

#[cfg(any(target_os = "android", target_os = "linux"))]
pub use backend::io::types::IFlags;

/// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag.
///
/// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids
Expand Down Expand Up @@ -75,3 +78,23 @@ pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
ioctl::ioctl(fd, ctl).map(|n| n as u64)
}
}

/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
///
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
#[doc(alias = "FS_IOC_GETFLAGS")]
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
backend::io::syscalls::ioctl_get_flags(fd.as_fd())
}

/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
///
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
#[doc(alias = "FS_IOC_GETFLAGS")]
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
backend::io::syscalls::ioctl_set_flags(fd.as_fd(), flags)
}

0 comments on commit f2504be

Please sign in to comment.