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