@@ -30,7 +30,7 @@ use crate::exceptions::PyBaseExceptionRef;
30
30
use crate :: function:: { IntoPyNativeFunc , OptionalArg , PyFuncArgs } ;
31
31
use crate :: obj:: objbyteinner:: PyBytesLike ;
32
32
use crate :: obj:: objbytes:: { PyBytes , PyBytesRef } ;
33
- use crate :: obj:: objdict:: PyDictRef ;
33
+ use crate :: obj:: objdict:: { PyDictRef , PyMapping } ;
34
34
use crate :: obj:: objint:: PyIntRef ;
35
35
use crate :: obj:: objiter;
36
36
use crate :: obj:: objset:: PySet ;
@@ -1615,7 +1615,7 @@ struct PosixSpawnArgs {
1615
1615
#[ pyarg( positional_only) ]
1616
1616
args : PyIterable < PyPathLike > ,
1617
1617
#[ pyarg( positional_only) ]
1618
- env : PyDictRef ,
1618
+ env : PyMapping ,
1619
1619
#[ pyarg( keyword_only, default = "None" ) ]
1620
1620
file_actions : Option < PyIterable < PyTupleRef > > ,
1621
1621
#[ pyarg( keyword_only, default = "None" ) ]
@@ -1721,7 +1721,7 @@ impl PosixSpawnArgs {
1721
1721
. map ( |s| s. as_ptr ( ) as _ )
1722
1722
. chain ( std:: iter:: once ( std:: ptr:: null_mut ( ) ) )
1723
1723
. collect ( ) ;
1724
- let mut env = envp_from_dict ( self . env , vm) ?;
1724
+ let mut env = envp_from_dict ( self . env . into_dict ( ) , vm) ?;
1725
1725
let envp: Vec < * mut libc:: c_char > = env
1726
1726
. iter_mut ( )
1727
1727
. map ( |s| s. as_ptr ( ) as _ )
@@ -1768,6 +1768,44 @@ fn os_posix_spawnp(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult<libc::
1768
1768
args. spawn ( true , vm)
1769
1769
}
1770
1770
1771
+ #[ cfg( unix) ]
1772
+ fn os_wifsignaled ( status : i32 ) -> bool {
1773
+ unsafe { libc:: WIFSIGNALED ( status) }
1774
+ }
1775
+ #[ cfg( unix) ]
1776
+ fn os_wifstopped ( status : i32 ) -> bool {
1777
+ unsafe { libc:: WIFSTOPPED ( status) }
1778
+ }
1779
+ #[ cfg( unix) ]
1780
+ fn os_wifexited ( status : i32 ) -> bool {
1781
+ unsafe { libc:: WIFEXITED ( status) }
1782
+ }
1783
+ #[ cfg( unix) ]
1784
+ fn os_wtermsig ( status : i32 ) -> i32 {
1785
+ unsafe { libc:: WTERMSIG ( status) }
1786
+ }
1787
+ #[ cfg( unix) ]
1788
+ fn os_wstopsig ( status : i32 ) -> i32 {
1789
+ unsafe { libc:: WSTOPSIG ( status) }
1790
+ }
1791
+ #[ cfg( unix) ]
1792
+ fn os_wexitstatus ( status : i32 ) -> i32 {
1793
+ unsafe { libc:: WEXITSTATUS ( status) }
1794
+ }
1795
+
1796
+ // TODO: os.wait[pid] for windows
1797
+ #[ cfg( unix) ]
1798
+ fn os_waitpid ( pid : libc:: pid_t , opt : i32 , vm : & VirtualMachine ) -> PyResult < ( libc:: pid_t , i32 ) > {
1799
+ let mut status = 0 ;
1800
+ let pid = unsafe { libc:: waitpid ( pid, & mut status, opt) } ;
1801
+ let pid = Errno :: result ( pid) . map_err ( |e| convert_nix_error ( vm, e) ) ?;
1802
+ Ok ( ( pid, status) )
1803
+ }
1804
+ #[ cfg( unix) ]
1805
+ fn os_wait ( vm : & VirtualMachine ) -> PyResult < ( libc:: pid_t , i32 ) > {
1806
+ os_waitpid ( -1 , 0 , vm)
1807
+ }
1808
+
1771
1809
pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
1772
1810
let ctx = & vm. ctx ;
1773
1811
@@ -1956,6 +1994,15 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
1956
1994
"ttyname" => ctx. new_function( os_ttyname) ,
1957
1995
"uname" => ctx. new_function( os_uname) ,
1958
1996
"uname_result" => uname_result,
1997
+ "wait" => ctx. new_function( os_wait) ,
1998
+ "waitpid" => ctx. new_function( os_waitpid) ,
1999
+ "WIFSIGNALED" => ctx. new_function( os_wifsignaled) ,
2000
+ "WIFSTOPPED" => ctx. new_function( os_wifstopped) ,
2001
+ "WIFEXITED" => ctx. new_function( os_wifexited) ,
2002
+ "WTERMSIG" => ctx. new_function( os_wtermsig) ,
2003
+ "WSTOPSIG" => ctx. new_function( os_wstopsig) ,
2004
+ "WEXITSTATUS" => ctx. new_function( os_wexitstatus) ,
2005
+ "WNOHANG" => ctx. new_int( libc:: WNOHANG ) ,
1959
2006
"EX_OK" => ctx. new_int( exitcode:: OK as i8 ) ,
1960
2007
"EX_USAGE" => ctx. new_int( exitcode:: USAGE as i8 ) ,
1961
2008
"EX_DATAERR" => ctx. new_int( exitcode:: DATAERR as i8 ) ,
0 commit comments