Skip to content

Commit d40533b

Browse files
coolreader18youknowone
authored andcommitted
Add os.wait[pid] and associated functions/constants
1 parent 05a0202 commit d40533b

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

vm/src/function.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ impl<T> From<HashMap<String, T>> for KwArgs<T> {
274274
KwArgs(map)
275275
}
276276
}
277+
impl<T> Default for KwArgs<T> {
278+
fn default() -> Self {
279+
KwArgs(HashMap::new())
280+
}
281+
}
277282

278283
impl<T> FromArgs for KwArgs<T>
279284
where

vm/src/obj/objdict.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::exceptions::PyBaseExceptionRef;
1010
use crate::function::{KwArgs, OptionalArg, PyFuncArgs};
1111
use crate::pyobject::{
1212
IdProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable,
13-
PyObjectRef, PyRef, PyResult, PyValue,
13+
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
1414
};
1515
use crate::vm::{ReprGuard, VirtualMachine};
1616

@@ -681,3 +681,26 @@ pub(crate) fn init(context: &PyContext) {
681681
PyDictItems::extend_class(context, &context.types.dictitems_type);
682682
PyDictItemIterator::extend_class(context, &context.types.dictitemiterator_type);
683683
}
684+
685+
pub struct PyMapping {
686+
dict: PyDictRef,
687+
}
688+
689+
impl TryFromObject for PyMapping {
690+
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
691+
let dict = vm.ctx.new_dict();
692+
PyDictRef::merge(
693+
&dict.entries,
694+
OptionalArg::Present(obj),
695+
KwArgs::default(),
696+
vm,
697+
)?;
698+
Ok(PyMapping { dict })
699+
}
700+
}
701+
702+
impl PyMapping {
703+
pub fn into_dict(self) -> PyDictRef {
704+
self.dict
705+
}
706+
}

vm/src/stdlib/os.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::exceptions::PyBaseExceptionRef;
3030
use crate::function::{IntoPyNativeFunc, OptionalArg, PyFuncArgs};
3131
use crate::obj::objbyteinner::PyBytesLike;
3232
use crate::obj::objbytes::{PyBytes, PyBytesRef};
33-
use crate::obj::objdict::PyDictRef;
33+
use crate::obj::objdict::{PyDictRef, PyMapping};
3434
use crate::obj::objint::PyIntRef;
3535
use crate::obj::objiter;
3636
use crate::obj::objset::PySet;
@@ -1615,7 +1615,7 @@ struct PosixSpawnArgs {
16151615
#[pyarg(positional_only)]
16161616
args: PyIterable<PyPathLike>,
16171617
#[pyarg(positional_only)]
1618-
env: PyDictRef,
1618+
env: PyMapping,
16191619
#[pyarg(keyword_only, default = "None")]
16201620
file_actions: Option<PyIterable<PyTupleRef>>,
16211621
#[pyarg(keyword_only, default = "None")]
@@ -1721,7 +1721,7 @@ impl PosixSpawnArgs {
17211721
.map(|s| s.as_ptr() as _)
17221722
.chain(std::iter::once(std::ptr::null_mut()))
17231723
.collect();
1724-
let mut env = envp_from_dict(self.env, vm)?;
1724+
let mut env = envp_from_dict(self.env.into_dict(), vm)?;
17251725
let envp: Vec<*mut libc::c_char> = env
17261726
.iter_mut()
17271727
.map(|s| s.as_ptr() as _)
@@ -1768,6 +1768,44 @@ fn os_posix_spawnp(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult<libc::
17681768
args.spawn(true, vm)
17691769
}
17701770

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+
17711809
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
17721810
let ctx = &vm.ctx;
17731811

@@ -1956,6 +1994,15 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
19561994
"ttyname" => ctx.new_function(os_ttyname),
19571995
"uname" => ctx.new_function(os_uname),
19581996
"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),
19592006
"EX_OK" => ctx.new_int(exitcode::OK as i8),
19602007
"EX_USAGE" => ctx.new_int(exitcode::USAGE as i8),
19612008
"EX_DATAERR" => ctx.new_int(exitcode::DATAERR as i8),

0 commit comments

Comments
 (0)