diff options
-rw-r--r-- | src/assuan-pipe-connect.c | 37 | ||||
-rw-r--r-- | src/assuan.h.in | 4 | ||||
-rw-r--r-- | src/libassuan.def | 2 | ||||
-rw-r--r-- | src/libassuan.vers | 2 | ||||
-rw-r--r-- | src/system-posix.c | 7 | ||||
-rw-r--r-- | src/system-w32.c | 26 |
6 files changed, 73 insertions, 5 deletions
diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index c116d1d..9669cb3 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -451,3 +451,40 @@ assuan_pipe_connect (assuan_context_t ctx, flags); } +gpg_error_t +assuan_pipe_wait_server_termination (assuan_context_t ctx, int *status, + int no_hang) +{ + assuan_pid_t pid; + + if (ctx->server_proc == -1) + 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); + + /* 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) + ; /* 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 + _assuan_post_syscall (); + } + return 0; +} diff --git a/src/assuan.h.in b/src/assuan.h.in index 30a243c..99444b8 100644 --- a/src/assuan.h.in +++ b/src/assuan.h.in @@ -514,6 +514,10 @@ int assuan_sock_get_nonce (struct sockaddr *addr, int addrlen, int assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce); void assuan_sock_set_system_hooks (assuan_system_hooks_t system_hooks); +gpg_error_t assuan_pipe_wait_server_termination (assuan_context_t ctx, + int *status, int no_hang); + +gpg_error_t assuan_pipe_kill_server (assuan_context_t ctx); /* Set the default system callbacks. This is irreversible. */ void assuan_set_system_hooks (assuan_system_hooks_t system_hooks); diff --git a/src/libassuan.def b/src/libassuan.def index ed9ceaf..d1f0f76 100644 --- a/src/libassuan.def +++ b/src/libassuan.def @@ -116,6 +116,8 @@ EXPORTS assuan_sock_get_flag @95 assuan_sock_connect_byname @96 assuan_sock_set_system_hooks @97 + assuan_pipe_wait_server_termination @98 + assuan_pipe_kill_server @99 ; END diff --git a/src/libassuan.vers b/src/libassuan.vers index 788bb92..1726dcc 100644 --- a/src/libassuan.vers +++ b/src/libassuan.vers @@ -105,6 +105,8 @@ LIBASSUAN_1.0 { assuan_sock_get_flag; assuan_sock_connect_byname; assuan_sock_set_system_hooks; + assuan_pipe_wait_server_termination; + assuan_pipe_kill_server; __assuan_close; __assuan_pipe; diff --git a/src/system-posix.c b/src/system-posix.c index 5f3a7f2..7952907 100644 --- a/src/system-posix.c +++ b/src/system-posix.c @@ -398,12 +398,13 @@ assuan_pid_t __assuan_waitpid (assuan_context_t ctx, assuan_pid_t pid, int nowait, int *status, int options) { + if (nowait) + return 0; + /* We can't just release the PID, a waitpid is mandatory. But NOWAIT in POSIX systems just means the caller already did the waitpid for this child. */ - if (! nowait) - return waitpid (pid, NULL, 0); - return 0; + return waitpid (pid, status, options ? WNOHANG : 0); } diff --git a/src/system-w32.c b/src/system-w32.c index 415cd63..a1ac42f 100644 --- a/src/system-w32.c +++ b/src/system-w32.c @@ -598,8 +598,30 @@ assuan_pid_t __assuan_waitpid (assuan_context_t ctx, assuan_pid_t pid, int nowait, int *status, int options) { - CloseHandle ((HANDLE) pid); - return 0; + int code; + DWORD exit_code; + + (void)ctx; + + if (nowait) + return 0; + + code = WaitForSingleObject ((HANDLE)pid, options? 0: INFINITE); + + if (code == WAIT_OBJECT_0) + { + if (status) + { + GetExitCodeProcess ((HANDLE)pid, &exit_code); + *status = (int)exit_code; + } + CloseHandle ((HANDLE)pid); + return pid; + } + else if (code == WAIT_TIMEOUT) + return 0; + else + return -1; } |