summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-06-16 16:37:20 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-06-21 10:18:16 +0200
commit0189a973fac5a97b13ff83b0f8a1d5044faee82c (patch)
tree94f3104b206a60f4921f9875bb3f7dc2d63dea42
parent170905e720919bde662015d24b3e70ff46e20290 (diff)
downloadnetwork-manager-applet-0189a973fac5a97b13ff83b0f8a1d5044faee82c.tar.gz
vpn-request: don't kill the auth-dialog upon request destroy
When the secrets request is destroyed, we unreferenced the AppletVpnRequest object and also killed any pending authentication dialog. Instead, send a CANCEL message to the dialog to notify it about the cancellation of the request and wait for its termination before destroying the AppletVpnRequest.
-rw-r--r--src/applet-vpn-request.c70
1 files changed, 46 insertions, 24 deletions
diff --git a/src/applet-vpn-request.c b/src/applet-vpn-request.c
index 69f72a7e..292eb38a 100644
--- a/src/applet-vpn-request.c
+++ b/src/applet-vpn-request.c
@@ -41,6 +41,9 @@
#define APPLET_IS_VPN_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APPLET_TYPE_VPN_REQUEST))
#define APPLET_VPN_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APPLET_TYPE_VPN_REQUEST, AppletVpnRequestClass))
+#define MSG_QUIT "QUIT\n\n"
+#define MSG_CANCEL "CANCEL %u %s\n\n"
+
typedef struct {
GObject parent;
} AppletVpnRequest;
@@ -132,6 +135,7 @@ child_finished_cb (GPid pid, gint status, gpointer user_data)
if (settings)
g_variant_unref (settings);
g_clear_error (&error);
+ g_object_unref (self);
}
static gboolean
@@ -140,7 +144,6 @@ child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer user_
VpnSecretsInfo *info = user_data;
AppletVpnRequest *self = info->vpn;
AppletVpnRequestPrivate *priv = APPLET_VPN_REQUEST_GET_PRIVATE (self);
- const char *buf = "QUIT\n\n";
char *str;
int len;
@@ -155,7 +158,7 @@ child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer user_
/* on second line with a newline newline */
if (++priv->num_newlines == 2) {
/* terminate the child */
- if (write (priv->child_stdin, buf, strlen (buf)) == -1)
+ if (write (priv->child_stdin, MSG_QUIT, NM_STRLEN (MSG_QUIT)) == -1)
return TRUE;
}
} else if (len > 0) {
@@ -191,14 +194,52 @@ find_auth_dialog_binary (const char *service,
*out_hints_supported = nm_vpn_plugin_info_supports_hints (plugin);
return g_strdup (auth_dialog);
}
+static const char *
+cancel_reason_to_str (NMSecretAgentCancelReason reason)
+{
+ switch (reason) {
+ case NM_SECRET_AGENT_CANCEL_REASON_CANCELED:
+ return _("the request was canceled");
+ case NM_SECRET_AGENT_CANCEL_REASON_TIMED_OUT:
+ return _("timeout reached");
+ case NM_SECRET_AGENT_CANCEL_REASON_UNKNOWN:
+ default:
+ return _("reason unknown");
+ }
+}
+
+static void
+child_finished_cb2 (GPid pid, gint status, gpointer user_data)
+{
+ g_object_unref (user_data);
+}
static void
free_vpn_secrets_info (SecretsRequest *req)
{
VpnSecretsInfo *info = (VpnSecretsInfo *) req;
+ gs_free char *msg_free = NULL;
+ char *msg;
+
+ if (info->vpn) {
+ AppletVpnRequestPrivate *priv = APPLET_VPN_REQUEST_GET_PRIVATE (info->vpn);
+
+ nm_clear_g_source (&priv->watch_id);
+
+ if (priv->pid) {
+ if (req->canceled) {
+ msg_free = msg = g_strdup_printf (MSG_CANCEL,
+ req->cancel_reason,
+ cancel_reason_to_str (req->cancel_reason));
+ } else
+ msg = MSG_QUIT;
+
+ write (priv->child_stdin, msg, strlen (msg));
+ priv->watch_id = g_child_watch_add (priv->pid, child_finished_cb2, info->vpn);
+ }
- if (info->vpn)
g_object_unref (info->vpn);
+ }
}
size_t
@@ -381,6 +422,7 @@ applet_vpn_request_get_secrets (SecretsRequest *req, GError **error)
/* catch when child is reaped */
priv->watch_id = g_child_watch_add (priv->pid, child_finished_cb, info);
+ g_object_ref (info->vpn);
/* listen to what child has to say */
priv->channel = g_io_channel_unix_new (priv->child_stdout);
@@ -401,18 +443,6 @@ applet_vpn_request_init (AppletVpnRequest *self)
{
}
-static gboolean
-ensure_killed (gpointer data)
-{
- pid_t pid = GPOINTER_TO_INT (data);
-
- if (kill (pid, 0) == 0)
- kill (pid, SIGKILL);
- /* ensure the child is reaped */
- waitpid (pid, NULL, 0);
- return FALSE;
-}
-
static void
dispose (GObject *object)
{
@@ -436,16 +466,8 @@ dispose (GObject *object)
if (priv->channel)
g_io_channel_unref (priv->channel);
- if (priv->pid) {
+ if (priv->pid)
g_spawn_close_pid (priv->pid);
- if (kill (priv->pid, SIGTERM) == 0)
- g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid));
- else {
- kill (priv->pid, SIGKILL);
- /* ensure the child is reaped */
- waitpid (priv->pid, NULL, 0);
- }
- }
g_slist_foreach (priv->lines, (GFunc) g_free, NULL);
g_slist_free (priv->lines);