Skip to content

Commit e20a767

Browse files
author
Minjun Shin
authored
os.execv implementation for unix systems
Uses nix::unistd::execv for implementation.
1 parent fa2d617 commit e20a767

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

vm/src/stdlib/os.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ use crate::vm::VirtualMachine;
4747
#[cfg(unix)]
4848
use crate::obj::objdict::PyMapping;
4949
#[cfg(unix)]
50+
use crate::obj::objlist::PyListRef;
51+
#[cfg(unix)]
5052
use crate::pyobject::PyIterable;
5153
#[cfg(unix)]
5254
use std::convert::TryFrom;
@@ -1271,6 +1273,33 @@ fn os_chmod(
12711273
Ok(())
12721274
}
12731275

1276+
#[cfg(unix)]
1277+
fn os_execv(
1278+
path: PyStringRef,
1279+
argv_list: Either<PyListRef, PyTupleRef>,
1280+
vm: &VirtualMachine,
1281+
) -> PyResult<()> {
1282+
let path = ffi::CString::new(path.as_str())
1283+
.map_err(|_| vm.new_value_error("embedded null character".to_owned()))?;
1284+
1285+
let argv: Vec<ffi::CString> = match argv_list {
1286+
Either::A(list) => vm.extract_elements(list.as_object())?,
1287+
Either::B(tuple) => vm.extract_elements(tuple.as_object())?,
1288+
};
1289+
let argv: Vec<&ffi::CStr> = argv.iter().map(|entry| entry.as_c_str()).collect();
1290+
1291+
if argv.is_empty() {
1292+
return Err(vm.new_value_error("execv() arg 2 must not be empty".to_owned()));
1293+
}
1294+
if argv.first().unwrap().to_bytes().is_empty() {
1295+
return Err(vm.new_value_error("execv() arg 2 first element cannot be empty".to_owned()));
1296+
}
1297+
1298+
unistd::execv(&path, &argv)
1299+
.map(|_ok| ())
1300+
.map_err(|err| convert_nix_error(vm, err))
1301+
}
1302+
12741303
fn os_fspath(path: PyPathLike, vm: &VirtualMachine) -> PyResult {
12751304
path.mode.process_path(path.path, vm)
12761305
}
@@ -2171,6 +2200,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
21712200
SupportFunc::new(vm, "lchown", os_lchown, None, None, None),
21722201
SupportFunc::new(vm, "fchown", os_fchown, Some(true), None, Some(true)),
21732202
SupportFunc::new(vm, "umask", os_umask, Some(false), Some(false), Some(false)),
2203+
SupportFunc::new(vm, "execv", os_execv, None, None, None),
21742204
]);
21752205
let supports_fd = PySet::default().into_ref(vm);
21762206
let supports_dir_fd = PySet::default().into_ref(vm);
@@ -2268,6 +2298,7 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
22682298

22692299
extend_module!(vm, module, {
22702300
"chmod" => ctx.new_function(os_chmod),
2301+
"execv" => ctx.new_function(os_execv), // TODO: windows
22712302
"get_inheritable" => ctx.new_function(os_get_inheritable), // TODO: windows
22722303
"get_blocking" => ctx.new_function(os_get_blocking),
22732304
"getppid" => ctx.new_function(os_getppid),

0 commit comments

Comments
 (0)