@@ -446,26 +446,44 @@ macro_rules! declare_file_operations {
446
446
///
447
447
/// For each macro, there is a handler function that takes the appropriate types as arguments.
448
448
pub trait IoctlHandler : Sync {
449
+ /// The type of the first argument to each associated function.
450
+ type Target ;
451
+
449
452
/// 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 > {
451
454
Err ( Error :: EINVAL )
452
455
}
453
456
454
457
/// Handles ioctls defined with the `_IOR` macro, that is, with an output buffer provided as
455
458
/// 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 > {
457
465
Err ( Error :: EINVAL )
458
466
}
459
467
460
468
/// Handles ioctls defined with the `_IOW` macro, that is, with an input buffer provided as
461
469
/// 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 > {
463
476
Err ( Error :: EINVAL )
464
477
}
465
478
466
479
/// Handles ioctls defined with the `_IOWR` macro, that is, with a buffer for both input and
467
480
/// 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 > {
469
487
Err ( Error :: EINVAL )
470
488
}
471
489
}
@@ -501,18 +519,18 @@ impl IoctlCommand {
501
519
///
502
520
/// It is meant to be used in implementations of [`FileOperations::ioctl`] and
503
521
/// [`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 > {
505
523
let dir = ( self . cmd >> bindings:: _IOC_DIRSHIFT) & bindings:: _IOC_DIRMASK;
506
524
if dir == bindings:: _IOC_NONE {
507
- return handler . pure ( file, self . cmd , self . arg ) ;
525
+ return T :: pure ( handler , file, self . cmd , self . arg ) ;
508
526
}
509
527
510
528
let data = self . user_slice . take ( ) . ok_or ( Error :: EINVAL ) ?;
511
529
const READ_WRITE : u32 = bindings:: _IOC_READ | bindings:: _IOC_WRITE;
512
530
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) ,
516
534
_ => Err ( Error :: EINVAL ) ,
517
535
}
518
536
}
0 commit comments