Skip to content

Commit

Permalink
Add ioctl_getflags and ioctl_setflags
Browse files Browse the repository at this point in the history
  • Loading branch information
ETKNeil committed Jan 23, 2023
1 parent 89a485e commit 9c60b25
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 1 deletion.
43 changes: 43 additions & 0 deletions src/backend/libc/io/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use super::super::offset::{libc_preadv2, libc_pwritev2};
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
#[cfg(not(any(target_os = "aix", target_os = "wasi")))]
use crate::io::DupFlags;
#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::io::IFlags;
#[cfg(not(any(
target_os = "aix",
target_os = "haiku",
Expand Down Expand Up @@ -324,6 +326,47 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
let mut result = MaybeUninit::<IFlags>::uninit();
#[cfg(target_pointer_width = "32")]
unsafe {
ret(c::ioctl(
borrowed_fd(fd),
c::FS_IOC32_GETFLAGS,
result.as_mut_ptr(),
))?;
Ok(result.assume_init() as IFlags)
}
#[cfg(target_pointer_width = "64")]
unsafe {
ret(c::ioctl(
borrowed_fd(fd),
c::FS_IOC_GETFLAGS,
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")]
unsafe {
ret(c::ioctl(
borrowed_fd(fd),
c::FS_IOC32_SETFLAGS,
flags.bits(),
))
}
#[cfg(target_pointer_width = "64")]
unsafe {
ret(c::ioctl(borrowed_fd(fd), c::FS_IOC_SETFLAGS, flags.bits()))
}
}

#[cfg(not(target_os = "redox"))]
pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
let mut nread = MaybeUninit::<c::c_int>::uninit();
Expand Down
33 changes: 33 additions & 0 deletions src/backend/libc/io/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,36 @@ impl<'a> IoSliceRaw<'a> {
}
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
bitflags! {
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
pub struct IFlags: c::c_uint {
/// `FS_APPEND_FL`
const APPEND = c::FS_APPEND_FL;
/// `FS_COMPR_FL`
const COMPRESSED = c::FS_COMPR_FL;
/// `FS_DIRSYNC_FL`
const DIRSYNC = c::FS_DIRSYNC_FL;
/// `FS_IMMUTABLE_FL`
const IMMUTABLE = c::FS_IMMUTABLE_FL;
/// `FS_JOURNAL_DATA_FL`
const JOURNALING = c::FS_JOURNAL_DATA_FL;
/// `FS_NOATIME_FL`
const NOATIME = c::FS_NOATIME_FL;
/// `FS_NODUMP_FL`
const NODUMP = c::FS_NODUMP_FL;
/// `FS_NOTAIL_FL`
const NOTAIL = c::FS_NOTAIL_FL;
/// `FS_PROJINHERIT_FL`
const PROJECT_INHERIT = c::FS_PROJINHERIT_FL;
/// `FS_SECRM_FL`
const SECURE_REMOVAL = c::FS_SECRM_FL;
/// `FS_SYNC_FL`
const SYNC = c::FS_SYNC_FL;
/// `FS_TOPDIR_FL`
const TOPDIR = c::FS_TOPDIR_FL;
/// `FS_UNRM_FL`
const UNRM = c::FS_UNRM_FL;
}
}
8 changes: 8 additions & 0 deletions src/backend/linux_raw/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,14 @@ impl<'a, Num: ArgNumber> From<crate::backend::fs::types::UnmountFlags> for ArgRe
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
impl<'a, Num: ArgNumber> From<crate::backend::io::types::IFlags> for ArgReg<'a, Num> {
#[inline]
fn from(flags: crate::backend::io::types::IFlags) -> Self {
c_uint(flags.bits())
}
}

/// Convert a `usize` returned from a syscall that effectively returns `()` on
/// success.
///
Expand Down
53 changes: 53 additions & 0 deletions src/backend/linux_raw/io/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use super::super::conv::{
};
#[cfg(target_pointer_width = "32")]
use super::super::conv::{hi, lo};
#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::backend::io::types::IFlags;
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::io::SpliceFlags;
Expand All @@ -33,6 +35,10 @@ use linux_raw_sys::general::{
UIO_MAXIOV,
};
use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, TIOCEXCL, TIOCNXCL};
#[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};
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
use {
super::super::conv::{opt_ref, size_of},
Expand Down Expand Up @@ -352,6 +358,53 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
}
}

#[inline]
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
let mut result = MaybeUninit::<IFlags>::uninit();
#[cfg(target_pointer_width = "32")]
unsafe {
ret(syscall!(
__NR_ioctl,
fd,
c_uint(FS_IOC32_GETFLAGS),
&mut result
))?;
Ok(result.assume_init() as IFlags)
}
#[cfg(target_pointer_width = "64")]
unsafe {
ret(syscall!(
__NR_ioctl,
fd,
c_uint(FS_IOC_GETFLAGS),
&mut result
))?;
Ok(result.assume_init() as IFlags)
}
}

#[inline]
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
#[cfg(target_pointer_width = "32")]
unsafe {
ret(syscall_readonly!(
__NR_ioctl,
fd,
c_uint(FS_IOC32_SETFLAGS),
flags
))
}
#[cfg(target_pointer_width = "64")]
unsafe {
ret(syscall_readonly!(
__NR_ioctl,
fd,
c_uint(FS_IOC_SETFLAGS),
flags
))
}
}

#[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
32 changes: 32 additions & 0 deletions src/backend/linux_raw/io/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,35 @@ impl<'a> IoSliceRaw<'a> {
}
}
}

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_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;
}
}
20 changes: 20 additions & 0 deletions src/io/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,23 @@ pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
backend::io::syscalls::ioctl_blkpbszget(fd.as_fd())
}

/// `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<backend::io::types::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: backend::io::types::IFlags) -> io::Result<()> {
backend::io::syscalls::ioctl_set_flags(fd.as_fd(), flags)
}
2 changes: 1 addition & 1 deletion src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub use ioctl::ioctl_fionbio;
#[cfg(not(target_os = "redox"))]
pub use ioctl::ioctl_fionread;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget};
pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget, ioctl_getflags, ioctl_setflags};
#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))]
pub use ioctl::{ioctl_tiocexcl, ioctl_tiocnxcl};
#[cfg(not(any(windows, target_os = "redox")))]
Expand Down

0 comments on commit 9c60b25

Please sign in to comment.