diff options
author | Justus Winter <[email protected]> | 2016-01-14 13:14:25 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2016-02-23 10:58:52 +0000 |
commit | 9f4a8d4ea173b4b4cb4d4f06b4004d43e2f4b97a (patch) | |
tree | c37c3538628bcabf8b8f389f7653c7e1b683a766 /common | |
parent | common/exechelp: Mute the Windows version. (diff) | |
download | gnupg-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.c | 9 | ||||
-rw-r--r-- | common/exechelp-w32.c | 67 | ||||
-rw-r--r-- | common/exechelp-w32ce.c | 9 | ||||
-rw-r--r-- | common/exechelp.h | 5 |
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 |