cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=dd45d7f7445b4ea0238a9ec229011016a8586706
commit dd45d7f7445b4ea0238a9ec229011016a8586706 Author: Vincent Torri <vincent dot torri at gmail dot com> Date: Sun Sep 27 10:08:26 2015 +0200 ecore_exe: make sure that ReadFile() will not hang When child process exits, ReadFile() will hang if those pipes are maintained Signed-off-by: Cedric BAIL <ced...@osg.samsung.com> --- src/lib/ecore/ecore_exe_private.h | 2 -- src/lib/ecore/ecore_exe_win32.c | 24 ++++++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/lib/ecore/ecore_exe_private.h b/src/lib/ecore/ecore_exe_private.h index f10c396..66c6d4f 100644 --- a/src/lib/ecore/ecore_exe_private.h +++ b/src/lib/ecore/ecore_exe_private.h @@ -83,7 +83,6 @@ struct _Ecore_Exe_Data struct { HANDLE child_pipe; - HANDLE child_pipe_x; HANDLE thread; void *data_buf; DWORD data_size; @@ -100,7 +99,6 @@ struct _Ecore_Exe_Data struct { HANDLE child_pipe; - HANDLE child_pipe_x; HANDLE thread; void *data_buf; DWORD data_size; diff --git a/src/lib/ecore/ecore_exe_win32.c b/src/lib/ecore/ecore_exe_win32.c index 24782e2..eba7913 100644 --- a/src/lib/ecore/ecore_exe_win32.c +++ b/src/lib/ecore/ecore_exe_win32.c @@ -389,6 +389,8 @@ _impl_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe) char exe_cmd_buf[1024]; SECURITY_ATTRIBUTES sa; STARTUPINFO si; + HANDLE child_pipe_read; + HANDLE child_pipe_error; PROCESS_INFORMATION pi; Ecore_Exe_Event_Add *e; Eina_Bool use_sh = EINA_FALSE; @@ -446,7 +448,7 @@ _impl_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe) /* stdout pipe */ if (exe->flags & ECORE_EXE_PIPE_READ) { - if (!CreatePipe(&exe->pipe_read.child_pipe, &exe->pipe_read.child_pipe_x, &sa, 0)) + if (!CreatePipe(&exe->pipe_read.child_pipe, &child_pipe_read, &sa, 0)) goto error; if (!SetHandleInformation(exe->pipe_read.child_pipe, HANDLE_FLAG_INHERIT, 0)) goto error; @@ -460,7 +462,7 @@ _impl_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe) /* stderr pipe */ if (exe->flags & ECORE_EXE_PIPE_ERROR) { - if (!CreatePipe(&exe->pipe_error.child_pipe, &exe->pipe_error.child_pipe_x, &sa, 0)) + if (!CreatePipe(&exe->pipe_error.child_pipe, &child_pipe_error, &sa, 0)) goto error; if (!SetHandleInformation(exe->pipe_error.child_pipe, HANDLE_FLAG_INHERIT, 0)) goto error; @@ -486,9 +488,9 @@ _impl_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe) ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); - si.hStdOutput = exe->pipe_read.child_pipe_x; + si.hStdOutput = child_pipe_read; si.hStdInput = exe->pipe_write.child_pipe; - si.hStdError = exe->pipe_error.child_pipe_x; + si.hStdError = child_pipe_error; si.dwFlags |= STARTF_USESTDHANDLES; DBG("CreateProcess: shell:%s child:%s", use_sh ? "yes" : "no", exe->cmd); @@ -499,6 +501,16 @@ _impl_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe) goto error; } + /* + * Close pipe handles (do not continue to modify the parent). + * We need to make sure that no handles to the write end of the + * output and error pipes are maintained in this process or else + * the pipe will not close when the child process exits and the + * ReadFile will hang. + */ + CloseHandle(child_pipe_read); + CloseHandle(child_pipe_error); + /* be sure that the child process is running */ /* FIXME: This does not work if the child is an EFL-based app */ /* if (WaitForInputIdle(pi.hProcess, INFINITE) == WAIT_FAILED) */ @@ -700,13 +712,9 @@ _impl_ecore_exe_eo_base_destructor(Eo *obj, Ecore_Exe_Data *exe) _ecore_exe_threads_terminate(obj); if (exe->pipe_error.child_pipe) CloseHandle(exe->pipe_error.child_pipe); - if (exe->pipe_error.child_pipe_x) - CloseHandle(exe->pipe_error.child_pipe_x); if (exe->pipe_read.child_pipe) CloseHandle(exe->pipe_read.child_pipe); - if (exe->pipe_read.child_pipe_x) - CloseHandle(exe->pipe_read.child_pipe_x); if (exe->cmd) free(exe->cmd); --