(
mode: i32,
path: OsPath,
argv: Either<PyListRef, PyTupleRef>,
env: PyDictRef,
vm: &VirtualMachine,
)
| 1101 | #[cfg(target_env = "msvc")] |
| 1102 | #[pyfunction] |
| 1103 | fn spawnve( |
| 1104 | mode: i32, |
| 1105 | path: OsPath, |
| 1106 | argv: Either<PyListRef, PyTupleRef>, |
| 1107 | env: PyDictRef, |
| 1108 | vm: &VirtualMachine, |
| 1109 | ) -> PyResult<intptr_t> { |
| 1110 | use crate::function::FsPath; |
| 1111 | use core::iter::once; |
| 1112 | |
| 1113 | let path = path.to_wide_cstring(vm)?; |
| 1114 | |
| 1115 | let argv = vm.extract_elements_with(argv.as_ref(), |obj| { |
| 1116 | let fspath = FsPath::try_from_path_like(obj, true, vm)?; |
| 1117 | fspath.to_wide_cstring(vm) |
| 1118 | })?; |
| 1119 | |
| 1120 | let first = argv |
| 1121 | .first() |
| 1122 | .ok_or_else(|| vm.new_value_error("spawnve() arg 2 cannot be empty"))?; |
| 1123 | |
| 1124 | if first.is_empty() { |
| 1125 | return Err(vm.new_value_error("spawnve() arg 2 first element cannot be empty")); |
| 1126 | } |
| 1127 | |
| 1128 | let argv_spawn: Vec<*const u16> = argv |
| 1129 | .iter() |
| 1130 | .map(|v| v.as_ptr()) |
| 1131 | .chain(once(core::ptr::null())) |
| 1132 | .collect(); |
| 1133 | |
| 1134 | // Build environment strings as "KEY=VALUE\0" wide strings |
| 1135 | let mut env_strings: Vec<widestring::WideCString> = Vec::new(); |
| 1136 | for (key, value) in env.into_iter() { |
| 1137 | let key = FsPath::try_from_path_like(key, true, vm)?; |
| 1138 | let value = FsPath::try_from_path_like(value, true, vm)?; |
| 1139 | let key_str = key.to_string_lossy(); |
| 1140 | let value_str = value.to_string_lossy(); |
| 1141 | |
| 1142 | // Validate: empty key or '=' in key after position 0 |
| 1143 | // (search from index 1 because on Windows starting '=' is allowed |
| 1144 | // for defining hidden environment variables) |
| 1145 | if key_str.is_empty() || key_str.get(1..).is_some_and(|s| s.contains('=')) { |
| 1146 | return Err(vm.new_value_error("illegal environment variable name")); |
| 1147 | } |
| 1148 | |
| 1149 | let env_str = format!("{}={}", key_str, value_str); |
| 1150 | env_strings.push( |
| 1151 | widestring::WideCString::from_os_str(&*std::ffi::OsString::from(env_str)) |
| 1152 | .map_err(|err| err.to_pyexception(vm))?, |
| 1153 | ); |
| 1154 | } |
| 1155 | |
| 1156 | let envp: Vec<*const u16> = env_strings |
| 1157 | .iter() |
| 1158 | .map(|s| s.as_ptr()) |
| 1159 | .chain(once(core::ptr::null())) |
| 1160 | .collect(); |
nothing calls this directly
no test coverage detected