aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/assuan-defs.h15
-rw-r--r--src/assuan-pipe-connect.c70
-rw-r--r--src/assuan.c2
-rw-r--r--src/client.c7
-rw-r--r--src/context.c10
-rw-r--r--src/system.c54
7 files changed, 102 insertions, 58 deletions
diff --git a/configure.ac b/configure.ac
index 2ab95dc..f6cd09f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -399,7 +399,7 @@ AM_CONDITIONAL(USE_DESCRIPTOR_PASSING, test "$use_descriptor_passing" = "yes")
# Checking for libgpg-error.
-AM_PATH_GPG_ERROR(1.17,, AC_MSG_ERROR([libgpg-error was not found]))
+AM_PATH_GPG_ERROR(1.50,, AC_MSG_ERROR([libgpg-error was not found]))
AM_CONDITIONAL(USE_GPGRT_CONFIG, [test -n "$GPGRT_CONFIG" \
-a "$ac_cv_path_GPG_ERROR_CONFIG" = no])
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 3f64f7f..f0740c6 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -177,11 +177,19 @@ struct assuan_context_s
int max_accepts; /* If we can not handle more than one connection,
set this to 1, otherwise to -1. */
- /*
+#if GPG_ERROR_VERSION_NUMBER < 0x013200 /* 1.50 */
* Process reference (PID on POSIX, Process Handle on Windows).
+ * Process reference.
* Internal use, only valid for client with pipe.
*/
assuan_pid_t server_proc;
+#else
+ /*
+ * Process reference.
+ * Internal use, only valid for client with pipe.
+ */
+ gpgrt_process_t server_proc;
+#endif
/*
* NOTE: There are two different references for the process:
@@ -300,11 +308,10 @@ int _assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd,
assuan_msghdr_t msg, int flags);
int _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd,
assuan_msghdr_t msg, int flags);
-int _assuan_spawn (assuan_context_t ctx, assuan_pid_t *r_pid, const char *name,
- const char *argv[],
+int _assuan_spawn (assuan_context_t ctx, const char *name, const char *argv[],
assuan_fd_t fd_in, assuan_fd_t fd_out,
assuan_fd_t *fd_child_list,
- void (*atfork) (void *opaque, int reserved),
+ void (*atfork) (void *opaque),
void *atforkvalue, unsigned int flags);
assuan_pid_t _assuan_waitpid (assuan_context_t ctx, assuan_pid_t pid,
int nowait, int *status, int options);
diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c
index 9669cb3..ec2800f 100644
--- a/src/assuan-pipe-connect.c
+++ b/src/assuan-pipe-connect.c
@@ -148,12 +148,12 @@ struct at_pipe_fork
static void
-at_pipe_fork_cb (void *opaque, int reserved)
+at_pipe_fork_cb (void *opaque)
{
struct at_pipe_fork *atp = opaque;
if (atp->user_atfork)
- atp->user_atfork (atp->user_atforkvalue, reserved);
+ atp->user_atfork (atp->user_atforkvalue, 0);
#ifndef HAVE_W32_SYSTEM
{
@@ -184,7 +184,6 @@ pipe_connect (assuan_context_t ctx,
gpg_error_t rc;
assuan_fd_t rp[2];
assuan_fd_t wp[2];
- assuan_pid_t pid;
int res;
struct at_pipe_fork atp;
unsigned int spawn_flags;
@@ -214,7 +213,7 @@ pipe_connect (assuan_context_t ctx,
spawn_flags |= ASSUAN_SPAWN_DETACHED;
/* FIXME: Use atfork handler that closes child fds on Unix. */
- res = _assuan_spawn (ctx, &pid, name, argv, wp[0], rp[1],
+ res = _assuan_spawn (ctx, name, argv, wp[0], rp[1],
fd_child_list, at_pipe_fork_cb, &atp, spawn_flags);
if (res < 0)
{
@@ -226,6 +225,20 @@ pipe_connect (assuan_context_t ctx,
return _assuan_error (ctx, rc);
}
+ /* The fork feature on POSIX when NAME==NULL. */
+ if (!name)
+ {
+ /* Set ARGV[0] for backward compatibility. */
+ if (ctx->server_proc == NULL)
+ {
+ /* If this is the server child process, exit early. */
+ argv[0] = "server";
+ return 0;
+ }
+ else
+ argv[0] = "client";
+ }
+
/* Close the stdin/stdout child fds in the parent. */
_assuan_close_inheritable (ctx, rp[1]);
_assuan_close_inheritable (ctx, wp[0]);
@@ -244,7 +257,6 @@ pipe_connect (assuan_context_t ctx,
ctx->accept_handler = NULL;
ctx->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */
ctx->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */
- ctx->server_proc = pid;
rc = initial_handshake (ctx);
if (rc)
@@ -268,12 +280,12 @@ struct at_socketpair_fork
static void
-at_socketpair_fork_cb (void *opaque, int reserved)
+at_socketpair_fork_cb (void *opaque)
{
struct at_socketpair_fork *atp = opaque;
if (atp->user_atfork)
- atp->user_atfork (atp->user_atforkvalue, reserved);
+ atp->user_atfork (atp->user_atforkvalue, 0);
#ifndef HAVE_W32_SYSTEM
{
@@ -299,8 +311,7 @@ at_socketpair_fork_cb (void *opaque, int reserved)
/* This function is similar to pipe_connect but uses a socketpair and
sets the I/O up to use sendmsg/recvmsg. */
static gpg_error_t
-socketpair_connect (assuan_context_t ctx,
- const char *name, const char **argv,
+socketpair_connect (assuan_context_t ctx, const char *name, const char **argv,
assuan_fd_t *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
@@ -309,7 +320,6 @@ socketpair_connect (assuan_context_t ctx,
int idx;
int fds[2];
char mypidstr[50];
- pid_t pid;
int *child_fds = NULL;
int child_fds_cnt = 0;
struct at_socketpair_fork atp;
@@ -352,7 +362,7 @@ socketpair_connect (assuan_context_t ctx,
atp.peer_fd = fds[1];
child_fds[0] = fds[1];
- rc = _assuan_spawn (ctx, &pid, name, argv, ASSUAN_INVALID_FD,
+ rc = _assuan_spawn (ctx, name, argv, ASSUAN_INVALID_FD,
ASSUAN_INVALID_FD, child_fds, at_socketpair_fork_cb,
&atp, 0);
if (rc < 0)
@@ -378,11 +388,18 @@ socketpair_connect (assuan_context_t ctx,
_assuan_free (ctx, child_fds);
- /* If this is the server child process, exit early. */
- if (! name && (*argv)[0] == 's')
+ /* The fork feature on POSIX when NAME==NULL. */
+ if (!name)
{
- _assuan_close (ctx, fds[0]);
- return 0;
+ /* Set ARGV[0] for backward compatibility. */
+ if (ctx->server_proc == NULL)
+ {
+ /* If this is the server child process, exit early. */
+ argv[0] = "server";
+ return 0;
+ }
+ else
+ argv[0] = "client";
}
_assuan_close (ctx, fds[1]);
@@ -455,35 +472,28 @@ gpg_error_t
assuan_pipe_wait_server_termination (assuan_context_t ctx, int *status,
int no_hang)
{
- assuan_pid_t pid;
+ gpg_err_code_t ec;
- if (ctx->server_proc == -1)
+ if (ctx->server_proc == NULL)
return _assuan_error (ctx, GPG_ERR_NO_SERVICE);
- pid = _assuan_waitpid (ctx, ctx->server_proc, 0, status, no_hang);
- if (pid == -1)
- return _assuan_error (ctx, gpg_err_code_from_syserror ());
- else if (pid == 0)
- return _assuan_error (ctx, GPG_ERR_TIMEOUT);
+ ec = gpgrt_process_wait (ctx->server_proc, !no_hang);
+
+ if (ec)
+ return _assuan_error (ctx, ec);
- /* We did wait on the process already, so, not any more. */
- ctx->flags.no_waitpid = 1;
return 0;
}
gpg_error_t
assuan_pipe_kill_server (assuan_context_t ctx)
{
- if (ctx->server_proc == -1)
+ if (ctx->server_proc == NULL)
; /* No pid available can't send a kill. */
else
{
_assuan_pre_syscall ();
-#ifdef HAVE_W32_SYSTEM
- TerminateProcess ((HANDLE)ctx->server_proc, 1);
-#else
- kill (ctx->server_proc, SIGINT);
-#endif
+ gpgrt_process_terminate (ctx->server_proc);
_assuan_post_syscall ();
}
return 0;
diff --git a/src/assuan.c b/src/assuan.c
index b72df65..44f4c23 100644
--- a/src/assuan.c
+++ b/src/assuan.c
@@ -197,7 +197,7 @@ assuan_new_ext (assuan_context_t *r_ctx, gpg_err_source_t err_source,
#else
ctx->pid = ASSUAN_INVALID_PID;
#endif
- ctx->server_proc = -1;
+ ctx->server_proc = NULL;
*r_ctx = ctx;
diff --git a/src/client.c b/src/client.c
index 410f940..afb9abc 100644
--- a/src/client.c
+++ b/src/client.c
@@ -48,11 +48,10 @@ _assuan_client_finish (assuan_context_t ctx)
_assuan_close (ctx, ctx->outbound.fd);
ctx->outbound.fd = ASSUAN_INVALID_FD;
}
- if (ctx->server_proc != -1)
+ if (ctx->server_proc != NULL)
{
- if (!ctx->flags.is_socket)
- _assuan_waitpid (ctx, ctx->server_proc, ctx->flags.no_waitpid, NULL, 0);
- ctx->server_proc = -1;
+ gpgrt_process_release (ctx->server_proc);
+ ctx->server_proc = NULL;
}
_assuan_uds_deinit (ctx);
diff --git a/src/context.c b/src/context.c
index 4246039..7877136 100644
--- a/src/context.c
+++ b/src/context.c
@@ -70,10 +70,6 @@ assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value)
switch (flag)
{
- case ASSUAN_NO_WAITPID:
- ctx->flags.no_waitpid = value;
- break;
-
case ASSUAN_CONFIDENTIAL:
ctx->flags.confidential = value;
if (ctx->flags.in_inq_cb && value)
@@ -112,10 +108,6 @@ assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag)
switch (flag)
{
- case ASSUAN_NO_WAITPID:
- res = ctx->flags.no_waitpid;
- break;
-
case ASSUAN_CONFIDENTIAL:
res = ctx->flags.confidential;
break;
@@ -219,7 +211,7 @@ assuan_get_pid (assuan_context_t ctx)
* application should be fixed. It's here, only for backward
* compatibility.
*/
- return ctx->server_proc;
+ return (pid_t)-1;
}
diff --git a/src/system.c b/src/system.c
index c6f0b3d..0327abf 100644
--- a/src/system.c
+++ b/src/system.c
@@ -34,6 +34,8 @@
#include <fcntl.h>
#endif
+#include <gpg-error.h>
+
#include "assuan-defs.h"
#include "debug.h"
@@ -293,15 +295,21 @@ _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
FD_CHILD_LIST as given (no remapping), which must be inheritable.
On Unix, call ATFORK with ATFORKVALUE after fork and before exec. */
int
-_assuan_spawn (assuan_context_t ctx, assuan_pid_t *r_pid, const char *name,
- const char **argv,
+_assuan_spawn (assuan_context_t ctx, const char *name, const char **argv,
assuan_fd_t fd_in, assuan_fd_t fd_out,
assuan_fd_t *fd_child_list,
- void (*atfork) (void *opaque, int reserved),
+ void (*atfork) (void *opaque),
void *atforkvalue, unsigned int flags)
{
int res;
int i;
+ gpgrt_spawn_actions_t act = NULL;
+ unsigned int spawn_flags;
+ gpg_err_code_t ec;
+ gpgrt_process_t proc = NULL;
+ int keep_stderr = 0;
+ assuan_fd_t *fdp;
+
TRACE_BEG6 (ctx, ASSUAN_LOG_CTX, "_assuan_spawn", ctx,
"name=%s,fd_in=0x%x,fd_out=0x%x,"
"atfork=%p,atforkvalue=%p,flags=%i",
@@ -327,17 +335,45 @@ _assuan_spawn (assuan_context_t ctx, assuan_pid_t *r_pid, const char *name,
}
}
- res = __assuan_spawn (ctx, r_pid, name, argv, fd_in, fd_out,
- fd_child_list, atfork, atforkvalue, flags);
+ spawn_flags = GPGRT_PROCESS_STDIN_PIPE|GPGRT_PROCESS_STDOUT_PIPE;
+ if ((flags & ASSUAN_SPAWN_DETACHED))
+ spawn_flags |= GPGRT_PROCESS_NO_CONSOLE;
- if (name)
+ if (fd_child_list)
+ {
+ for (fdp = fd_child_list; *fdp != ASSUAN_INVALID_FD; fdp++)
+ if (*fdp == (assuan_fd_t)STDERR_FILENO)
+ {
+ keep_stderr = 1;
+ break;
+ }
+ }
+ if (keep_stderr)
+ spawn_flags |= GPGRT_PROCESS_STDERR_KEEP;
+
+ ec = gpgrt_spawn_actions_new (&act);
+ if (ec)
{
- TRACE_LOG1 ("pid = 0x%x", *r_pid);
+ return -1;
}
- else
+
+#ifdef HAVE_W32_SYSTEM
+ /*FIXME*/
+ gpgrt_spawn_actions_set_inherit_handles (act, fd_child_list);
+ gpgrt_spawn_actions_set_redirect (act, fd_in, fd_out, -1);
+#else
+ gpgrt_spawn_actions_set_inherit_fds (act, fd_child_list);
+ gpgrt_spawn_actions_set_redirect (act, fd_in, fd_out, -1);
+ gpgrt_spawn_actions_set_atfork (act, atfork, atforkvalue);
+#endif
+ ec = gpgrt_process_spawn (name, argv+1, spawn_flags, act, &proc);
+ gpgrt_spawn_actions_release (act);
+ if (ec)
{
- TRACE_LOG2 ("pid = 0x%x (%s)", *r_pid, *argv);
+ return -1;
}
+ ctx->server_proc = proc;
+ res = 0;
return TRACE_SYSERR (res);
}