@@ -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 ;
@@ -1604,7 +1604,7 @@ struct PosixSpawnArgs {
1604
1604
#[ pyarg( positional_only) ]
1605
1605
args : PyIterable < PyPathLike > ,
1606
1606
#[ pyarg( positional_only) ]
1607
- env : PyDictRef ,
1607
+ env : PyMapping ,
1608
1608
#[ pyarg( keyword_only, default = "None" ) ]
1609
1609
file_actions : Option < PyIterable < PyTupleRef > > ,
1610
1610
#[ pyarg( keyword_only, default = "None" ) ]
@@ -1710,7 +1710,7 @@ impl PosixSpawnArgs {
1710
1710
. map ( |s| s. as_ptr ( ) as _ )
1711
1711
. chain ( std:: iter:: once ( std:: ptr:: null_mut ( ) ) )
1712
1712
. collect ( ) ;
1713
- let mut env = envp_from_dict ( self . env , vm) ?;
1713
+ let mut env = envp_from_dict ( self . env . into_dict ( ) , vm) ?;
1714
1714
let envp: Vec < * mut libc:: c_char > = env
1715
1715
. iter_mut ( )
1716
1716
. map ( |s| s. as_ptr ( ) as _ )
@@ -1757,6 +1757,44 @@ fn os_posix_spawnp(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult<libc::
1757
1757
args. spawn ( true , vm)
1758
1758
}
1759
1759
1760
+ #[ cfg( unix) ]
1761
+ fn os_wifsignaled ( status : i32 ) -> bool {
1762
+ unsafe { libc:: WIFSIGNALED ( status) }
1763
+ }
1764
+ #[ cfg( unix) ]
1765
+ fn os_wifstopped ( status : i32 ) -> bool {
1766
+ unsafe { libc:: WIFSTOPPED ( status) }
1767
+ }
1768
+ #[ cfg( unix) ]
1769
+ fn os_wifexited ( status : i32 ) -> bool {
1770
+ unsafe { libc:: WIFEXITED ( status) }
1771
+ }
1772
+ #[ cfg( unix) ]
1773
+ fn os_wtermsig ( status : i32 ) -> i32 {
1774
+ unsafe { libc:: WTERMSIG ( status) }
1775
+ }
1776
+ #[ cfg( unix) ]
1777
+ fn os_wstopsig ( status : i32 ) -> i32 {
1778
+ unsafe { libc:: WSTOPSIG ( status) }
1779
+ }
1780
+ #[ cfg( unix) ]
1781
+ fn os_wexitstatus ( status : i32 ) -> i32 {
1782
+ unsafe { libc:: WEXITSTATUS ( status) }
1783
+ }
1784
+
1785
+ // TODO: os.wait[pid] for windows
1786
+ #[ cfg( unix) ]
1787
+ fn os_waitpid ( pid : libc:: pid_t , opt : i32 , vm : & VirtualMachine ) -> PyResult < ( libc:: pid_t , i32 ) > {
1788
+ let mut status = 0 ;
1789
+ let pid = unsafe { libc:: waitpid ( pid, & mut status, opt) } ;
1790
+ let pid = Errno :: result ( pid) . map_err ( |e| convert_nix_error ( vm, e. into ( ) ) ) ?;
1791
+ Ok ( ( pid, status) )
1792
+ }
1793
+ #[ cfg( unix) ]
1794
+ fn os_wait ( vm : & VirtualMachine ) -> PyResult < ( libc:: pid_t , i32 ) > {
1795
+ os_waitpid ( -1 , 0 , vm)
1796
+ }
1797
+
1760
1798
pub fn make_module ( vm : & VirtualMachine ) -> PyObjectRef {
1761
1799
let ctx = & vm. ctx ;
1762
1800
@@ -1945,6 +1983,15 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
1945
1983
"ttyname" => ctx. new_function( os_ttyname) ,
1946
1984
"uname" => ctx. new_function( os_uname) ,
1947
1985
"uname_result" => uname_result,
1986
+ "wait" => ctx. new_function( os_wait) ,
1987
+ "waitpid" => ctx. new_function( os_waitpid) ,
1988
+ "WIFSIGNALED" => ctx. new_function( os_wifsignaled) ,
1989
+ "WIFSTOPPED" => ctx. new_function( os_wifstopped) ,
1990
+ "WIFEXITED" => ctx. new_function( os_wifexited) ,
1991
+ "WTERMSIG" => ctx. new_function( os_wtermsig) ,
1992
+ "WSTOPSIG" => ctx. new_function( os_wstopsig) ,
1993
+ "WEXITSTATUS" => ctx. new_function( os_wexitstatus) ,
1994
+ "WNOHANG" => ctx. new_int( libc:: WNOHANG ) ,
1948
1995
"EX_OK" => ctx. new_int( exitcode:: OK as i8 ) ,
1949
1996
"EX_USAGE" => ctx. new_int( exitcode:: USAGE as i8 ) ,
1950
1997
"EX_DATAERR" => ctx. new_int( exitcode:: DATAERR as i8 ) ,
0 commit comments