From 1192449207f41b26be8950b04df84a52c8a2a886 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 Feb 2017 09:34:29 +0100 Subject: [PATCH] w32: Make pipes really pollable. * common/exectool.c (gnupg_exec_tool_stream) [W32]: Use _get_osfhandle to print the fd for the command line. * common/exechelp-w32.c (create_pipe_and_estream): Use es_sysopen so that the streams are actually pollable. -- This addresses two bugs: - Using the "-&@INEXTRA@" kludges requires that we pass the value of the handle on the command line and not the libc fd. - gpgrt_poll requires the use of the ReadFile/WriteFile backend which is currently only used when the stream has been created with gpgrt_sysopen. Signed-off-by: Werner Koch --- common/exechelp-w32.c | 12 ++++++++++-- common/exectool.c | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index e79ee5b14..2c44e2c75 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -309,6 +309,7 @@ create_pipe_and_estream (int filedes[2], int flags, { gpg_error_t err = 0; HANDLE fds[2]; + es_syshd_t syshd; filedes[0] = filedes[1] = -1; err = my_error (GPG_ERR_GENERAL); @@ -337,10 +338,17 @@ create_pipe_and_estream (int filedes[2], int flags, if (! err && r_fp) { + syshd.type = ES_SYSHD_HANDLE; if (!outbound) - *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r"); + { + syshd.u.handle = fds[0]; + *r_fp = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); + } else - *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w"); + { + syshd.u.handle = fds[1]; + *r_fp = es_sysopen (&syshd, nonblock? "w,nonblock" : "w"); + } if (!*r_fp) { err = my_error_from_syserror (); diff --git a/common/exectool.c b/common/exectool.c index ed8225ad4..c9e00205a 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -384,7 +384,12 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], /* Now find the argument marker and replace by the pipe's fd. Yeah, that is an ugly non-thread safe hack but it safes us to create a copy of the array. */ +#ifdef HAVE_W32_SYSTEM + snprintf (extrafdbuf, sizeof extrafdbuf, "-&%lu", + (unsigned long)(void*)_get_osfhandle (extrapipe[0])); +#else snprintf (extrafdbuf, sizeof extrafdbuf, "-&%d", extrapipe[0]); +#endif for (argsaveidx=0; argv[argsaveidx]; argsaveidx++) if (!strcmp (argv[argsaveidx], "-&@INEXTRA@")) {