diff options
Diffstat (limited to 'private/crt32/exec/wait.c')
-rw-r--r-- | private/crt32/exec/wait.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/private/crt32/exec/wait.c b/private/crt32/exec/wait.c new file mode 100644 index 000000000..c6ba4cae4 --- /dev/null +++ b/private/crt32/exec/wait.c @@ -0,0 +1,199 @@ +/*** +*wait.c - OS/2 wait for child process to terminate +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* defines _wait() - wait for child process to terminate +* +*Revision History: +* 06-08-89 PHG Module created, based on asm version +* 03-08-90 GJF Made calling type _CALLTYPE2 (for now), added #include +* <cruntime.h> and fixed the copyright. Also, cleaned up +* the formatting a bit. +* 04-02-90 GJF Now _CALLTYPE1. +* 07-24-90 SBM Removed '32' from API names +* 09-27-90 GJF New-style function declarators. +* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h> +* 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. +* 01-17-91 GJF ANSI naming +* 02-18-91 SRW Fixed code to close process handle. [_WIN32_] +* 04-26-91 SRW Removed level 3 warnings [_WIN32_] +* 12-17-91 GJF Fixed _cwait for Win32. However, _wait is still +* broken [_WIN32_]. +* 07-21-92 GJF Removed _wait for Win32, not implemented and no good +* way to implement. +* 12-14-92 GJF For Win32, map ERROR_INVALID_HANDLE to ECHILD. +* +*******************************************************************************/ + +#include <cruntime.h> +#include <oscalls.h> +#include <process.h> +#include <errno.h> +#include <internal.h> +#include <stdlib.h> + +/*** +*int _cwait(stat_loc, process_id, action_code) - wait for specific child +* process +* +*Purpose: +* The function _cwait() suspends the calling-process until the specified +* child-process terminates. If the specifed child-process terminated +* prior to the call to _cwait(), return is immediate. +* +*Entry: +* int *stat_loc - pointer to where status is stored or NULL +* process_id - specific process id to be interrogated (0 means any) +* action_code - specific action to perform on process ID +* either _WAIT_CHILD or _WAIT_GRANDCHILD +* +*Exit: +* process ID of terminated child or -1 on error +* +* *stat_loc is updated to contain the following: +* Normal termination: lo-byte = 0, hi-byte = child exit code +* Abnormal termination: lo-byte = term status, hi-byte = 0 +* +*Exceptions: +* +*******************************************************************************/ + +int _CRTAPI1 _cwait ( + int *stat_loc, + int process_id, + int action_code + ) +{ +#ifdef _CRUISER_ + ULONG retstatus; /* return status from child */ + ULONG retval; /* return value from wait */ + char abnormend; /* child terminated abnormally */ + ULONG dosretval; /* return value from OS/2 call */ + RESULTCODES retcodes; /* return codes from child process */ + PID pid_finished; /* process id of child that finished */ + + /* call OS/2 wait for child routine */ + if (dosretval = DOSWAITCHILD(action_code, DCWW_WAIT, &retcodes, + &pid_finished, process_id)) { + /* error occured -- map error code and return */ + _dosmaperr(dosretval); + return -1; + } + + /* set status code values -- note that return value is + truncated to a byte for XENIX compatibility */ + + if (retcodes.codeTerminate != 0) { + abnormend = 1; + retstatus = retcodes.codeTerminate & 0xFF; + } + else { + abnormend = 0; + retstatus = (retcodes.codeResult & 0xFF) << 8 + + (retcodes.codeTerminate & 0xFF); + } + + if (stat_loc != NULL) + *stat_loc = retstatus; + + if (abnormend) { + /* abnormal termination, set errno and return -1 */ + errno = EINTR; + _doserrno = 0; /* no OS/2 error */ + return -1; + } + + return retval; + +#else /* ndef _CRUISER_ */ + +#ifdef _WIN32_ + + int retval; + int retstatus; + unsigned long oserror; + + DBG_UNREFERENCED_PARAMETER(action_code); + + /* Explicitly check for process_id being -1 or -2. In Windows NT, + * -1 is a handle on the current process, -2 is a handle on the + * current thread, and it is perfectly legal to to wait (forever) + * on either */ + if ( (process_id == -1) || (process_id == -2) ) { + errno = ECHILD; + return -1; + } + + /* wait for child process, then fetch its exit code */ + if ( (WaitForSingleObject((HANDLE)process_id, (DWORD)(-1L)) == 0) && + GetExitCodeProcess((HANDLE)process_id, (LPDWORD)&retstatus) ) { + retval = process_id; + } + else { + /* one of the API calls failed. map the error and set up to + return failure. note the invalid handle error is mapped in- + line to ECHILD */ + if ( (oserror = GetLastError()) == ERROR_INVALID_HANDLE ) { + errno = ECHILD; + _doserrno = oserror; + } + else + _dosmaperr(GetLastError()); + + retval = -1; + retstatus = -1; + } + + CloseHandle((HANDLE)process_id); + + if (stat_loc != NULL) + *stat_loc = retstatus; + + return retval; + +#else /* ndef _WIN32_ */ + +#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! + +#endif /* _WIN32_ */ + +#endif /* _CRUISER_ */ +} + + +#ifndef _WIN32_ + +/*** +*int _wait(stat_loc) - wait for a child to terminate +* +*Purpose: +* The function _wait() suspends the calling-process until one of the +* immediate children terminates. If a child-process terminated prior to +* the call on the function _wait(), return is immediate. +* +*Entry: +* int *stat_loc - pointer to where status is stored or NULL +* +*Exit: +* returns process id or -1 on errors. +* +* *stat_loc is updated to contain the following: +* Normal termination: lo-byte = 0, hi-byte = child exit code +* Abnormal termination: lo-byte = term status, hi-byte = 0 +* +*Exceptions: +* +*******************************************************************************/ + +/* _wait calls _cwait to do all the real work */ +int _CRTAPI1 _wait ( + int *stat_loc + ) +{ + return _cwait(stat_loc, 0, _WAIT_CHILD); +} + + +#endif |