@@ -10,12 +10,16 @@ use nix::{
1010 } ,
1111 unistd:: Pid ,
1212} ;
13- use procfs:: process:: { MMapPath , Process } ;
13+ use procfs:: process:: { MMapPath , Process , Task } ;
14+ use tracing:: info;
1415
1516pub trait EventSource {
1617 fn request_trace ( & self ) -> nix:: Result < ( ) > ;
1718 fn get_offset ( & self , pid : Pid , config : & Config ) -> u64 ;
1819 fn trace_children ( & self , pid : Pid ) -> nix:: Result < ( ) > ;
20+ /// This will be at the start of every wait/handle/continue loop so can be used to pop out and
21+ /// apply state changes which occur when tests are running for any mock event sources. In real
22+ /// life the actual processes under test will be modifying things!
1923 fn waitpid ( & self , pid : Pid , options : Option < WaitPidFlag > ) -> nix:: Result < WaitStatus > ;
2024 fn next_events ( & self , wait_queue : & mut Vec < WaitStatus > ) -> Result < Option < TestState > , RunError > ;
2125 fn get_event_data ( & self , pid : Pid ) -> nix:: Result < c_long > ;
@@ -26,6 +30,9 @@ pub trait EventSource {
2630 fn set_current_instruction_pointer ( & self , pid : Pid , addr : u64 ) -> nix:: Result < c_long > ;
2731 fn write_address ( & self , pid : Pid , addr : u64 , data : c_long ) -> nix:: Result < ( ) > ;
2832 fn read_address ( & self , pid : Pid , addr : u64 ) -> nix:: Result < c_long > ;
33+
34+ fn get_tasks ( & self , pid : Pid ) -> Box < dyn Iterator < Item = Task > + ' _ > ;
35+ fn get_ppid ( & self , pid : Pid ) -> Option < Pid > ;
2936}
3037
3138#[ derive( Clone ) ]
@@ -137,61 +144,23 @@ impl EventSource for PtraceEventSource {
137144 fn read_address ( & self , pid : Pid , address : u64 ) -> nix:: Result < c_long > {
138145 read_address ( pid, address)
139146 }
140- }
141-
142- #[ derive( Clone ) ]
143- pub struct ReplayEventSource { }
144-
145- impl EventSource for ReplayEventSource {
146- fn request_trace ( & self ) -> nix:: Result < ( ) > {
147- Ok ( ( ) )
148- }
149-
150- fn get_offset ( & self , pid : Pid , config : & Config ) -> u64 {
151- 0
152- }
153-
154- fn trace_children ( & self , pid : Pid ) -> nix:: Result < ( ) > {
155- todo ! ( )
156- }
157-
158- fn waitpid ( & self , pid : Pid , options : Option < WaitPidFlag > ) -> nix:: Result < WaitStatus > {
159- todo ! ( )
160- }
161-
162- fn next_events ( & self , wait_queue : & mut Vec < WaitStatus > ) -> Result < Option < TestState > , RunError > {
163- todo ! ( ) ;
164- }
165-
166- fn get_event_data ( & self , pid : Pid ) -> nix:: Result < c_long > {
167- todo ! ( )
168- }
169147
170- fn continue_pid ( & self , pid : Pid , signal : Option < Signal > ) -> nix:: Result < ( ) > {
171- todo ! ( ) ;
172- }
173-
174- fn single_step ( & self , pid : Pid ) -> nix:: Result < ( ) > {
175- todo ! ( ) ;
176- }
177-
178- fn detach_child ( & self , pid : Pid ) -> nix:: Result < ( ) > {
179- todo ! ( )
180- }
181-
182- fn current_instruction_pointer ( & self , pid : Pid ) -> nix:: Result < c_long > {
183- todo ! ( ) ;
184- }
185-
186- fn set_current_instruction_pointer ( & self , pid : Pid , addr : u64 ) -> nix:: Result < c_long > {
187- todo ! ( ) ;
188- }
189-
190- fn write_address ( & self , pid : Pid , address : u64 , data : c_long ) -> nix:: Result < ( ) > {
191- todo ! ( ) ;
148+ fn get_tasks ( & self , pid : Pid ) -> Box < dyn Iterator < Item = Task > + ' _ > {
149+ if let Some ( proc) = Process :: new ( pid. as_raw ( ) ) . ok ( ) . and_then ( |x| x. tasks ( ) . ok ( ) ) {
150+ Box :: new ( proc. filter_map ( Result :: ok) )
151+ } else {
152+ Box :: new ( std:: iter:: empty ( ) )
153+ }
192154 }
193155
194- fn read_address ( & self , pid : Pid , address : u64 ) -> nix:: Result < c_long > {
195- todo ! ( ) ;
156+ fn get_ppid ( & self , pid : Pid ) -> Option < Pid > {
157+ let proc = Process :: new ( pid. as_raw ( ) ) . ok ( ) ?;
158+ if let Ok ( status) = proc. status ( ) {
159+ info ! ( "Found potential parent" ) ;
160+ let pid = Pid :: from_raw ( status. ppid ) ;
161+ Some ( pid)
162+ } else {
163+ None
164+ }
196165 }
197166}
0 commit comments