Skip to content

Commit c5b2b41

Browse files
committed
fix waitstatus_to_exitcode
1 parent a3d638a commit c5b2b41

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
@@ -3431,7 +3431,6 @@ def test_waitstatus_to_exitcode(self):
34313431
with self.assertRaises(TypeError):
34323432
os.waitstatus_to_exitcode(0.0)
34333433

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

3443-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OverflowError: Python int too large to convert to Rust i32)')
34443442
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
34453443
def test_waitstatus_to_exitcode_windows(self):
34463444
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
@@ -1421,29 +1421,32 @@ pub(super) mod _os {
14211421
Ok((loadavg[0], loadavg[1], loadavg[2]))
14221422
}
14231423

1424-
#[cfg(any(unix, windows))]
1424+
#[cfg(unix)]
14251425
#[pyfunction]
14261426
fn waitstatus_to_exitcode(status: i32, vm: &VirtualMachine) -> PyResult<i32> {
14271427
let status = u32::try_from(status)
14281428
.map_err(|_| vm.new_value_error(format!("invalid WEXITSTATUS: {status}")))?;
14291429

1430-
cfg_if::cfg_if! {
1431-
if #[cfg(not(windows))] {
1432-
let status = status as libc::c_int;
1433-
if libc::WIFEXITED(status) {
1434-
return Ok(libc::WEXITSTATUS(status));
1435-
}
1436-
1437-
if libc::WIFSIGNALED(status) {
1438-
return Ok(-libc::WTERMSIG(status));
1439-
}
1430+
let status = status as libc::c_int;
1431+
if libc::WIFEXITED(status) {
1432+
return Ok(libc::WEXITSTATUS(status));
1433+
}
14401434

1441-
Err(vm.new_value_error(format!("Invalid wait status: {status}")))
1442-
} else {
1443-
i32::try_from(status.rotate_right(8))
1444-
.map_err(|_| vm.new_value_error(format!("invalid wait status: {status}")))
1445-
}
1435+
if libc::WIFSIGNALED(status) {
1436+
return Ok(-libc::WTERMSIG(status));
14461437
}
1438+
1439+
Err(vm.new_value_error(format!("Invalid wait status: {status}")))
1440+
}
1441+
1442+
#[cfg(windows)]
1443+
#[pyfunction]
1444+
fn waitstatus_to_exitcode(status: u64, vm: &VirtualMachine) -> PyResult<u32> {
1445+
let exitcode = status >> 8;
1446+
// ExitProcess() accepts an UINT type:
1447+
// reject exit code which doesn't fit in an UINT
1448+
u32::try_from(exitcode)
1449+
.map_err(|_| vm.new_value_error(format!("invalid exit code: {exitcode}")))
14471450
}
14481451

14491452
#[pyfunction]

0 commit comments

Comments
 (0)