Module: wine Branch: master Commit: 044461e8a6f4c1a29c1d72119d2ed207e9d0573b URL: https://source.winehq.org/git/wine.git/?a=commit;h=044461e8a6f4c1a29c1d72119...
Author: Martin Storsjo martin@martin.st Date: Tue May 14 22:02:50 2019 +0300
ntdll: Avoid truncating a nonzero exit code to zero in unix.
On Windows, the exit codes can use the full 32 bit range, while on unix, they are truncated to the lowest 8 bits. If the intended exit code is nonzero, to indicate failure, but the lower 8 bits are zero (like when winedbg tries to exit with EXCEPTION_WINE_STUB, 80000100), the observed exit code used to be zero, indicating successful execution.
Signed-off-by: Martin Storsjo martin@martin.st Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/loader.c | 2 +- dlls/ntdll/ntdll_misc.h | 7 +++++++ dlls/ntdll/process.c | 2 +- dlls/ntdll/thread.c | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 034b98c..8dae813 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3264,7 +3264,7 @@ void WINAPI RtlExitUserProcess( DWORD status ) NtTerminateProcess( 0, status ); LdrShutdownProcess(); NtTerminateProcess( GetCurrentProcess(), status ); - exit( status ); + exit( get_unix_exit_code( status )); }
/****************************************************************** diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 24c61a0..3463ebd 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -247,6 +247,13 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void) return (struct ntdll_thread_data *)&NtCurrentTeb()->GdiTebBatch; }
+static inline int get_unix_exit_code( NTSTATUS status ) +{ + /* prevent a nonzero exit code to end up truncated to zero in unix */ + if (status && !(status & 0xff)) return 1; + return status; +} + extern mode_t FILE_umask DECLSPEC_HIDDEN; extern HANDLE keyed_event DECLSPEC_HIDDEN; extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 3ce5aeb..c1570a5 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -88,7 +88,7 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code ) self = !ret && reply->self; } SERVER_END_REQ; - if (self && handle) _exit( exit_code ); + if (self && handle) _exit( get_unix_exit_code( exit_code )); return ret; }
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index be46218..46de839 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -291,7 +291,7 @@ static void free_thread_data( TEB *teb ) void abort_thread( int status ) { pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); - if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status ); + if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( get_unix_exit_code( status )); signal_exit_thread( status ); }
@@ -332,7 +332,7 @@ void WINAPI RtlExitUserThread( ULONG status ) { LdrShutdownProcess(); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); - signal_exit_process( status ); + signal_exit_process( get_unix_exit_code( status )); }
LdrShutdownThread();