diff options
author | NIIBE Yutaka <[email protected]> | 2024-06-07 04:34:41 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2024-06-07 04:34:41 +0000 |
commit | 0127c42da119b8d1a74fccd26d795a0dc9857f5d (patch) | |
tree | ac7402282159e53b05fb10bb9954333bdf39050c | |
parent | Remove system hooks API. (diff) | |
download | libassuan-0127c42da119b8d1a74fccd26d795a0dc9857f5d.tar.gz libassuan-0127c42da119b8d1a74fccd26d795a0dc9857f5d.zip |
posix: Use gpgrt_process_spawn API.
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/assuan-defs.h | 15 | ||||
-rw-r--r-- | src/assuan-pipe-connect.c | 70 | ||||
-rw-r--r-- | src/assuan.c | 2 | ||||
-rw-r--r-- | src/client.c | 7 | ||||
-rw-r--r-- | src/context.c | 10 | ||||
-rw-r--r-- | src/system.c | 54 |
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); } |