os.execv implementation for unix systems

Uses nix::unistd::execv for implementation.
This commit is contained in:
Minjun Shin authored and GitHub committed 2020-07-29 13:09:27 +09:00
1 parent fa2d6175c5
commit e20a7673e3
1 file changed
+31
+31
View File
@@ -47,6 +47,8 @@ use crate::vm::VirtualMachine;
#[cfg(unix)]
use crate::obj::objdict::PyMapping;
#[cfg(unix)]
use crate::obj::objlist::PyListRef;
#[cfg(unix)]
use crate::pyobject::PyIterable;
#[cfg(unix)]
use std::convert::TryFrom;
@@ -1271,6 +1273,33 @@ fn os_chmod(
Ok(())
}
#[cfg(unix)]
fn os_execv(
path: PyStringRef,
argv_list: Either<PyListRef, PyTupleRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
let path = ffi::CString::new(path.as_str())
.map_err(|_| vm.new_value_error("embedded null character".to_owned()))?;
let argv: Vec<ffi::CString> = match argv_list {
Either::A(list) => vm.extract_elements(list.as_object())?,
Either::B(tuple) => vm.extract_elements(tuple.as_object())?,
};
let argv: Vec<&ffi::CStr> = argv.iter().map(|entry| entry.as_c_str()).collect();
if argv.is_empty() {
return Err(vm.new_value_error("execv() arg 2 must not be empty".to_owned()));
}
if argv.first().unwrap().to_bytes().is_empty() {
return Err(vm.new_value_error("execv() arg 2 first element cannot be empty".to_owned()));
}
unistd::execv(&path, &argv)
.map(|_ok| ())
.map_err(|err| convert_nix_error(vm, err))
}
fn os_fspath(path: PyPathLike, vm: &VirtualMachine) -> PyResult {
path.mode.process_path(path.path, vm)
}
@@ -2171,6 +2200,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
SupportFunc::new(vm, "lchown", os_lchown, None, None, None),
SupportFunc::new(vm, "fchown", os_fchown, Some(true), None, Some(true)),
SupportFunc::new(vm, "umask", os_umask, Some(false), Some(false), Some(false)),
SupportFunc::new(vm, "execv", os_execv, None, None, None),
]);
let supports_fd = PySet::default().into_ref(vm);
let supports_dir_fd = PySet::default().into_ref(vm);
@@ -2268,6 +2298,7 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
extend_module!(vm, module, {
"chmod" => ctx.new_function(os_chmod),
"execv" => ctx.new_function(os_execv), // TODO: windows
"get_inheritable" => ctx.new_function(os_get_inheritable), // TODO: windows
"get_blocking" => ctx.new_function(os_get_blocking),
"getppid" => ctx.new_function(os_getppid),