Skip to content

Commit abc5c22

Browse files
authored
os.waitstatus_to_exitcode for windows (RustPython#6355)
1 parent 42d0a58 commit abc5c22

File tree

2 files changed

+19
-18
lines changed

2 files changed

+19
-18
lines changed

Lib/test/test_os.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,7 +3426,6 @@ def test_waitstatus_to_exitcode(self):
34263426
with self.assertRaises(TypeError):
34273427
os.waitstatus_to_exitcode(0.0)
34283428

3429-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.spawnv not implemented yet for all platforms')
34303429
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
34313430
def test_waitpid_windows(self):
34323431
# bpo-40138: test os.waitpid() and os.waitstatus_to_exitcode()
@@ -3435,7 +3434,6 @@ def test_waitpid_windows(self):
34353434
code = f'import _winapi; _winapi.ExitProcess({STATUS_CONTROL_C_EXIT})'
34363435
self.check_waitpid(code, exitcode=STATUS_CONTROL_C_EXIT)
34373436

3438-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OverflowError: Python int too large to convert to Rust i32)')
34393437
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
34403438
def test_waitstatus_to_exitcode_windows(self):
34413439
max_exitcode = 2 ** 32 - 1

crates/vm/src/stdlib/os.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,29 +1444,32 @@ pub(super) mod _os {
14441444
Ok((loadavg[0], loadavg[1], loadavg[2]))
14451445
}
14461446

1447-
#[cfg(any(unix, windows))]
1447+
#[cfg(unix)]
14481448
#[pyfunction]
14491449
fn waitstatus_to_exitcode(status: i32, vm: &VirtualMachine) -> PyResult<i32> {
14501450
let status = u32::try_from(status)
14511451
.map_err(|_| vm.new_value_error(format!("invalid WEXITSTATUS: {status}")))?;
14521452

1453-
cfg_if::cfg_if! {
1454-
if #[cfg(not(windows))] {
1455-
let status = status as libc::c_int;
1456-
if libc::WIFEXITED(status) {
1457-
return Ok(libc::WEXITSTATUS(status));
1458-
}
1459-
1460-
if libc::WIFSIGNALED(status) {
1461-
return Ok(-libc::WTERMSIG(status));
1462-
}
1453+
let status = status as libc::c_int;
1454+
if libc::WIFEXITED(status) {
1455+
return Ok(libc::WEXITSTATUS(status));
1456+
}
14631457

1464-
Err(vm.new_value_error(format!("Invalid wait status: {status}")))
1465-
} else {
1466-
i32::try_from(status.rotate_right(8))
1467-
.map_err(|_| vm.new_value_error(format!("invalid wait status: {status}")))
1468-
}
1458+
if libc::WIFSIGNALED(status) {
1459+
return Ok(-libc::WTERMSIG(status));
14691460
}
1461+
1462+
Err(vm.new_value_error(format!("Invalid wait status: {status}")))
1463+
}
1464+
1465+
#[cfg(windows)]
1466+
#[pyfunction]
1467+
fn waitstatus_to_exitcode(status: u64, vm: &VirtualMachine) -> PyResult<u32> {
1468+
let exitcode = status >> 8;
1469+
// ExitProcess() accepts an UINT type:
1470+
// reject exit code which doesn't fit in an UINT
1471+
u32::try_from(exitcode)
1472+
.map_err(|_| vm.new_value_error(format!("Invalid exit code: {exitcode}")))
14701473
}
14711474

14721475
#[pyfunction]

0 commit comments

Comments
 (0)