@@ -469,13 +469,36 @@ open class Process: NSObject {
469
469
470
470
WaitForSingleObject ( process. processHandle, WinSDK . INFINITE)
471
471
472
+ // On Windows, the top nibble of an NTSTATUS indicates severity, with
473
+ // the top two bits both being set (0b11) indicating an error. In
474
+ // addition, in a well formed NTSTATUS, the 4th bit must be 0.
475
+ // The third bit indicates if the error is a Microsoft defined error
476
+ // and may or may not be set.
477
+ //
478
+ // If we receive such an error, we'll indicate that the process
479
+ // exited abnormally (confusingly indicating "signalled" so we match
480
+ // POSIX behaviour for abnormal exits).
481
+ //
482
+ // However, we don't want user programs which normally exit -1, -2,
483
+ // etc to count as exited abnormally, so we specifically check for a
484
+ // top nibble of 0b11_0 so that e.g. 0xFFFFFFFF, won't trigger an
485
+ // abnormal exit.
486
+ //
487
+ // Additionally, on Windows, an uncaught signal terminates the
488
+ // program with the magic exit code 3, regardless of the signal (I'd
489
+ // personally love to know the reason for this). So we also consider
490
+ // 3 to be an abnormal exit.
472
491
var dwExitCode : DWORD = 0
473
- // FIXME(compnerd) how do we handle errors here?
474
492
GetExitCodeProcess ( process. processHandle, & dwExitCode)
475
-
476
- // TODO(compnerd) check if the process terminated abnormally
477
- process. _terminationStatus = Int32 ( dwExitCode)
478
- process. _terminationReason = . exit
493
+ if ( dwExitCode & 0xF0000000 ) == 0xC0000000
494
+ || ( dwExitCode & 0xF0000000 ) == 0xE0000000
495
+ || dwExitCode == 3 {
496
+ process. _terminationStatus = Int32 ( dwExitCode & 0x3FFFFFFF )
497
+ process. _terminationReason = . uncaughtSignal
498
+ } else {
499
+ process. _terminationStatus = Int32 ( bitPattern: dwExitCode)
500
+ process. _terminationReason = . exit
501
+ }
479
502
480
503
if let handler = process. terminationHandler {
481
504
let thread : Thread = Thread { handler ( process) }
0 commit comments