1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-11 23:59:50 +02:00

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 static gpg_error_t
create_pipe_and_estream (int filedes[2], estream_t *r_fp, 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 #define INHERIT_READ 1
the read end is inheritable, with 1 the write end is inheritable. */ #define INHERIT_WRITE 2
#define INHERIT_BOTH (INHERIT_READ|INHERIT_WRITE)
/* Create pipe. FLAGS indicates which ends are inheritable. */
static int 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; SECURITY_ATTRIBUTES sec_attr;
memset (&sec_attr, 0, sizeof sec_attr ); memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr; sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE; sec_attr.bInheritHandle = TRUE;
if (!CreatePipe (&r, &w, &sec_attr, 0)) if (!CreatePipe (&r, &w, &sec_attr, 0))
return -1; return -1;
if (!DuplicateHandle (GetCurrentProcess(), inherit_idx? w : r, if ((flags & INHERIT_READ) == 0)
GetCurrentProcess(), &h, 0, if (! SetHandleInformation (r, HANDLE_FLAG_INHERIT, 0))
TRUE, DUPLICATE_SAME_ACCESS )) goto fail;
{
log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
CloseHandle (r);
CloseHandle (w);
return -1;
}
if (inherit_idx) if ((flags & INHERIT_WRITE) == 0)
{ if (! SetHandleInformation (w, HANDLE_FLAG_INHERIT, 0))
CloseHandle (w); goto fail;
w = h;
}
else
{
CloseHandle (r);
r = h;
}
filedes[0] = r; filedes[0] = r;
filedes[1] = w; filedes[1] = w;
return 0; 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 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; gpg_error_t err = 0;
HANDLE fds[2]; HANDLE fds[2];
filedes[0] = filedes[1] = -1; filedes[0] = filedes[1] = -1;
err = gpg_error (GPG_ERR_GENERAL); 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); filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), O_RDONLY);
if (filedes[0] == -1) if (filedes[0] == -1)
@ -328,7 +324,7 @@ do_create_pipe (int filedes[2], int inherit_idx)
gpg_error_t gpg_error_t
gnupg_create_inbound_pipe (int filedes[2]) 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 gpg_error_t
gnupg_create_outbound_pipe (int filedes[2]) 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 (r_infp)
{ {
if (create_inheritable_pipe (inpipe, 0)) if (create_inheritable_pipe (inpipe, INHERIT_READ))
{ {
err = gpg_err_make (errsource, GPG_ERR_GENERAL); err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); 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 (r_outfp)
{ {
if (create_inheritable_pipe (outpipe, 1)) if (create_inheritable_pipe (outpipe, INHERIT_WRITE))
{ {
err = gpg_err_make (errsource, GPG_ERR_GENERAL); err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); 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 (r_errfp)
{ {
if (create_inheritable_pipe (errpipe, 1)) if (create_inheritable_pipe (errpipe, INHERIT_WRITE))
{ {
err = gpg_err_make (errsource, GPG_ERR_GENERAL); err = gpg_err_make (errsource, GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); 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 static int
create_process (const char *pgmname, const char *cmdline, create_process (const char *pgmname, const char *cmdline,
PROCESS_INFORMATION *pi) PROCESS_INFORMATION *pi)

View File

@ -59,6 +59,11 @@ gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
inheritable. */ inheritable. */
gpg_error_t gnupg_create_outbound_pipe (int filedes[2]); 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_NONBLOCK 16
#define GNUPG_SPAWN_RUN_ASFW 64 #define GNUPG_SPAWN_RUN_ASFW 64
#define GNUPG_SPAWN_DETACHED 128 #define GNUPG_SPAWN_DETACHED 128