diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 333753e5b..1ba0703ae 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -1122,9 +1122,11 @@ spawn_detached (gnupg_process_t process, sca.ask_inherit = FALSE; sca.allow_foreground_window = FALSE; - sca.plpAttributeList = &si.lpAttributeList; - sca.arg = spawn_cb_arg; sca.hd[0] = INVALID_HANDLE_VALUE; + sca.hd[1] = INVALID_HANDLE_VALUE; + sca.hd[2] = INVALID_HANDLE_VALUE; + sca.inherit_hds = NULL; + sca.arg = spawn_cb_arg; if (spawn_cb) (*spawn_cb) (&sca); @@ -1344,22 +1346,46 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], sca.ask_inherit = FALSE; sca.allow_foreground_window = FALSE; - sca.plpAttributeList = &si.lpAttributeList; + sca.hd[0] = hd_in[0]; + sca.hd[1] = hd_out[1]; + sca.hd[2] = hd_err[1]; + sca.inherit_hds = NULL; sca.arg = spawn_cb_arg; - i = 0; - if (hd_in[0] != INVALID_HANDLE_VALUE) - sca.hd[i++] = hd_in[0]; - if (hd_out[1] != INVALID_HANDLE_VALUE) - sca.hd[i++] = hd_out[1]; - if (hd_err[1] != INVALID_HANDLE_VALUE) - sca.hd[i++] = hd_err[1]; - sca.hd[i] = INVALID_HANDLE_VALUE; if (spawn_cb) (*spawn_cb) (&sca); - if (i != 0) + i = 0; + if (sca.hd[0] != INVALID_HANDLE_VALUE) + i++; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + i++; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + i++; + + if (i != 0 || sca.inherit_hds) { SIZE_T attr_list_size = 0; + HANDLE hd[16]; + HANDLE *hd_p = sca.inherit_hds; + int j = 0; + + if (sca.hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[0]; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[1]; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[2]; + if (hd_p) + { + while (*hd_p != INVALID_HANDLE_VALUE) + if (j < DIM (hd)) + hd[j++] = *hd_p++; + else + { + log_error ("Too much handles\n"); + break; + } + } InitializeProcThreadAttributeList (NULL, 1, 0, &attr_list_size); si.lpAttributeList = xtrymalloc (attr_list_size); @@ -1387,7 +1413,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], &attr_list_size); UpdateProcThreadAttribute (si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, - sca.hd, sizeof (HANDLE) * i, NULL, NULL); + hd, sizeof (HANDLE) * j, NULL, NULL); sca.ask_inherit = TRUE; } diff --git a/common/exechelp.h b/common/exechelp.h index 926ae2922..6375d9d10 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -214,10 +214,10 @@ typedef struct gnupg_process *gnupg_process_t; struct spawn_cb_arg; #ifdef NEED_STRUCT_SPAWN_CB_ARG struct spawn_cb_arg { + HANDLE hd[3]; + HANDLE *inherit_hds; BOOL ask_inherit; BOOL allow_foreground_window; - void *plpAttributeList; - HANDLE hd[16]; void *arg; }; #endif diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index 39cdd2132..58659c1b8 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -42,6 +42,9 @@ #endif #include "../../common/util.h" +#ifdef HAVE_W32_SYSTEM +#define NEED_STRUCT_SPAWN_CB_ARG +#endif #include "../../common/exechelp.h" #include "../../common/sysutils.h" @@ -868,9 +871,18 @@ setup_std_fds (struct spawn_cb_arg *sca) { int *std_fds = sca->arg; +#ifdef HAVE_W32_SYSTEM + sca->hd[0] = std_fds[0] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[0]); + sca->hd[1] = std_fds[1] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[1]); + sca->hd[2] = std_fds[2] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[2]); +#else sca->fds[0] = std_fds[0]; sca->fds[1] = std_fds[1]; sca->fds[2] = std_fds[2]; +#endif } static pointer