Skip to content

Commit e5ab853

Browse files
committed
Add os.wait[pid] and associated functions/constants
1 parent 5aeb778 commit e5ab853

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

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

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;
@@ -1604,7 +1604,7 @@ struct PosixSpawnArgs {
16041604
#[pyarg(positional_only)]
16051605
args: PyIterable<PyPathLike>,
16061606
#[pyarg(positional_only)]
1607-
env: PyDictRef,
1607+
env: PyMapping,
16081608
#[pyarg(keyword_only, default = "None")]
16091609
file_actions: Option<PyIterable<PyTupleRef>>,
16101610
#[pyarg(keyword_only, default = "None")]
@@ -1710,7 +1710,7 @@ impl PosixSpawnArgs {
17101710
.map(|s| s.as_ptr() as _)
17111711
.chain(std::iter::once(std::ptr::null_mut()))
17121712
.collect();
1713-
let mut env = envp_from_dict(self.env, vm)?;
1713+
let mut env = envp_from_dict(self.env.into_dict(), vm)?;
17141714
let envp: Vec<*mut libc::c_char> = env
17151715
.iter_mut()
17161716
.map(|s| s.as_ptr() as _)
@@ -1757,6 +1757,44 @@ fn os_posix_spawnp(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult<libc::
17571757
args.spawn(true, vm)
17581758
}
17591759

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

@@ -1945,6 +1983,15 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
19451983
"ttyname" => ctx.new_function(os_ttyname),
19461984
"uname" => ctx.new_function(os_uname),
19471985
"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),
19481995
"EX_OK" => ctx.new_int(exitcode::OK as i8),
19491996
"EX_USAGE" => ctx.new_int(exitcode::USAGE as i8),
19501997
"EX_DATAERR" => ctx.new_int(exitcode::DATAERR as i8),

0 commit comments

Comments
 (0)