Skip to content

Commit af512cb

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

File tree

7 files changed

+192
-2
lines changed

7 files changed

+192
-2
lines changed

src/backend/libc/io/syscalls.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::super::offset::{libc_pread, libc_pwrite};
1111
use super::super::offset::{libc_preadv, libc_pwritev};
1212
#[cfg(all(target_os = "linux", target_env = "gnu"))]
1313
use super::super::offset::{libc_preadv2, libc_pwritev2};
14+
use crate::backend::io::types::IFlags;
1415
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
1516
#[cfg(not(any(target_os = "aix", target_os = "wasi")))]
1617
use crate::io::DupFlags;
@@ -324,6 +325,51 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
324325
}
325326
}
326327

328+
#[cfg(any(target_os = "android", target_os = "linux"))]
329+
#[inline]
330+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
331+
let mut result = MaybeUninit::<IFlags>::uninit();
332+
#[cfg(target_pointer_width = "32")]
333+
unsafe {
334+
ret(c::ioctl(
335+
borrowed_fd(fd),
336+
c::FS_IOC32_GETFLAGS,
337+
result.as_mut_ptr(),
338+
))?;
339+
Ok(result.assume_init() as u32)
340+
}
341+
#[cfg(target_pointer_width = "64")]
342+
unsafe {
343+
ret(c::ioctl(
344+
borrowed_fd(fd),
345+
c::FS_IOC_GETFLAGS,
346+
result.as_mut_ptr(),
347+
))?;
348+
Ok(result.assume_init() as u32)
349+
}
350+
}
351+
352+
#[cfg(any(target_os = "android", target_os = "linux"))]
353+
#[inline]
354+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
355+
#[cfg(target_pointer_width = "32")]
356+
unsafe {
357+
ret(c::ioctl(
358+
borrowed_fd(fd),
359+
c::FS_IOC32_SETFLAGS,
360+
flags.as_ptr(),
361+
))
362+
}
363+
#[cfg(target_pointer_width = "64")]
364+
unsafe {
365+
ret(c::ioctl(
366+
borrowed_fd(fd),
367+
c::FS_IOC_SETFLAGS,
368+
flags.as_ptr(),
369+
))
370+
}
371+
}
372+
327373
#[cfg(not(target_os = "redox"))]
328374
pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
329375
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: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use super::super::conv::{
1515
};
1616
#[cfg(target_pointer_width = "32")]
1717
use super::super::conv::{hi, lo};
18+
use crate::backend::io::types::IFlags;
1819
use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
1920
#[cfg(any(target_os = "android", target_os = "linux"))]
2021
use crate::io::SpliceFlags;
@@ -32,7 +33,9 @@ use linux_raw_sys::general::{
3233
epoll_event, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, F_DUPFD_CLOEXEC, F_GETFD, F_SETFD,
3334
UIO_MAXIOV,
3435
};
35-
use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, TIOCEXCL, TIOCNXCL};
36+
use linux_raw_sys::ioctl::{
37+
BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, FS_IOC_GETFLAGS, FS_IOC_SETFLAGS, TIOCEXCL, TIOCNXCL,
38+
};
3639
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
3740
use {
3841
super::super::conv::{opt_ref, size_of},
@@ -352,6 +355,53 @@ pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
352355
}
353356
}
354357

358+
#[inline]
359+
pub(crate) fn ioctl_get_flags(fd: BorrowedFd) -> io::Result<IFlags> {
360+
let mut result = MaybeUninit::<IFlags>::uninit();
361+
#[cfg(target_pointer_width = "32")]
362+
unsafe {
363+
ret(syscall!(
364+
__NR_ioctl,
365+
fd,
366+
c_uint(FS_IOC32_GETFLAGS),
367+
&mut result
368+
))?;
369+
Ok(result.assume_init() as IFlags)
370+
}
371+
#[cfg(target_pointer_width = "64")]
372+
unsafe {
373+
ret(syscall!(
374+
__NR_ioctl,
375+
fd,
376+
c_uint(FS_IOC_GETFLAGS),
377+
&mut result
378+
))?;
379+
Ok(result.assume_init() as IFlags)
380+
}
381+
}
382+
383+
#[inline]
384+
pub(crate) fn ioctl_set_flags(fd: BorrowedFd, flags: IFlags) -> io::Result<()> {
385+
#[cfg(target_pointer_width = "32")]
386+
unsafe {
387+
ret(syscall_readonly!(
388+
__NR_ioctl,
389+
fd,
390+
c_uint(FS_IOC32_SETFLAGS),
391+
flags
392+
))
393+
}
394+
#[cfg(target_pointer_width = "64")]
395+
unsafe {
396+
ret(syscall_readonly!(
397+
__NR_ioctl,
398+
fd,
399+
c_uint(FS_IOC_SETFLAGS),
400+
flags
401+
))
402+
}
403+
}
404+
355405
#[cfg(all(feature = "fs", feature = "net"))]
356406
pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
357407
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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use crate::{backend, io};
77
use backend::fd::AsFd;
8+
use backend::io::types::IFlags;
89

910
/// `ioctl(fd, TIOCEXCL)`—Enables exclusive mode on a terminal.
1011
///
@@ -97,3 +98,23 @@ pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
9798
pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
9899
backend::io::syscalls::ioctl_blkpbszget(fd.as_fd())
99100
}
101+
102+
/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
103+
///
104+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
105+
#[cfg(any(target_os = "linux"))]
106+
#[inline]
107+
#[doc(alias = "FS_IOC_GETFLAGS")]
108+
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
109+
backend::io::syscalls::ioctl_get_flags(fd.as_fd())
110+
}
111+
112+
/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
113+
///
114+
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
115+
#[cfg(any(target_os = "linux"))]
116+
#[inline]
117+
#[doc(alias = "FS_IOC_GETFLAGS")]
118+
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
119+
backend::io::syscalls::ioctl_set_flags(fd.as_fd(), flags)
120+
}

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)