Skip to content

Commit f2504be

Browse files
committed
feat: add ioctl_getflags and ioctl_setflags
1 parent 8539ad6 commit f2504be

File tree

5 files changed

+155
-1
lines changed

5 files changed

+155
-1
lines changed

src/backend/libc/io/syscalls.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use crate::backend::c;
44
#[cfg(not(target_os = "wasi"))]
55
use crate::backend::conv::ret_discarded_fd;
66
use crate::backend::conv::{borrowed_fd, ret, ret_c_int, ret_owned_fd, ret_usize};
7+
#[cfg(any(target_os = "android", target_os = "linux"))]
8+
use crate::backend::io::types::IFlags;
79
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
810
#[cfg(not(any(
911
target_os = "aix",
@@ -217,6 +219,33 @@ pub(crate) unsafe fn ioctl_readonly(
217219
ioctl(fd, request, arg)
218220
}
219221

222+
#[cfg(any(target_os = "android", target_os = "linux"))]
223+
#[inline]
224+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
225+
let mut result = std::mem::MaybeUninit::<IFlags>::uninit();
226+
227+
#[cfg(target_pointer_width = "32")]
228+
let get_flags = c::FS_IOC32_GETFLAGS;
229+
#[cfg(target_pointer_width = "64")]
230+
let get_flags = c::FS_IOC_GETFLAGS;
231+
232+
unsafe {
233+
ret(c::ioctl(borrowed_fd(fd), get_flags, result.as_mut_ptr()))?;
234+
Ok(result.assume_init() as IFlags)
235+
}
236+
}
237+
238+
#[cfg(any(target_os = "android", target_os = "linux"))]
239+
#[inline]
240+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
241+
#[cfg(target_pointer_width = "32")]
242+
let set_flags = c::FS_IOC32_SETFLAGS;
243+
#[cfg(target_pointer_width = "64")]
244+
let set_flags = c::FS_IOC_SETFLAGS;
245+
246+
unsafe { ret(c::ioctl(borrowed_fd(fd), set_flags, flags.bits())) }
247+
}
248+
220249
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
221250
#[cfg(all(feature = "fs", feature = "net"))]
222251
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {

src/backend/libc/io/types.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,37 @@ bitflags! {
6363
const _ = !0;
6464
}
6565
}
66+
67+
bitflags! {
68+
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
69+
pub struct IFlags: c::c_uint {
70+
/// `FS_APPEND_FL`
71+
const APPEND = linux_raw_sys::general::FS_APPEND_FL;
72+
/// `FS_COMPR_FL`
73+
const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
74+
/// `FS_DIRSYNC_FL`
75+
const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
76+
/// `FS_IMMUTABLE_FL`
77+
const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
78+
/// `FS_JOURNAL_DATA_FL`
79+
const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
80+
/// `FS_NOATIME_FL`
81+
const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
82+
/// `FS_NOCOW_FL`
83+
const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
84+
/// `FS_NODUMP_FL`
85+
const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
86+
/// `FS_NOTAIL_FL`
87+
const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
88+
/// `FS_PROJINHERIT_FL`
89+
const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
90+
/// `FS_SECRM_FL`
91+
const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
92+
/// `FS_SYNC_FL`
93+
const SYNC = linux_raw_sys::general::FS_SYNC_FL;
94+
/// `FS_TOPDIR_FL`
95+
const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
96+
/// `FS_UNRM_FL`
97+
const UNRM = linux_raw_sys::general::FS_UNRM_FL;
98+
}
99+
}

src/backend/linux_raw/io/syscalls.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ use crate::backend::conv::loff_t_from_u64;
1414
))]
1515
use crate::backend::conv::zero;
1616
use crate::backend::conv::{
17-
c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd,
17+
by_ref, c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd,
1818
ret_usize, slice,
1919
};
2020
#[cfg(target_pointer_width = "32")]
2121
use crate::backend::conv::{hi, lo};
22+
#[cfg(any(target_os = "android", target_os = "linux"))]
23+
use crate::backend::io::types::IFlags;
2224
use crate::backend::{c, MAX_IOV};
2325
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
2426
use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags};
@@ -27,6 +29,10 @@ use crate::ioctl::{IoctlOutput, RawOpcode};
2729
use crate::net::{RecvFlags, SendFlags};
2830
use core::cmp;
2931
use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD};
32+
#[cfg(target_pointer_width = "32")]
33+
use linux_raw_sys::ioctl::{FS_IOC32_GETFLAGS, FS_IOC32_SETFLAGS};
34+
#[cfg(target_pointer_width = "64")]
35+
use linux_raw_sys::ioctl::{FS_IOC_GETFLAGS, FS_IOC_SETFLAGS};
3036

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

268+
#[inline]
269+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
270+
let mut result = core::mem::MaybeUninit::<IFlags>::uninit();
271+
272+
#[cfg(target_pointer_width = "32")]
273+
let get_flags = c_uint(FS_IOC32_GETFLAGS);
274+
#[cfg(target_pointer_width = "64")]
275+
let get_flags = c_uint(FS_IOC_GETFLAGS);
276+
277+
unsafe {
278+
ret(syscall!(__NR_ioctl, fd, get_flags, &mut result))?;
279+
Ok(result.assume_init() as IFlags)
280+
}
281+
}
282+
283+
#[inline]
284+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
285+
// ioctl expect a *const c_uint, we thus need to convert it and pass it by reference
286+
let attr = flags.bits();
287+
288+
#[cfg(target_pointer_width = "32")]
289+
let set_flags = c_uint(FS_IOC32_SETFLAGS);
290+
#[cfg(target_pointer_width = "64")]
291+
let set_flags = c_uint(FS_IOC_SETFLAGS);
292+
293+
unsafe { ret(syscall_readonly!(__NR_ioctl, fd, set_flags, by_ref(&attr))) }
294+
}
295+
262296
#[cfg(all(feature = "fs", feature = "net"))]
263297
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
264298
let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;

src/backend/linux_raw/io/types.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,37 @@ bitflags! {
5555
const _ = !0;
5656
}
5757
}
58+
59+
bitflags! {
60+
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
61+
pub struct IFlags: c::c_uint {
62+
/// `FS_APPEND_FL`
63+
const APPEND = linux_raw_sys::general::FS_APPEND_FL;
64+
/// `FS_COMPR_FL`
65+
const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
66+
/// `FS_DIRSYNC_FL`
67+
const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
68+
/// `FS_IMMUTABLE_FL`
69+
const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
70+
/// `FS_JOURNAL_DATA_FL`
71+
const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
72+
/// `FS_NOATIME_FL`
73+
const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
74+
/// `FS_NOCOW_FL`
75+
const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
76+
/// `FS_NODUMP_FL`
77+
const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
78+
/// `FS_NOTAIL_FL`
79+
const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
80+
/// `FS_PROJINHERIT_FL`
81+
const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
82+
/// `FS_SECRM_FL`
83+
const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
84+
/// `FS_SYNC_FL`
85+
const SYNC = linux_raw_sys::general::FS_SYNC_FL;
86+
/// `FS_TOPDIR_FL`
87+
const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
88+
/// `FS_UNRM_FL`
89+
const UNRM = linux_raw_sys::general::FS_UNRM_FL;
90+
}
91+
}

src/io/ioctl.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use crate::{backend, io, ioctl};
1212
use backend::c;
1313
use backend::fd::AsFd;
1414

15+
#[cfg(any(target_os = "android", target_os = "linux"))]
16+
pub use backend::io::types::IFlags;
17+
1518
/// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag.
1619
///
1720
/// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids
@@ -75,3 +78,23 @@ pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
7578
ioctl::ioctl(fd, ctl).map(|n| n as u64)
7679
}
7780
}
81+
82+
/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
83+
///
84+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
85+
#[cfg(any(target_os = "android", target_os = "linux"))]
86+
#[inline]
87+
#[doc(alias = "FS_IOC_GETFLAGS")]
88+
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
89+
backend::io::syscalls::ioctl_get_flags(fd.as_fd())
90+
}
91+
92+
/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
93+
///
94+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
95+
#[cfg(any(target_os = "android", target_os = "linux"))]
96+
#[inline]
97+
#[doc(alias = "FS_IOC_GETFLAGS")]
98+
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
99+
backend::io::syscalls::ioctl_set_flags(fd.as_fd(), flags)
100+
}

0 commit comments

Comments
 (0)