11use std:: cell:: RefCell ;
2+ use std:: ffi:: OsString ;
23use std:: fs:: File ;
34use std:: time:: Duration ;
45
56use subprocess;
67
78use crate :: function:: OptionalArg ;
9+ use crate :: obj:: objbytes:: PyBytesRef ;
810use crate :: obj:: objlist:: PyListRef ;
911use crate :: obj:: objsequence;
1012use crate :: obj:: objstr:: { self , PyStringRef } ;
1113use crate :: obj:: objtype:: PyClassRef ;
1214use crate :: pyobject:: { Either , IntoPyObject , PyObjectRef , PyRef , PyResult , PyValue } ;
1315use crate :: stdlib:: io:: io_open;
14- use crate :: stdlib:: os:: { raw_file_number, rust_file} ;
16+ use crate :: stdlib:: os:: { convert_io_error , raw_file_number, rust_file} ;
1517use crate :: vm:: VirtualMachine ;
1618
1719#[ derive( Debug ) ]
@@ -37,6 +39,8 @@ struct PopenArgs {
3739 stdout : Option < i64 > ,
3840 #[ pyarg( positional_or_keyword, default = "None" ) ]
3941 stderr : Option < i64 > ,
42+ #[ pyarg( positional_or_keyword, default = "None" ) ]
43+ cwd : Option < PyStringRef > ,
4044}
4145
4246impl IntoPyObject for subprocess:: ExitStatus {
@@ -95,13 +99,15 @@ impl PopenRef {
9599 . map ( |x| objstr:: get_value ( x) )
96100 . collect ( ) ,
97101 } ;
102+ let cwd = args. cwd . map ( |x| OsString :: from ( x. as_str ( ) ) ) ;
98103
99104 let process = subprocess:: Popen :: create (
100105 & command_list,
101106 subprocess:: PopenConfig {
102107 stdin,
103108 stdout,
104109 stderr,
110+ cwd,
105111 ..Default :: default ( )
106112 } ,
107113 )
@@ -149,6 +155,36 @@ impl PopenRef {
149155 fn stderr ( self , vm : & VirtualMachine ) -> PyResult {
150156 convert_to_file_io ( & self . process . borrow ( ) . stderr , "rb" . to_string ( ) , vm)
151157 }
158+
159+ fn terminate ( self , vm : & VirtualMachine ) -> PyResult < ( ) > {
160+ self . process
161+ . borrow_mut ( )
162+ . terminate ( )
163+ . map_err ( |err| convert_io_error ( vm, err) )
164+ }
165+
166+ fn kill ( self , vm : & VirtualMachine ) -> PyResult < ( ) > {
167+ self . process
168+ . borrow_mut ( )
169+ . kill ( )
170+ . map_err ( |err| convert_io_error ( vm, err) )
171+ }
172+
173+ #[ allow( clippy:: type_complexity) ]
174+ fn communicate (
175+ self ,
176+ stdin : OptionalArg < PyBytesRef > ,
177+ vm : & VirtualMachine ,
178+ ) -> PyResult < ( Option < Vec < u8 > > , Option < Vec < u8 > > ) > {
179+ self . process
180+ . borrow_mut ( )
181+ . communicate_bytes ( stdin. into_option ( ) . as_ref ( ) . map ( |bytes| bytes. get_value ( ) ) )
182+ . map_err ( |err| convert_io_error ( vm, err) )
183+ }
184+
185+ fn pid ( self , _vm : & VirtualMachine ) -> Option < u32 > {
186+ self . process . borrow ( ) . pid ( )
187+ }
152188}
153189
154190pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
@@ -165,6 +201,10 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
165201 "stdin" => ctx. new_property( PopenRef :: stdin) ,
166202 "stdout" => ctx. new_property( PopenRef :: stdout) ,
167203 "stderr" => ctx. new_property( PopenRef :: stderr) ,
204+ "terminate" => ctx. new_rustfunc( PopenRef :: terminate) ,
205+ "kill" => ctx. new_rustfunc( PopenRef :: kill) ,
206+ "communicate" => ctx. new_rustfunc( PopenRef :: communicate) ,
207+ "pid" => ctx. new_property( PopenRef :: pid) ,
168208 } ) ;
169209
170210 let module = py_module ! ( vm, "subprocess" , {
0 commit comments