1+ use crate :: guest:: user;
2+ use crate :: hidpipe_common:: {
3+ empty_input_event, struct_to_socket, AddDevice , ClientHello , FFErase , FFUpload , InputEvent ,
4+ MessageType , RemoveDevice , ServerHello ,
5+ } ;
16use input_linux:: bitmask:: BitmaskTrait ;
27use input_linux:: {
38 AbsoluteAxis , AbsoluteInfo , Bitmask , EventKind , ForceFeedbackKind , InputProperty , Key , LedKind ,
@@ -7,20 +12,16 @@ use input_linux_sys::{
712 ff_effect, ff_replay, ff_trigger, input_absinfo, input_id, uinput_abs_setup, uinput_ff_erase,
813 uinput_ff_upload, uinput_setup,
914} ;
10- use muvm:: hidpipe_common:: {
11- empty_input_event, struct_to_socket, AddDevice , ClientHello , FFErase , FFUpload , InputEvent ,
12- MessageType , RemoveDevice , ServerHello ,
13- } ;
1415use nix:: errno:: Errno ;
1516use nix:: libc:: { c_char, O_NONBLOCK } ;
1617use nix:: sys:: epoll:: { Epoll , EpollCreateFlags , EpollEvent , EpollFlags , EpollTimeout } ;
1718use nix:: sys:: socket:: { connect, socket, AddressFamily , SockFlag , SockType , VsockAddr } ;
1819use std:: collections:: HashMap ;
19- use std:: env ;
20+ use std:: ffi :: CString ;
2021use std:: fs:: File ;
2122use std:: io:: { Read , Write } ;
2223use std:: os:: fd:: AsRawFd ;
23- use std:: os:: unix:: fs:: { chown , OpenOptionsExt } ;
24+ use std:: os:: unix:: fs:: OpenOptionsExt ;
2425use std:: os:: unix:: net:: UnixStream ;
2526use std:: { mem, slice} ;
2627
@@ -29,6 +30,7 @@ const REMOVE_DEVICE: u32 = MessageType::RemoveDevice as u32;
2930const INPUT_EVENT : u32 = MessageType :: InputEvent as u32 ;
3031const FF_UPLOAD : u32 = MessageType :: FFUpload as u32 ;
3132const FF_ERASE : u32 = MessageType :: FFErase as u32 ;
33+ pub const UINPUT_PATH : & str = "/dev/uinput" ;
3234
3335fn bitmask_from_slice < T , A > ( s : & T :: Array ) -> Bitmask < T >
3436where
@@ -53,7 +55,7 @@ fn init_uinput(sock: &mut UnixStream, user_id: u32) -> (u64, UInputHandle<File>)
5355 . read ( true )
5456 . write ( true )
5557 . custom_flags ( O_NONBLOCK )
56- . open ( "/dev/uinput" )
58+ . open ( UINPUT_PATH )
5759 . unwrap ( ) ,
5860 ) ;
5961 for evbit in bitmask_from_slice :: < EventKind , _ > ( & add_dev. evbits ) . iter ( ) {
@@ -119,7 +121,18 @@ fn init_uinput(sock: &mut UnixStream, user_id: u32) -> (u64, UInputHandle<File>)
119121 } )
120122 . unwrap ( ) ;
121123 uinput. dev_create ( ) . unwrap ( ) ;
122- chown ( uinput. evdev_path ( ) . unwrap ( ) , Some ( user_id) , Some ( 0 ) ) . unwrap ( ) ;
124+ let ev_path = CString :: new (
125+ uinput
126+ . evdev_path ( )
127+ . unwrap ( )
128+ . into_os_string ( )
129+ . into_encoded_bytes ( ) ,
130+ )
131+ . unwrap ( ) ;
132+ // SAFETY: chown is async signal safe
133+ unsafe {
134+ user:: run_as_root ( || nix:: libc:: chown ( ev_path. as_ptr ( ) , user_id, 0 ) ) . unwrap ( ) ;
135+ }
123136 ( add_dev. id , uinput)
124137}
125138
@@ -140,8 +153,7 @@ fn ff_effect_empty() -> ff_effect {
140153 }
141154}
142155
143- fn main ( ) {
144- let user_id = env:: args ( ) . nth ( 1 ) . unwrap ( ) . parse :: < u32 > ( ) . unwrap ( ) ;
156+ pub fn start_hidpipe ( user_id : u32 ) {
145157 let sock_fd = socket (
146158 AddressFamily :: Vsock ,
147159 SockType :: Stream ,
0 commit comments