11011 Note that win32 needs to know the HANDLE of the process on which |
11011 Note that win32 needs to know the HANDLE of the process on which |
11012 it waits. In case of an error, THIS ALWAYS WAITS and then times out." |
11012 it waits. In case of an error, THIS ALWAYS WAITS and then times out." |
11013 |
11013 |
11014 |pid status code core| |
11014 |pid status code core| |
11015 %{ |
11015 %{ |
|
11016 #define PROCESSDEBUG_CHILDPROCESSWAIT |
|
11017 |
11016 int endStatus; |
11018 int endStatus; |
|
11019 DWORD exitCode; |
11017 |
11020 |
11018 if (__isExternalAddressLike(pidToWait) ) { |
11021 if (__isExternalAddressLike(pidToWait) ) { |
11019 HANDLE __pidToWait = _HANDLEVal(pidToWait); |
11022 HANDLE __pidToWait = _HANDLEVal(pidToWait); |
11020 int t; |
|
11021 |
11023 |
11022 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11024 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11023 console_printf("childProcessWait %x b %d\n",__pidToWait,blocking==true); |
11025 console_printf("childProcessWait %x b %d\n",__pidToWait,blocking==true); |
11024 #endif |
11026 #endif |
11025 t = (blocking==true) ? INFINITE : 0; |
11027 |
11026 |
11028 if (blocking == true) { |
11027 #ifdef DO_WRAP_CALLS |
11029 #ifdef DO_WRAP_CALLS |
11028 if (t == 0) { |
11030 do { |
11029 /* no need for WRAP-call; does not block */ |
11031 __threadErrno = 0; |
11030 endStatus = WaitForSingleObject(__pidToWait, t); |
11032 // do not cast to INT - will loose sign bit then! |
11031 if (endStatus < 0) { |
11033 endStatus = STX_API_CALL2( "WaitForSingleObject", WaitForSingleObject, __pidToWait, INFINITE); |
11032 __threadErrno = __WIN32_ERR(GetLastError()); |
11034 } while ((endStatus < 0) && (__threadErrno == EINTR)); |
11033 } |
|
11034 } else { |
|
11035 do { |
|
11036 __threadErrno = 0; |
|
11037 // do not cast to INT - will loose sign bit then! |
|
11038 endStatus = STX_API_CALL2( "WaitForSingleObject", WaitForSingleObject, __pidToWait, t); |
|
11039 } while ((endStatus < 0) && (__threadErrno == EINTR)); |
|
11040 } |
|
11041 #else |
11035 #else |
11042 endStatus = WaitForSingleObject(__pidToWait, t); |
11036 endStatus = WaitForSingleObject(__pidToWait, INFINITE); |
11043 if (endStatus < 0) { |
11037 if (endStatus < 0) { |
11044 __threadErrno = __WIN32_ERR(GetLastError()); |
11038 __threadErrno = __WIN32_ERR(GetLastError()); |
11045 } |
11039 } |
11046 #endif |
11040 #endif |
11047 if ( endStatus == WAIT_TIMEOUT ) { |
11041 if (endStatus == WAIT_TIMEOUT) { |
11048 if (blocking==true) |
11042 if (blocking==true) |
11049 status = @symbol(timeout); |
11043 status = @symbol(timeout); |
11050 else { |
11044 else { |
11051 status = @symbol(continue); |
11045 status = @symbol(continue); |
11052 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11046 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11053 console_printf("ret nil\n"); |
11047 console_printf("ret nil\n"); |
11054 #endif |
11048 #endif |
11055 RETURN(nil); |
11049 RETURN(nil); |
11056 } |
11050 } |
11057 } else { |
11051 } else if (endStatus == WAIT_OBJECT_0) { |
11058 status = @symbol(exit); |
11052 |
|
11053 } |
|
11054 } |
|
11055 |
11059 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11056 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11060 console_printf("exit\n"); |
11057 console_printf("GetExitCodeProcess\n"); |
11061 #endif |
11058 #endif |
11062 if (endStatus == WAIT_OBJECT_0) { |
11059 |
11063 DWORD exitCode; |
11060 if (GetExitCodeProcess(__pidToWait, &exitCode)) { |
11064 |
11061 if (exitCode == STILL_ACTIVE) { |
11065 if (GetExitCodeProcess(__pidToWait, &exitCode)) { |
|
11066 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11062 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11067 console_printf("exitCode: %d\n", exitCode); |
11063 console_printf("exitCode: STILL_ACTIVE\n"); |
11068 #endif |
11064 #endif |
11069 if (exitCode == STILL_ACTIVE) { |
11065 RETURN(nil); |
11070 RETURN(nil); |
11066 } |
11071 } |
|
11072 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11067 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11073 console_printf("exit %d\n", exitCode); |
11068 console_printf("exitCode %d\n", exitCode); |
11074 #endif |
11069 #endif |
11075 code = __mkSmallInteger(exitCode); |
11070 status = @symbol(exit); |
11076 } else { |
11071 code = __mkSmallInteger(exitCode); |
|
11072 core = false; |
|
11073 pid = pidToWait; |
|
11074 } else { |
|
11075 code = __mkSmallInteger(GetLastError()); |
11077 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11076 #ifdef PROCESSDEBUG_CHILDPROCESSWAIT |
11078 console_printf("GetExitCodeProcess failed\n"); |
11077 console_printf("GetExitCodeProcess failed: error=%d\n", GetLastError()); |
11079 #endif |
11078 #endif |
11080 code = __mkSmallInteger(GetLastError()); |
11079 } |
11081 } |
|
11082 } else { |
|
11083 code = __mkSmallInteger(-1); |
|
11084 } |
|
11085 } |
|
11086 core = false; |
|
11087 pid = pidToWait; |
|
11088 } |
11080 } |
11089 %}. |
11081 %}. |
11090 |
11082 |
11091 (status isNil or:[pid isNil]) ifTrue:[ |
11083 (status isNil or:[pid isNil]) ifTrue:[ |
11092 ^ self primitiveFailed |
11084 ^ self primitiveFailed:code |
11093 ]. |
11085 ]. |
11094 |
11086 |
11095 "/ Transcript show:'pid: '; show:pid; show:' status: '; show:status; |
11087 "/ Transcript show:'pid: '; show:pid; show:' status: '; show:status; |
11096 "/ show:' code: '; show:code; show:' core:'; showCR:core. |
11088 "/ show:' code: '; show:code; show:' core:'; showCR:core. |
11097 |
11089 |
11098 ^ OSProcessStatus pid:pid status:status code:code core:core |
11090 ^ OSProcessStatus pid:pid status:status code:code core:core |
11099 |
|
11100 " |
|
11101 OperatingSystem childProcessWait:false |
|
11102 " |
|
11103 |
|
11104 "Created: 5.1.1996 / 16:39:14 / stefan" |
|
11105 ! |
11091 ! |
11106 |
11092 |
11107 numAvailableForReadOn:fd |
11093 numAvailableForReadOn:fd |
11108 "return the number of bytes available for reading, without blocking." |
11094 "return the number of bytes available for reading, without blocking." |
11109 |
11095 |
11288 else |
11274 else |
11289 goto polling; |
11275 goto polling; |
11290 } |
11276 } |
11291 if (res == WAIT_FAILED) { |
11277 if (res == WAIT_FAILED) { |
11292 #ifdef SELECT2DEBUGWIN32 |
11278 #ifdef SELECT2DEBUGWIN32 |
11293 console_printf("- error %d; ret nil\n", GetLastError()); |
11279 console_printf("- error %d (last %d); ret -1\n", __threadErrno, GetLastError()); |
11294 #endif |
11280 #endif |
11295 if (__threadErrno == EINTR) { |
11281 if (__threadErrno == EINTR) { |
11296 @global(LastErrorNumber) = nil; |
11282 @global(LastErrorNumber) = nil; |
11297 RETURN (__mkSmallInteger(0)); |
11283 RETURN (__mkSmallInteger(0)); |
11298 } else { |
11284 } else { |
11299 if (@global(InfoPrinting) == true) { |
11285 if (@global(InfoPrinting) == true) { |
11300 console_fprintf(stderr, "Win32OS [info]: select errno = %d\n", __threadErrno); |
11286 // console_fprintf(stderr, "Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError()); |
|
11287 console_printf("Win32OS [info]: select errno = %d (last %d)\n", __threadErrno, GetLastError()); |
11301 } |
11288 } |
11302 @global(LastErrorNumber) = __mkSmallInteger(EBADF); |
11289 @global(LastErrorNumber) = __mkSmallInteger(EBADF); |
11303 RETURN (__mkSmallInteger(-1)); |
11290 RETURN (__mkSmallInteger(-1)); |
11304 } |
11291 } |
11305 } |
11292 } |