Reverts commit 387cbe67c3db27e8a61117fedb6e7fad76e409ef. --- generator/generator | 18 +++++++++++++++++- lib/handle.c | 28 +++++++++++++++++++++++++++- tests/closure-lifetimes.c | 4 +++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/generator/generator b/generator/generator index 2cd83f1..25e4aa5 100755 --- a/generator/generator +++ b/generator/generator @@ -1191,7 +1191,9 @@ has been made."; longdesc = "\ Run the command as a subprocess and connect to it over stdin/stdout. This is for use with NBD servers which can -behave like inetd clients, such as C<nbdkit --single>."; +behave like inetd clients, such as C<nbdkit --single>. + +See also C<nbd_kill_command>."; }; "read_only", { @@ -2244,6 +2246,20 @@ The release number is incremented for each release along a particular branch."; }; + "kill_command", { + default_call with + args = [ Int "signal" ]; ret = RErr; + shortdesc = "kill server running as a subprocess"; + longdesc = "\ +This call may be used to kill the server running as a subprocess +that was previously created using C<nbd_connect_command>. You +do not need to use this call. It is only needed if the server +does not exit when the socket is closed. + +The C<signal> flag is the optional signal number to send +(see L<signal(7)>). If signal is C<0> then C<SIGTERM> is sent."; + }; + "supports_tls", { default_call with args = []; ret = RBool; is_locked = false; may_set_error = false; diff --git a/lib/handle.c b/lib/handle.c index 1fe4467..ccfea42 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -22,6 +22,8 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> +#include <signal.h> +#include <assert.h> #include <netdb.h> #include <sys/types.h> #include <sys/wait.h> @@ -124,7 +126,7 @@ nbd_close (struct nbd_handle *h) freeaddrinfo (h->result); if (h->sock) h->sock->ops->close (h->sock); - if (h->pid >= 0) /* XXX kill it? */ + if (h->pid > 0) waitpid (h->pid, NULL, 0); free (h->export_name); @@ -215,6 +217,30 @@ nbd_unlocked_get_version (struct nbd_handle *h) return PACKAGE_VERSION; } +int +nbd_unlocked_kill_command (struct nbd_handle *h, int signal) +{ + if (h->pid == -1) { + set_error (ESRCH, "no subprocess exists"); + return -1; + } + assert (h->pid > 0); + + if (signal == 0) + signal = SIGTERM; + if (signal < 0) { + set_error (EINVAL, "invalid signal number: %d", signal); + return -1; + } + + if (kill (h->pid, signal) == -1) { + set_error (errno, "kill"); + return -1; + } + + return 0; +} + /* NB: is_locked = false, may_set_error = false. */ int nbd_unlocked_supports_tls (struct nbd_handle *h) diff --git a/tests/closure-lifetimes.c b/tests/closure-lifetimes.c index 910bdf4..3ddf4c1 100644 --- a/tests/closure-lifetimes.c +++ b/tests/closure-lifetimes.c @@ -35,7 +35,7 @@ static char *nbdkit_delay[] = { "nbdkit", "-s", "--exit-with-parent", "-v", "--filter=delay", "null", "size=512", - "delay-read=3", + "delay-read=10", NULL }; static unsigned debug_fn_valid; @@ -134,6 +134,7 @@ main (int argc, char *argv[]) assert (read_cb_free == 1); assert (completion_cb_free == 1); + nbd_kill_command (nbd, 0); nbd_close (nbd); /* Test command callbacks are freed if the handle is closed without @@ -149,6 +150,7 @@ main (int argc, char *argv[]) read_cb, NULL, completion_cb, NULL, 0); if (cookie == -1) NBD_ERROR; + nbd_kill_command (nbd, 0); nbd_close (nbd); assert (read_cb_free == 1); -- 2.22.0