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 <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-01-14 14:14:25 +01:00
parent 54acc87c1e
commit 9f4a8d4ea1
4 changed files with 59 additions and 31 deletions

View File

@ -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,

View File

@ -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));

View File

@ -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)

View File

@ -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