Skip to content

Commit a5a22ed

Browse files
authored
Merge pull request #388 from wedsonaf/ioctl
rust: update IoctlHandler to allow arbitrary type as well.
2 parents 0559333 + 12ab579 commit a5a22ed

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

drivers/android/process.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -766,27 +766,29 @@ impl Process {
766766
}
767767

768768
impl IoctlHandler for Process {
769-
fn write(&self, _file: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> {
770-
let thread = self.get_thread(unsafe { rust_helper_current_pid() })?;
769+
type Target = Self;
770+
771+
fn write(this: &Self, _file: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> {
772+
let thread = this.get_thread(unsafe { rust_helper_current_pid() })?;
771773
match cmd {
772-
bindings::BINDER_SET_MAX_THREADS => self.set_max_threads(reader.read()?),
773-
bindings::BINDER_SET_CONTEXT_MGR => self.set_as_manager(None, &thread)?,
774-
bindings::BINDER_THREAD_EXIT => self.remove_thread(thread),
774+
bindings::BINDER_SET_MAX_THREADS => this.set_max_threads(reader.read()?),
775+
bindings::BINDER_SET_CONTEXT_MGR => this.set_as_manager(None, &thread)?,
776+
bindings::BINDER_THREAD_EXIT => this.remove_thread(thread),
775777
bindings::BINDER_SET_CONTEXT_MGR_EXT => {
776-
self.set_as_manager(Some(reader.read()?), &thread)?
778+
this.set_as_manager(Some(reader.read()?), &thread)?
777779
}
778780
_ => return Err(Error::EINVAL),
779781
}
780782
Ok(0)
781783
}
782784

783-
fn read_write(&self, file: &File, cmd: u32, data: UserSlicePtr) -> Result<i32> {
784-
let thread = self.get_thread(unsafe { rust_helper_current_pid() })?;
785+
fn read_write(this: &Self, file: &File, cmd: u32, data: UserSlicePtr) -> Result<i32> {
786+
let thread = this.get_thread(unsafe { rust_helper_current_pid() })?;
785787
match cmd {
786788
bindings::BINDER_WRITE_READ => thread.write_read(data, file.is_blocking())?,
787-
bindings::BINDER_GET_NODE_DEBUG_INFO => self.get_node_debug_info(data)?,
788-
bindings::BINDER_GET_NODE_INFO_FOR_REF => self.get_node_info_from_ref(data)?,
789-
bindings::BINDER_VERSION => self.version(data)?,
789+
bindings::BINDER_GET_NODE_DEBUG_INFO => this.get_node_debug_info(data)?,
790+
bindings::BINDER_GET_NODE_INFO_FOR_REF => this.get_node_info_from_ref(data)?,
791+
bindings::BINDER_VERSION => this.version(data)?,
790792
_ => return Err(Error::EINVAL),
791793
}
792794
Ok(0)

rust/kernel/file_operations.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,26 +446,44 @@ macro_rules! declare_file_operations {
446446
///
447447
/// For each macro, there is a handler function that takes the appropriate types as arguments.
448448
pub trait IoctlHandler: Sync {
449+
/// The type of the first argument to each associated function.
450+
type Target;
451+
449452
/// Handles ioctls defined with the `_IO` macro, that is, with no buffer as argument.
450-
fn pure(&self, _file: &File, _cmd: u32, _arg: usize) -> Result<i32> {
453+
fn pure(_this: &Self::Target, _file: &File, _cmd: u32, _arg: usize) -> Result<i32> {
451454
Err(Error::EINVAL)
452455
}
453456

454457
/// Handles ioctls defined with the `_IOR` macro, that is, with an output buffer provided as
455458
/// argument.
456-
fn read(&self, _file: &File, _cmd: u32, _writer: &mut UserSlicePtrWriter) -> Result<i32> {
459+
fn read(
460+
_this: &Self::Target,
461+
_file: &File,
462+
_cmd: u32,
463+
_writer: &mut UserSlicePtrWriter,
464+
) -> Result<i32> {
457465
Err(Error::EINVAL)
458466
}
459467

460468
/// Handles ioctls defined with the `_IOW` macro, that is, with an input buffer provided as
461469
/// argument.
462-
fn write(&self, _file: &File, _cmd: u32, _reader: &mut UserSlicePtrReader) -> Result<i32> {
470+
fn write(
471+
_this: &Self::Target,
472+
_file: &File,
473+
_cmd: u32,
474+
_reader: &mut UserSlicePtrReader,
475+
) -> Result<i32> {
463476
Err(Error::EINVAL)
464477
}
465478

466479
/// Handles ioctls defined with the `_IOWR` macro, that is, with a buffer for both input and
467480
/// output provided as argument.
468-
fn read_write(&self, _file: &File, _cmd: u32, _data: UserSlicePtr) -> Result<i32> {
481+
fn read_write(
482+
_this: &Self::Target,
483+
_file: &File,
484+
_cmd: u32,
485+
_data: UserSlicePtr,
486+
) -> Result<i32> {
469487
Err(Error::EINVAL)
470488
}
471489
}
@@ -501,18 +519,18 @@ impl IoctlCommand {
501519
///
502520
/// It is meant to be used in implementations of [`FileOperations::ioctl`] and
503521
/// [`FileOperations::compat_ioctl`].
504-
pub fn dispatch<T: IoctlHandler>(&mut self, handler: &T, file: &File) -> Result<i32> {
522+
pub fn dispatch<T: IoctlHandler>(&mut self, handler: &T::Target, file: &File) -> Result<i32> {
505523
let dir = (self.cmd >> bindings::_IOC_DIRSHIFT) & bindings::_IOC_DIRMASK;
506524
if dir == bindings::_IOC_NONE {
507-
return handler.pure(file, self.cmd, self.arg);
525+
return T::pure(handler, file, self.cmd, self.arg);
508526
}
509527

510528
let data = self.user_slice.take().ok_or(Error::EINVAL)?;
511529
const READ_WRITE: u32 = bindings::_IOC_READ | bindings::_IOC_WRITE;
512530
match dir {
513-
bindings::_IOC_WRITE => handler.write(file, self.cmd, &mut data.reader()),
514-
bindings::_IOC_READ => handler.read(file, self.cmd, &mut data.writer()),
515-
READ_WRITE => handler.read_write(file, self.cmd, data),
531+
bindings::_IOC_WRITE => T::write(handler, file, self.cmd, &mut data.reader()),
532+
bindings::_IOC_READ => T::read(handler, file, self.cmd, &mut data.writer()),
533+
READ_WRITE => T::read_write(handler, file, self.cmd, data),
516534
_ => Err(Error::EINVAL),
517535
}
518536
}

samples/rust/rust_semaphore.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,20 +153,22 @@ const IOCTL_GET_READ_COUNT: u32 = 0x80086301;
153153
const IOCTL_SET_READ_COUNT: u32 = 0x40086301;
154154

155155
impl IoctlHandler for FileState {
156-
fn read(&self, _: &File, cmd: u32, writer: &mut UserSlicePtrWriter) -> Result<i32> {
156+
type Target = Self;
157+
158+
fn read(this: &Self, _: &File, cmd: u32, writer: &mut UserSlicePtrWriter) -> Result<i32> {
157159
match cmd {
158160
IOCTL_GET_READ_COUNT => {
159-
writer.write(&self.read_count.load(Ordering::Relaxed))?;
161+
writer.write(&this.read_count.load(Ordering::Relaxed))?;
160162
Ok(0)
161163
}
162164
_ => Err(Error::EINVAL),
163165
}
164166
}
165167

166-
fn write(&self, _: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> {
168+
fn write(this: &Self, _: &File, cmd: u32, reader: &mut UserSlicePtrReader) -> Result<i32> {
167169
match cmd {
168170
IOCTL_SET_READ_COUNT => {
169-
self.read_count.store(reader.read()?, Ordering::Relaxed);
171+
this.read_count.store(reader.read()?, Ordering::Relaxed);
170172
Ok(0)
171173
}
172174
_ => Err(Error::EINVAL),

0 commit comments

Comments
 (0)