Message365498
On Windows, the exit code is a 32-bit value. It may or may not signed depending on the function.
Unsigned in the Windows native API:
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode);
Signed in the POSIX API:
intptr_t _cwait(int *termstat, intptr_t procHandle, int action);
Problem: os.waitpid() uses "status << 8" which can overflow; status is an int.
static PyObject *
os_waitpid_impl(PyObject *module, intptr_t pid, int options)
{
int status;
(...)
/* shift the status left a byte so this is more like the POSIX waitpid */
return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
}
int64_t or uint64_t should be used, or a Python object should be used, to avoid the overflow.
I just added os.waitstatus_to_exitcode() in bpo-40094 which simply does "status >> 8" on Windows. Currently, this function casts the argument to a C int and so is limited to INT_MAX. It should also be adapted to handle values larger than INT_MAX.
By the way, I'm not sure how to handle values larger than INT_MAX. The POSIX API of Windows uses a signed integer, and so convert such value as a negative value. But the native Windows API uses unsigned numbers.
It seems like using unsigned number would be better.
--
By the way, currently os.waitstatus_to_exitcode() ignores the lower 8 bits of the status. Maybe it should raise an error if lower 8 bits are not zero, and maybe also raise an exception if the number is negative?
--
See also interesting comments by Eryk Sun in bpo-40094 about this problem. |
|
Date |
User |
Action |
Args |
2020-04-01 17:05:27 | vstinner | set | recipients:
+ vstinner |
2020-04-01 17:05:27 | vstinner | set | messageid: <1585760727.67.0.797995887325.issue40138@roundup.psfhosted.org> |
2020-04-01 17:05:27 | vstinner | link | issue40138 messages |
2020-04-01 17:05:27 | vstinner | create | |
|