aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJustus Winter <[email protected]>2016-01-14 13:14:25 +0000
committerJustus Winter <[email protected]>2016-02-23 10:58:52 +0000
commit9f4a8d4ea173b4b4cb4d4f06b4004d43e2f4b97a (patch)
treec37c3538628bcabf8b8f389f7653c7e1b683a766 /common
parentcommon/exechelp: Mute the Windows version. (diff)
downloadgnupg-9f4a8d4ea173b4b4cb4d4f06b4004d43e2f4b97a.tar.gz
gnupg-9f4a8d4ea173b4b4cb4d4f06b4004d43e2f4b97a.zip
common/exechelp: Add general pipe function.
* common/exechelp-posix.c (gnupg_create_pipe): New function. * common/exechelp-w32.c (INHERIT_{READ,WRITE,BOTH}): New macros. (create_inheritable_pipe): Generalize so that both ends can be inherited. (do_create_pipe): Rename argument accordingly. (gnupg_create_{in,out}bound_pipe): Use new flags. (gnupg_create_pipe): New function. (gnupg_spawn_process): Use new flags. * common/exechelp-w32ce.c (gnupg_create_pipe): New stub. * common/exechelp.h (gnupg_create_pipe): New prototype. Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to 'common')
-rw-r--r--common/exechelp-posix.c9
-rw-r--r--common/exechelp-w32.c67
-rw-r--r--common/exechelp-w32ce.c9
-rw-r--r--common/exechelp.h5
4 files changed, 59 insertions, 31 deletions
diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index 5706dbe1f..37abf55a1 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -310,6 +310,15 @@ gnupg_create_outbound_pipe (int filedes[2])
}
+/* Portable function to create a pipe. Under Windows both ends are
+ inheritable. */
+gpg_error_t
+gnupg_create_pipe (int filedes[2])
+{
+ return do_create_pipe (filedes);
+}
+
+
static gpg_error_t
create_pipe_and_estream (int filedes[2], estream_t *r_fp,
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c
index a77e27c53..68846f817 100644
--- a/common/exechelp-w32.c
+++ b/common/exechelp-w32.c
@@ -233,45 +233,41 @@ build_w32_commandline (const char *pgmname, const char * const *argv,
}
-/* Create pipe where one end is inheritable: With an INHERIT_IDX of 0
- the read end is inheritable, with 1 the write end is inheritable. */
+#define INHERIT_READ 1
+#define INHERIT_WRITE 2
+#define INHERIT_BOTH (INHERIT_READ|INHERIT_WRITE)
+
+/* Create pipe. FLAGS indicates which ends are inheritable. */
static int
-create_inheritable_pipe (HANDLE filedes[2], int inherit_idx)
+create_inheritable_pipe (HANDLE filedes[2], int flags)
{
- HANDLE r, w, h;
+ HANDLE r, w;
SECURITY_ATTRIBUTES sec_attr;
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
- sec_attr.bInheritHandle = FALSE;
+ sec_attr.bInheritHandle = TRUE;
if (!CreatePipe (&r, &w, &sec_attr, 0))
return -1;
- if (!DuplicateHandle (GetCurrentProcess(), inherit_idx? w : r,
- GetCurrentProcess(), &h, 0,
- TRUE, DUPLICATE_SAME_ACCESS ))
- {
- log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
- CloseHandle (r);
- CloseHandle (w);
- return -1;
- }
+ if ((flags & INHERIT_READ) == 0)
+ if (! SetHandleInformation (r, HANDLE_FLAG_INHERIT, 0))
+ goto fail;
- if (inherit_idx)
- {
- CloseHandle (w);
- w = h;
- }
- else
- {
- CloseHandle (r);
- r = h;
- }
+ if ((flags & INHERIT_WRITE) == 0)
+ if (! SetHandleInformation (w, HANDLE_FLAG_INHERIT, 0))
+ goto fail;
filedes[0] = r;
filedes[1] = w;
return 0;
+
+ fail:
+ log_error ("SetHandleInformation failed: %s\n", w32_strerror (-1));
+ CloseHandle (r);
+ CloseHandle (w);
+ return -1;
}
@@ -291,14 +287,14 @@ w32_open_null (int for_write)
static gpg_error_t
-do_create_pipe (int filedes[2], int inherit_idx)
+do_create_pipe (int filedes[2], int flags)
{
gpg_error_t err = 0;
HANDLE fds[2];
filedes[0] = filedes[1] = -1;
err = gpg_error (GPG_ERR_GENERAL);
- if (!create_inheritable_pipe (fds, inherit_idx))
+ if (!create_inheritable_pipe (fds, flags))
{
filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), O_RDONLY);
if (filedes[0] == -1)
@@ -328,7 +324,7 @@ do_create_pipe (int filedes[2], int inherit_idx)
gpg_error_t
gnupg_create_inbound_pipe (int filedes[2])
{
- return do_create_pipe (filedes, 1);
+ return do_create_pipe (filedes, INHERIT_WRITE);
}
@@ -337,7 +333,16 @@ gnupg_create_inbound_pipe (int filedes[2])
gpg_error_t
gnupg_create_outbound_pipe (int filedes[2])
{
- return do_create_pipe (filedes, 0);
+ return do_create_pipe (filedes, INHERIT_READ);
+}
+
+
+/* Portable function to create a pipe. Under Windows both ends are
+ inheritable. */
+gpg_error_t
+gnupg_create_pipe (int filedes[2])
+{
+ return do_create_pipe (filedes, INHERIT_BOTH);
}
@@ -385,7 +390,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
if (r_infp)
{
- if (create_inheritable_pipe (inpipe, 0))
+ if (create_inheritable_pipe (inpipe, INHERIT_READ))
{
err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
@@ -409,7 +414,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
if (r_outfp)
{
- if (create_inheritable_pipe (outpipe, 1))
+ if (create_inheritable_pipe (outpipe, INHERIT_WRITE))
{
err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
@@ -439,7 +444,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
if (r_errfp)
{
- if (create_inheritable_pipe (errpipe, 1))
+ if (create_inheritable_pipe (errpipe, INHERIT_WRITE))
{
err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c
index 49ccdbb99..710c828d2 100644
--- a/common/exechelp-w32ce.c
+++ b/common/exechelp-w32ce.c
@@ -465,6 +465,15 @@ gnupg_create_outbound_pipe (int filedes[2])
}
+/* Portable function to create a pipe. Under Windows both ends are
+ inheritable. */
+gpg_error_t
+gnupg_create_pipe (int filedes[2])
+{
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+}
+
+
static int
create_process (const char *pgmname, const char *cmdline,
PROCESS_INFORMATION *pi)
diff --git a/common/exechelp.h b/common/exechelp.h
index 908834238..cdee300ef 100644
--- a/common/exechelp.h
+++ b/common/exechelp.h
@@ -59,6 +59,11 @@ gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
inheritable. */
gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
+/* Portable function to create a pipe. Under Windows both ends are
+ inheritable. */
+gpg_error_t gnupg_create_pipe (int filedes[2]);
+
+
#define GNUPG_SPAWN_NONBLOCK 16
#define GNUPG_SPAWN_RUN_ASFW 64
#define GNUPG_SPAWN_DETACHED 128