Rev 175 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 175 | Rev 177 | ||
|---|---|---|---|
| Line 18... | Line 18... | ||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | // function prototypes |
20 | // function prototypes |
| 21 | FILE *pipe_open (const wchar_t *shell_command, const wchar_t *mode); |
21 | FILE *pipe_open (const wchar_t *shell_command, const wchar_t *mode); |
| 22 | int pipe_close (FILE *stream); |
22 | int pipe_close (FILE *stream); |
| 23 | int pipe_isalive (FILE * |
23 | int pipe_isalive (FILE *stream, int64_t *exit_code); |
| 24 | int pipe_hasdata (FILE *stream); |
24 | int pipe_hasdata (FILE *stream); |
| 25 | int pipe_read (FILE *stream, void *dstbuf, int nbytes); |
25 | int pipe_read (FILE *stream, void *dstbuf, int nbytes); |
| 26 | int pipe_write (FILE *stream, void *srcbuf, int nbytes); |
26 | int pipe_write (FILE *stream, void *srcbuf, int nbytes); |
| 27 | 27 | ||
| 28 | 28 | ||
| Line 152... | Line 152... | ||
| 152 | return (pclose (stream)); |
152 | return (pclose (stream)); |
| 153 | #endif // _WIN32 |
153 | #endif // _WIN32 |
| 154 | } |
154 | } |
| 155 | 155 | ||
| 156 | 156 | ||
| 157 | int pipe_isalive (FILE * |
157 | int pipe_isalive (FILE *stream, int64_t *exit_code) |
| 158 | { |
158 | { |
| 159 | // wrapper around ioctl() on pipes for systems that don't have it |
159 | // wrapper around ioctl() on pipes for systems that don't have it |
| 160 | 160 | ||
| 161 | #ifdef _WIN32 |
161 | #ifdef _WIN32 |
| 162 | DWORD |
162 | DWORD w32exitcode; |
| 163 | DWORD handle_flags; |
163 | DWORD handle_flags; |
| 164 | if (((pipe_t *) stream)->procinfo.hProcess == 0) |
164 | if (((pipe_t *) stream)->procinfo.hProcess == 0) |
| 165 | return (1); // if the child process has not been fully started yet, assume the pipe is still alive |
165 | return (1); // if the child process has not been fully started yet, assume the pipe is still alive |
| 166 | else if (((pipe_t *) stream)->procinfo.hProcess == INVALID_HANDLE_VALUE) |
166 | else if (((pipe_t *) stream)->procinfo.hProcess == INVALID_HANDLE_VALUE) |
| 167 | return (0); // if the child process handle has been explicitly marked invalid, assume it's already dead |
167 | return (0); // if the child process handle has been explicitly marked invalid, assume it's already dead |
| 168 | else if (GetHandleInformation (((pipe_t *) stream)->procinfo.hProcess, &handle_flags) == 0) |
168 | else if (GetHandleInformation (((pipe_t *) stream)->procinfo.hProcess, &handle_flags) == 0) |
| 169 | { |
169 | { |
| 170 | ((pipe_t *) stream)->procinfo.hProcess = INVALID_HANDLE_VALUE; |
170 | ((pipe_t *) stream)->procinfo.hProcess = INVALID_HANDLE_VALUE; |
| 171 | return (0); // if the process handle is no longer valid but its handle is not marked as such, assume the child is dead |
171 | return (0); // if the process handle is no longer valid but its handle is not marked as such, assume the child is dead |
| 172 | } |
172 | } |
| 173 | else if (GetExitCodeProcess (((pipe_t *) stream)->procinfo.hProcess, & |
173 | else if (GetExitCodeProcess (((pipe_t *) stream)->procinfo.hProcess, &w32exitcode) == 0) |
| 174 | return (1); // if GetExitCodeProcess() failed, *conservatively* assume the child is still alive |
174 | return (1); // if GetExitCodeProcess() failed, *conservatively* assume the child is still alive |
| - | 175 | *exit_code = (int64_t) w32exitcode; |
|
| 175 | return ( |
176 | return (w32exitcode == STILL_ACTIVE); |
| 176 | #else // !_WIN32 |
177 | #else // !_WIN32 |
| - | 178 | *exit_code = 0; |
|
| 177 | return (1); // UNIX doesn't provide a portable way for this |
179 | return (1); // UNIX doesn't provide a portable way for this |
| 178 | #endif // _WIN32 |
180 | #endif // _WIN32 |
| 179 | } |
181 | } |
| 180 | 182 | ||
| 181 | 183 | ||