@@ -140,6 +140,17 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
140140 return NULL ;
141141}
142142
143+ static void terminateChildProcess (HANDLE hProcess , HANDLE hChildPipeRead , HANDLE hReadEvent , IO_STATUS_BLOCK * piosb )
144+ {
145+ IO_STATUS_BLOCK cancelIosb = {};
146+ if (NT_SUCCESS (NtCancelIoFileEx (hChildPipeRead , piosb , & cancelIosb )))
147+ {
148+ if (hReadEvent )
149+ NtWaitForSingleObject (hReadEvent , TRUE, & (LARGE_INTEGER ) { .QuadPart = -100000 }); // wait for cancellation to complete
150+ }
151+ NtTerminateProcess (hProcess , 1 );
152+ }
153+
143154const char * ffProcessReadOutput (FFProcessHandle * handle , FFstrbuf * buffer )
144155{
145156 assert (handle -> pipeRead != INVALID_HANDLE_VALUE );
@@ -180,13 +191,13 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
180191 break ;
181192
182193 case STATUS_TIMEOUT :
183- CancelIo ( hChildPipeRead );
184- TerminateProcess (hProcess , 1 );
194+ {
195+ terminateChildProcess (hProcess , hChildPipeRead , hReadEvent , & iosb );
185196 return "NtReadFile(hChildPipeRead) timed out" ;
197+ }
186198
187199 default :
188- CancelIo (hChildPipeRead );
189- TerminateProcess (hProcess , 1 );
200+ terminateChildProcess (hProcess , hChildPipeRead , hReadEvent , & iosb );
190201 return "NtWaitForSingleObject(hReadEvent) failed" ;
191202 }
192203 }
@@ -196,8 +207,7 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
196207
197208 if (!NT_SUCCESS (status ))
198209 {
199- CancelIo (hChildPipeRead );
200- TerminateProcess (hProcess , 1 );
210+ terminateChildProcess (hProcess , hChildPipeRead , NULL , & iosb );
201211 return "NtReadFile(hChildPipeRead) failed" ;
202212 }
203213
0 commit comments