Skip to content

Commit e5aaaba

Browse files
authored
Merge pull request raspberrypi#608 from danobi/file_flags_type
rust: file: Add `FileFlags` type for `File` flags
2 parents 1781c4c + e55cbe3 commit e5aaaba

File tree

3 files changed

+96
-9
lines changed

3 files changed

+96
-9
lines changed

drivers/android/process.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use core::{convert::TryFrom, mem::take, ops::Range};
44
use kernel::{
55
bindings,
66
cred::Credential,
7-
file::{self, File, IoctlCommand, IoctlHandler, PollTable},
7+
file::{self, File, FileFlags, IoctlCommand, IoctlHandler, PollTable},
88
io_buffer::{IoBufferReader, IoBufferWriter},
99
linked_list::List,
1010
mm,
@@ -794,8 +794,9 @@ impl IoctlHandler for Process {
794794
data: UserSlicePtr,
795795
) -> Result<i32> {
796796
let thread = this.get_thread(Task::current().pid())?;
797+
let blocking = (file.flags() & FileFlags::O_NONBLOCK) == 0;
797798
match cmd {
798-
bindings::BINDER_WRITE_READ => thread.write_read(data, file.is_blocking())?,
799+
bindings::BINDER_WRITE_READ => thread.write_read(data, blocking)?,
799800
bindings::BINDER_GET_NODE_DEBUG_INFO => this.get_node_debug_info(data)?,
800801
bindings::BINDER_GET_NODE_INFO_FOR_REF => this.get_node_info_from_ref(data)?,
801802
bindings::BINDER_VERSION => this.version(data)?,

rust/kernel/file.rs

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,94 @@ use core::convert::{TryFrom, TryInto};
2121
use core::{cell::UnsafeCell, marker, mem, ptr};
2222
use macros::vtable;
2323

24+
/// Flags associated with a [`File`].
25+
///
26+
/// It is tagged with `non_exhaustive` to prevent users from instantiating it.
27+
#[non_exhaustive]
28+
pub struct FileFlags;
29+
30+
impl FileFlags {
31+
/// File is opened in append mode.
32+
pub const O_APPEND: u32 = bindings::O_APPEND;
33+
34+
/// Signal-driven I/O is enabled.
35+
pub const O_ASYNC: u32 = bindings::FASYNC;
36+
37+
/// Close-on-exec flag is set.
38+
pub const O_CLOEXEC: u32 = bindings::O_CLOEXEC;
39+
40+
/// File was created if it didn't already exist.
41+
pub const O_CREAT: u32 = bindings::O_CREAT;
42+
43+
/// Direct I/O is enabled for this file.
44+
pub const O_DIRECT: u32 = bindings::O_DIRECT;
45+
46+
/// File must be a directory.
47+
pub const O_DIRECTORY: u32 = bindings::O_DIRECTORY;
48+
49+
/// Like `Self::O_SYNC` except metadata is not synced.
50+
pub const O_DSYNC: u32 = bindings::O_DSYNC;
51+
52+
/// Ensure that this file is created with the `open(2)` call.
53+
pub const O_EXCL: u32 = bindings::O_EXCL;
54+
55+
/// Large file size enabled (`off64_t` over `off_t`)
56+
pub const O_LARGEFILE: u32 = bindings::O_LARGEFILE;
57+
58+
/// Do not update the file last access time.
59+
pub const O_NOATIME: u32 = bindings::O_NOATIME;
60+
61+
/// File should not be used as process's controlling terminal.
62+
pub const O_NOCTTY: u32 = bindings::O_NOCTTY;
63+
64+
/// If basename of path is a symbolic link, fail open.
65+
pub const O_NOFOLLOW: u32 = bindings::O_NOFOLLOW;
66+
67+
/// File is using nonblocking I/O.
68+
pub const O_NONBLOCK: u32 = bindings::O_NONBLOCK;
69+
70+
/// Also known as `O_NDELAY`.
71+
///
72+
/// This is effectively the same flag as [`Self::O_NONBLOCK`] on all architectures
73+
/// except SPARC64.
74+
pub const O_NDELAY: u32 = bindings::O_NDELAY;
75+
76+
/// Used to obtain a path file descriptor.
77+
pub const O_PATH: u32 = bindings::O_PATH;
78+
79+
/// Write operations on this file will flush data and metadata.
80+
pub const O_SYNC: u32 = bindings::O_SYNC;
81+
82+
/// This file is an unnamed temporary regular file.
83+
pub const O_TMPFILE: u32 = bindings::O_TMPFILE;
84+
85+
/// File should be truncated to length 0.
86+
pub const O_TRUNC: u32 = bindings::O_TRUNC;
87+
88+
/// Bitmask for access mode flags.
89+
///
90+
/// # Examples
91+
///
92+
/// ```
93+
/// use kernel::file::FileFlags;
94+
/// # fn do_something() {}
95+
/// # let flags = 0;
96+
/// if (flags & FileFlags::O_ACCMODE) == FileFlags::O_RDONLY {
97+
/// do_something();
98+
/// }
99+
/// ```
100+
pub const O_ACCMODE: u32 = bindings::O_ACCMODE;
101+
102+
/// File is read only.
103+
pub const O_RDONLY: u32 = bindings::O_RDONLY;
104+
105+
/// File is write only.
106+
pub const O_WRONLY: u32 = bindings::O_WRONLY;
107+
108+
/// File can be both read and written.
109+
pub const O_RDWR: u32 = bindings::O_RDWR;
110+
}
111+
24112
/// Wraps the kernel's `struct file`.
25113
///
26114
/// # Invariants
@@ -63,11 +151,6 @@ impl File {
63151
unsafe { core::ptr::addr_of!((*self.0.get()).f_pos).read() as _ }
64152
}
65153

66-
/// Returns whether the file is in blocking mode.
67-
pub fn is_blocking(&self) -> bool {
68-
self.flags() & bindings::O_NONBLOCK == 0
69-
}
70-
71154
/// Returns the credentials of the task that originally opened the file.
72155
pub fn cred(&self) -> &Credential {
73156
// SAFETY: The file is valid because the shared reference guarantees a nonzero refcount.
@@ -79,6 +162,8 @@ impl File {
79162
}
80163

81164
/// Returns the flags associated with the file.
165+
///
166+
/// The flags are a combination of the constants in [`FileFlags`].
82167
pub fn flags(&self) -> u32 {
83168
// SAFETY: The file is valid because the shared reference guarantees a nonzero refcount.
84169
unsafe { core::ptr::addr_of!((*self.0.get()).f_flags).read() }

samples/rust/rust_random.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! <https://github.com/alex/just-use/blob/master/src/lib.rs>.
77
88
use kernel::{
9-
file::{self, File},
9+
file::{self, File, FileFlags},
1010
io_buffer::{IoBufferReader, IoBufferWriter},
1111
prelude::*,
1212
};
@@ -34,8 +34,9 @@ impl file::Operations for RandomFile {
3434
while !buf.is_empty() {
3535
let len = chunkbuf.len().min(buf.len());
3636
let chunk = &mut chunkbuf[0..len];
37+
let blocking = (file.flags() & FileFlags::O_NONBLOCK) == 0;
3738

38-
if file.is_blocking() {
39+
if blocking {
3940
kernel::random::getrandom(chunk)?;
4041
} else {
4142
kernel::random::getrandom_nonblock(chunk)?;

0 commit comments

Comments
 (0)