Skip to content

Commit a5cd2eb

Browse files
committed
Add ioctl_getflags and ioctl_setflags
1 parent 89a485e commit a5cd2eb

File tree

7 files changed

+189
-2
lines changed

7 files changed

+189
-2
lines changed

src/backend/libc/io/syscalls.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use super::super::offset::{libc_preadv2, libc_pwritev2};
1414
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
1515
#[cfg(not(any(target_os = "aix", target_os = "wasi")))]
1616
use crate::io::DupFlags;
17+
#[cfg(any(target_os = "android", target_os = "linux"))]
18+
use crate::io::IFlags;
1719
#[cfg(not(any(
1820
target_os = "aix",
1921
target_os = "haiku",
@@ -324,6 +326,47 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
324326
}
325327
}
326328

329+
#[cfg(any(target_os = "android", target_os = "linux"))]
330+
#[inline]
331+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
332+
let mut result = MaybeUninit::<IFlags>::uninit();
333+
#[cfg(target_pointer_width = "32")]
334+
unsafe {
335+
ret(c::ioctl(
336+
borrowed_fd(fd),
337+
c::FS_IOC32_GETFLAGS,
338+
result.as_mut_ptr(),
339+
))?;
340+
Ok(result.assume_init() as IFlags)
341+
}
342+
#[cfg(target_pointer_width = "64")]
343+
unsafe {
344+
ret(c::ioctl(
345+
borrowed_fd(fd),
346+
c::FS_IOC_GETFLAGS,
347+
result.as_mut_ptr(),
348+
))?;
349+
Ok(result.assume_init() as IFlags)
350+
}
351+
}
352+
353+
#[cfg(any(target_os = "android", target_os = "linux"))]
354+
#[inline]
355+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
356+
#[cfg(target_pointer_width = "32")]
357+
unsafe {
358+
ret(c::ioctl(
359+
borrowed_fd(fd),
360+
c::FS_IOC32_SETFLAGS,
361+
flags.bits(),
362+
))
363+
}
364+
#[cfg(target_pointer_width = "64")]
365+
unsafe {
366+
ret(c::ioctl(borrowed_fd(fd), c::FS_IOC_SETFLAGS, flags.bits()))
367+
}
368+
}
369+
327370
#[cfg(not(target_os = "redox"))]
328371
pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
329372
let mut nread = MaybeUninit::<c::c_int>::uninit();

src/backend/libc/io/types.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,36 @@ impl<'a> IoSliceRaw<'a> {
157157
}
158158
}
159159
}
160+
161+
#[cfg(any(target_os = "android", target_os = "linux"))]
162+
bitflags! {
163+
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
164+
pub struct IFlags: c::c_uint {
165+
/// `FS_APPEND_FL`
166+
const APPEND = c::FS_APPEND_FL;
167+
/// `FS_COMPR_FL`
168+
const COMPRESSED = c::FS_COMPR_FL;
169+
/// `FS_DIRSYNC_FL`
170+
const DIRSYNC = c::FS_DIRSYNC_FL;
171+
/// `FS_IMMUTABLE_FL`
172+
const IMMUTABLE = c::FS_IMMUTABLE_FL;
173+
/// `FS_JOURNAL_DATA_FL`
174+
const JOURNALING = c::FS_JOURNAL_DATA_FL;
175+
/// `FS_NOATIME_FL`
176+
const NOATIME = c::FS_NOATIME_FL;
177+
/// `FS_NODUMP_FL`
178+
const NODUMP = c::FS_NODUMP_FL;
179+
/// `FS_NOTAIL_FL`
180+
const NOTAIL = c::FS_NOTAIL_FL;
181+
/// `FS_PROJINHERIT_FL`
182+
const PROJECT_INHERIT = c::FS_PROJINHERIT_FL;
183+
/// `FS_SECRM_FL`
184+
const SECURE_REMOVAL = c::FS_SECRM_FL;
185+
/// `FS_SYNC_FL`
186+
const SYNC = c::FS_SYNC_FL;
187+
/// `FS_TOPDIR_FL`
188+
const TOPDIR = c::FS_TOPDIR_FL;
189+
/// `FS_UNRM_FL`
190+
const UNRM = c::FS_UNRM_FL;
191+
}
192+
}

src/backend/linux_raw/conv.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,14 @@ impl<'a, Num: ArgNumber> From<crate::backend::fs::types::UnmountFlags> for ArgRe
683683
}
684684
}
685685

686+
#[cfg(any(target_os = "android", target_os = "linux"))]
687+
impl<'a, Num: ArgNumber> From<crate::backend::io::types::IFlags> for ArgReg<'a, Num> {
688+
#[inline]
689+
fn from(flags: crate::backend::io::types::IFlags) -> Self {
690+
c_uint(flags.bits())
691+
}
692+
}
693+
686694
/// Convert a `usize` returned from a syscall that effectively returns `()` on
687695
/// success.
688696
///

src/backend/linux_raw/io/syscalls.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use super::super::conv::{
1717
use super::super::conv::{hi, lo};
1818
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
1919
#[cfg(any(target_os = "android", target_os = "linux"))]
20+
use crate::io::types::IFlags;
21+
#[cfg(any(target_os = "android", target_os = "linux"))]
2022
use crate::io::SpliceFlags;
2123
use crate::io::{
2224
self, epoll, DupFlags, EventfdFlags, FdFlags, IoSlice, IoSliceMut, IoSliceRaw, PipeFlags,
@@ -32,7 +34,9 @@ use linux_raw_sys::general::{
3234
epoll_event, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, F_DUPFD_CLOEXEC, F_GETFD, F_SETFD,
3335
UIO_MAXIOV,
3436
};
35-
use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, TIOCEXCL, TIOCNXCL};
37+
use linux_raw_sys::ioctl::{
38+
BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, FS_IOC_GETFLAGS, FS_IOC_SETFLAGS, TIOCEXCL, TIOCNXCL,
39+
};
3640
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
3741
use {
3842
super::super::conv::{opt_ref, size_of},
@@ -352,6 +356,53 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
352356
}
353357
}
354358

359+
#[inline]
360+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
361+
let mut result = MaybeUninit::<IFlags>::uninit();
362+
#[cfg(target_pointer_width = "32")]
363+
unsafe {
364+
ret(syscall!(
365+
__NR_ioctl,
366+
fd,
367+
c_uint(FS_IOC32_GETFLAGS),
368+
&mut result
369+
))?;
370+
Ok(result.assume_init() as IFlags)
371+
}
372+
#[cfg(target_pointer_width = "64")]
373+
unsafe {
374+
ret(syscall!(
375+
__NR_ioctl,
376+
fd,
377+
c_uint(FS_IOC_GETFLAGS),
378+
&mut result
379+
))?;
380+
Ok(result.assume_init() as IFlags)
381+
}
382+
}
383+
384+
#[inline]
385+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
386+
#[cfg(target_pointer_width = "32")]
387+
unsafe {
388+
ret(syscall_readonly!(
389+
__NR_ioctl,
390+
fd,
391+
c_uint(FS_IOC32_SETFLAGS),
392+
flags
393+
))
394+
}
395+
#[cfg(target_pointer_width = "64")]
396+
unsafe {
397+
ret(syscall_readonly!(
398+
__NR_ioctl,
399+
fd,
400+
c_uint(FS_IOC_SETFLAGS),
401+
flags
402+
))
403+
}
404+
}
405+
355406
#[cfg(all(feature = "fs", feature = "net"))]
356407
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
357408
let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;

src/backend/linux_raw/io/types.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,35 @@ impl<'a> IoSliceRaw<'a> {
126126
}
127127
}
128128
}
129+
130+
bitflags! {
131+
/// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
132+
pub struct IFlags: c::c_uint {
133+
/// `FS_APPEND_FL`
134+
const APPEND = linux_raw_sys::general::FS_APPEND_FL;
135+
/// `FS_COMPR_FL`
136+
const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
137+
/// `FS_DIRSYNC_FL`
138+
const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
139+
/// `FS_IMMUTABLE_FL`
140+
const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
141+
/// `FS_JOURNAL_DATA_FL`
142+
const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
143+
/// `FS_NOATIME_FL`
144+
const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
145+
/// `FS_NODUMP_FL`
146+
const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
147+
/// `FS_NOTAIL_FL`
148+
const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
149+
/// `FS_PROJINHERIT_FL`
150+
const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
151+
/// `FS_SECRM_FL`
152+
const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
153+
/// `FS_SYNC_FL`
154+
const SYNC = linux_raw_sys::general::FS_SYNC_FL;
155+
/// `FS_TOPDIR_FL`
156+
const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
157+
/// `FS_UNRM_FL`
158+
const UNRM = linux_raw_sys::general::FS_UNRM_FL;
159+
}
160+
}

src/io/ioctl.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,23 @@ pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
9797
pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
9898
backend::io::syscalls::ioctl_blkpbszget(fd.as_fd())
9999
}
100+
101+
/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
102+
///
103+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
104+
#[cfg(any(target_os = "android", target_os = "linux"))]
105+
#[inline]
106+
#[doc(alias = "FS_IOC_GETFLAGS")]
107+
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<backend::io::types::IFlags> {
108+
backend::io::syscalls::ioctl_get_flags(fd.as_fd())
109+
}
110+
111+
/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
112+
///
113+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
114+
#[cfg(any(target_os = "android", target_os = "linux"))]
115+
#[inline]
116+
#[doc(alias = "FS_IOC_GETFLAGS")]
117+
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: backend::io::types::IFlags) -> io::Result<()> {
118+
backend::io::syscalls::ioctl_set_flags(fd.as_fd(), flags)
119+
}

src/io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub use ioctl::ioctl_fionbio;
4242
#[cfg(not(target_os = "redox"))]
4343
pub use ioctl::ioctl_fionread;
4444
#[cfg(any(target_os = "android", target_os = "linux"))]
45-
pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget};
45+
pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget, ioctl_getflags, ioctl_setflags};
4646
#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))]
4747
pub use ioctl::{ioctl_tiocexcl, ioctl_tiocnxcl};
4848
#[cfg(not(any(windows, target_os = "redox")))]

0 commit comments

Comments
 (0)