diff --git a/man/launch.1.md b/man/launch.1.md index 8d5115a592e22d9c375a7a95ae82afd04b70f03a..4e6d52d863f7b3a4f5086f8bf95454629547fdbc 100644 --- a/man/launch.1.md +++ b/man/launch.1.md @@ -19,6 +19,11 @@ pressure-vessel-launch - client to launch processes in a container [**--**] *COMMAND* [*ARGUMENTS...*] +**pressure-vessel-launch** +[**--verbose**] +{**--bus-name** *NAME*|**--dbus-address** *ADDRESS*|**--socket** *SOCKET*} +**--terminate** + # DESCRIPTION **pressure-vessel-launch** connects to an `AF_UNIX` socket established @@ -70,6 +75,9 @@ as a subprocess of **pressure-vessel-launcher**. (standard input, standard output and standard error) are always forwarded. +**--terminate** +: Instead of running a *COMMAND*, terminate the Launcher server. + **--verbose** : Be more verbose. @@ -86,7 +94,8 @@ on standard error. The exit status is similar to **env**(1): 0 -: The *COMMAND* exited successfully with status 0. +: The *COMMAND* exited successfully with status 0, + or **--terminate** succeeded. 125 : Invalid arguments were given, or **pressure-vessel-launch** failed diff --git a/src/launch.c b/src/launch.c index 1f0f91b449bbb9df4c4b0ff2094120e0b52dd731..812a31e9bdc40082013cd649ab1941120008232f 100644 --- a/src/launch.c +++ b/src/launch.c @@ -292,6 +292,7 @@ static gchar *opt_dbus_address = NULL; static gchar *opt_directory = NULL; static gchar *opt_socket = NULL; static gchar **opt_envs = NULL; +static gboolean opt_terminate = FALSE; static gboolean opt_verbose = FALSE; static gboolean opt_version = FALSE; @@ -323,6 +324,9 @@ static const GOptionEntry options[] = G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &opt_socket, "Connect to a Launcher server listening on this AF_UNIX socket.", "ABSPATH|@ABSTRACT" }, + { "terminate", '\0', + G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_terminate, + "Terminate the Launcher server.", NULL }, { "verbose", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_verbose, "Be more verbose.", NULL }, @@ -408,17 +412,20 @@ main (int argc, goto out; } - /* We have to block the signals we want to forward before we start any - * other thread, and in particular the GDBus worker thread, because - * the signal mask is per-thread. We need all threads to have the same - * mask, otherwise a thread that doesn't have the mask will receive - * process-directed signals, causing the whole process to exit. */ - signal_source = forward_signals (); - - if (signal_source == 0) + if (!opt_terminate) { - launch_exit_status = LAUNCH_EX_FAILED; - goto out; + /* We have to block the signals we want to forward before we start any + * other thread, and in particular the GDBus worker thread, because + * the signal mask is per-thread. We need all threads to have the same + * mask, otherwise a thread that doesn't have the mask will receive + * process-directed signals, causing the whole process to exit. */ + signal_source = forward_signals (); + + if (signal_source == 0) + { + launch_exit_status = LAUNCH_EX_FAILED; + goto out; + } } pv_avoid_gvfs (); @@ -435,7 +442,15 @@ main (int argc, argc--; } - if (argc < 2) + if (opt_terminate) + { + if (argc != 1) + { + glnx_throw (error, "--terminate cannot be combined with a COMMAND"); + goto out; + } + } + else if (argc < 2) { glnx_throw (error, "Usage: %s [OPTIONS] COMMAND [ARG...]", g_get_prgname ()); @@ -534,6 +549,25 @@ main (int argc, g_assert (bus_or_peer_connection != NULL); + if (opt_terminate) + { + reply = g_dbus_connection_call_sync (bus_or_peer_connection, + service_bus_name, + service_obj_path, + service_iface, + "Terminate", + g_variant_new ("()"), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, error); + + if (local_error != NULL) + g_dbus_error_strip_remote_error (local_error); + + goto out; + } + g_dbus_connection_signal_subscribe (bus_or_peer_connection, service_bus_name, /* NULL if p2p */ service_iface,