Reactos
at master 87 lines 2.7 kB view raw
1/*** 2*wait.c - wait for child process to terminate 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* defines _wait() - wait for child process to terminate 8* 9*******************************************************************************/ 10 11#include <corecrt_internal.h> 12#include <errno.h> 13#include <process.h> 14#include <stdlib.h> 15 16/*** 17*int _cwait(stat_loc, process_id, action_code) - wait for specific child 18* process 19* 20*Purpose: 21* The function _cwait() suspends the calling-process until the specified 22* child-process terminates. If the specifed child-process terminated 23* prior to the call to _cwait(), return is immediate. 24* 25*Entry: 26* int *stat_loc - pointer to where status is stored or nullptr 27* process_id - specific process id to be interrogated (0 means any) 28* action_code - specific action to perform on process ID 29* either _WAIT_CHILD or _WAIT_GRANDCHILD 30* 31*Exit: 32* process ID of terminated child or -1 on error 33* 34* *stat_loc is updated to contain the following: 35* Normal termination: lo-byte = 0, hi-byte = child exit code 36* Abnormal termination: lo-byte = term status, hi-byte = 0 37* 38*Exceptions: 39* 40*******************************************************************************/ 41 42extern "C" intptr_t __cdecl _cwait( 43 int* const exit_code_result, 44 intptr_t const process_id, 45 int const action_code 46 ) 47{ 48 DBG_UNREFERENCED_PARAMETER(action_code); 49 50 if (exit_code_result) 51 *exit_code_result = static_cast<DWORD>(-1); 52 53 // Explicitly check for process ids -1 and -2. In Windows NT, -1 is a handle 54 // to the current process and -2 is a handle to the current thread, and the 55 // OS will let you wait (forever) on either. 56 _VALIDATE_RETURN_NOEXC(process_id != -1 && process_id != -2, ECHILD, -1); 57 58 __crt_unique_handle process_handle(reinterpret_cast<HANDLE>(process_id)); 59 60 // Wait for the child process and get its exit code: 61 DWORD exit_code; 62 if (WaitForSingleObject(process_handle.get(), static_cast<DWORD>(-1)) == 0 && 63 GetExitCodeProcess(process_handle.get(), &exit_code)) 64 { 65 if (exit_code_result) 66 *exit_code_result = exit_code; 67 68 return process_id; 69 } 70 71 // One of the API calls failed; map the error and return failure. 72 DWORD const os_error = GetLastError(); 73 if (os_error == ERROR_INVALID_HANDLE) 74 { 75 errno = ECHILD; 76 _doserrno = os_error; 77 } 78 else 79 { 80 __acrt_errno_map_os_error(os_error); 81 } 82 83 if (exit_code_result) 84 *exit_code_result = static_cast<DWORD>(-1); 85 86 return -1; 87}