[network-manager-libreswan/th/vpn-plugin-debug-bgo766872: 22/22] WIP -- ignore for now
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-libreswan/th/vpn-plugin-debug-bgo766872: 22/22] WIP -- ignore for now
- Date: Thu, 9 Jun 2016 15:46:18 +0000 (UTC)
commit 1e21b51753ba98a669d156ba1b83343d89172c40
Author: Thomas Haller <thaller redhat com>
Date: Sun May 29 16:36:07 2016 +0200
WIP -- ignore for now
src/nm-libreswan-service.c | 180 ++++++++++++++++++++++++++++++++++----------
1 files changed, 141 insertions(+), 39 deletions(-)
---
diff --git a/src/nm-libreswan-service.c b/src/nm-libreswan-service.c
index 3ef8915..7dbd858 100644
--- a/src/nm-libreswan-service.c
+++ b/src/nm-libreswan-service.c
@@ -60,8 +60,9 @@
# define DIST_VERSION VERSION
#endif
-#define NM_TYPE_LIBRESWAN_PLUGIN (nm_libreswan_plugin_get_type ())
-#define NM_LIBRESWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LIBRESWAN_PLUGIN,
NMLibreswanPlugin))
+#define NM_TYPE_LIBRESWAN_PLUGIN (nm_libreswan_plugin_get_type ())
+#define NM_LIBRESWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LIBRESWAN_PLUGIN,
NMLibreswanPlugin))
+#define NM_IS_LIBRESWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LIBRESWAN_PLUGIN))
typedef NMVpnServicePlugin NMLibreswanPlugin;
typedef NMVpnServicePluginClass NMLibreswanPluginClass;
@@ -93,6 +94,8 @@ typedef enum {
typedef struct {
GIOChannel *channel;
guint id;
+ guint flush_id;
+ GPid pid;
GString *str;
const char *detail;
} Pipe;
@@ -123,8 +126,7 @@ typedef struct {
GString *io_buf;
char *password;
- Pipe out;
- Pipe err;
+ GSList *pipes;
} NMLibreswanPluginPrivate;
#define NM_LIBRESWAN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LIBRESWAN_PLUGIN,
NMLibreswanPluginPrivate))
@@ -168,71 +170,174 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix)
/****************************************************************/
-static gboolean pr_cb (GIOChannel *source, GIOCondition condition, gpointer user_data);
+static gboolean pipe_callback (GIOChannel *source, GIOCondition condition, gpointer user_data);
static void
-pipe_cleanup (Pipe *pipe)
+pipe_free (Pipe *pipe)
{
- if (pipe->id) {
- g_source_remove (pipe->id);
- pipe->id = 0;
- }
+ nm_clear_g_source (&pipe->id);
+ nm_clear_g_source (&pipe->flush_id);
g_clear_pointer (&pipe->channel, g_io_channel_unref);
if (pipe->str) {
g_string_free (pipe->str, TRUE);
pipe->str = NULL;
}
+ g_slice_free (Pipe, pipe);
+}
+
+static void
+pipe_release (NMLibreswanPlugin *self, Pipe *pipe)
+{
+ NMLibreswanPluginPrivate *priv;
+ GSList *iter;
+
+ g_return_if_fail (NM_IS_LIBRESWAN_PLUGIN (self));
+ g_return_if_fail (pipe);
+
+ priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (self);
+
+ for (iter = priv->pipes; iter; iter = iter->next) {
+ if (iter->data == pipe) {
+ pipe_free (pipe);
+ priv->pipes = g_slist_delete_link (priv->pipes, iter);
+ return;
+ }
+ }
+ g_return_if_reached ();
+}
+
+static void
+pipe_release_all (NMLibreswanPlugin *self, GPid pid)
+{
+ NMLibreswanPluginPrivate *priv;
+ GSList *iter, *iter2;
+
+ g_return_if_fail (NM_IS_LIBRESWAN_PLUGIN (self));
+
+ priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (self);
+
+ for (iter = priv->pipes; iter; ) {
+ Pipe *pipe = iter->data;
+
+ if ( pid != ((GPid) -1)
+ && pid != pipe->pid) {
+ iter = iter->next;
+ continue;
+ }
+
+ pipe_free (pipe);
+ iter2 = iter;
+ iter = iter->next;
+ priv->pipes = g_slist_delete_link (priv->pipes, iter);
+ }
}
static void
-pipe_init (Pipe *pipe, int fd, const char *detail)
+pipe_start (NMLibreswanPlugin *self, GPid pid, int fd, const char *detail)
{
- g_assert (fd >= 0);
- g_assert (detail);
- g_assert (pipe);
+ NMLibreswanPluginPrivate *priv;
+ Pipe *pipe;
+
+ g_return_if_fail (NM_IS_LIBRESWAN_PLUGIN (self));
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (pid > 0);
+ g_return_if_fail (detail);
+
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ _LOGD ("pipe[%ld,%s]: failure to set nonblocking: %s", (long) pid,
+ detail, g_strerror (errno));
+ }
+ pipe = g_slice_new0 (Pipe);
pipe->detail = detail;
+ pipe->pid = pid;
pipe->str = g_string_sized_new (256);
pipe->channel = g_io_channel_unix_new (fd);
g_io_channel_set_encoding (pipe->channel, NULL, NULL);
g_io_channel_set_buffered (pipe->channel, FALSE);
- pipe->id = g_io_add_watch (pipe->channel, G_IO_IN | G_IO_ERR | G_IO_HUP, pr_cb, pipe);
+ pipe->id = g_io_add_watch (pipe->channel, G_IO_IN | G_IO_ERR | G_IO_HUP, pipe_callback, pipe);
+
+ priv = NM_LIBRESWAN_PLUGIN_GET_PRIVATE (self);
+ priv->pipes = g_slist_prepend (priv->pipes, pipe);
}
static gboolean
-pr_cb (GIOChannel *source, GIOCondition condition, gpointer user_data)
+pipe_callback (GIOChannel *source, GIOCondition condition, gpointer user_data)
{
Pipe *pipe = user_data;
char buf[200];
gsize bytes_read = 0;
char *nl;
+ gboolean invalid = FALSE;
+
+ g_return_val_if_fail (pipe && NM_IS_LIBRESWAN_PLUGIN (pipe->self), G_SOURCE_REMOVE);
+
+ nm_clear_g_source (&pipe->flush_id);
if (condition & (G_IO_ERR | G_IO_HUP)) {
- _LOGD ("PTY(%s) pipe error!", pipe->detail);
+ _LOGD ("pipe[%ld,%s] pipe error!", (long) pipe->pid, pipe->detail);
pipe->id = 0;
+ pipe_release (priv->self, pipe);
return G_SOURCE_REMOVE;
}
- g_assert (condition & G_IO_IN);
- while ( (g_io_channel_read_chars (source,
- buf,
- sizeof (buf) - 1,
- &bytes_read,
- NULL) == G_IO_STATUS_NORMAL)
- && bytes_read
- && pipe->str->len < 500)
+ g_return_val_if_fail (condition & G_IO_IN, G_SOURCE_REMOVE);
+
+ while (TRUE) {
+ GIOStatus st;
+ GError *local = NULL;
+
+ st = g_io_channel_read_chars (source,
+ buf,
+ sizeof (buf) - 1,
+ &bytes_read,
+ &local);
+ if (local) {
+ if (pipe->str->len)
+ _LOGD ("pipe[%ld,%s]: %s", (long) pipe->pid, pipe->detail, pipe->str);
+ _LOGD ("pipe[%ld,%s] pipe read error: %s", (long) pipe->pid, pipe->detail,
+ local->message);
+ pipe->id = 0;
+ pipe_release (priv->self, pipe);
+ g_error_free (local);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (st == G_IO_STATUS_AGAIN)
+ return G_SOURCE_CONTINUE;
+
+ if (st != G_IO_STATUS_NORMAL) {
+ if (pipe->str->len)
+ _LOGD ("pipe[%ld,%s]: %s", (long) pipe->pid, pipe->detail, pipe->str);
+ _LOGD ("pipe[%ld,%s] pipe read error", (long) pipe->pid, pipe->detail);
+ pipe->id = 0;
+ pipe_release (priv->self, pipe);
+ g_error_free (local);
+ return G_SOURCE_REMOVE;
+ }
+
+ if (!bytes_read)
+ continue;
+
g_string_append_len (pipe->str, buf, bytes_read);
- /* Print each complete line and remove it from the buffer */
- while (pipe->str->len) {
nl = strpbrk (pipe->str->str, "\n\r");
- if (!nl)
- break;
- *nl = 0; /* Don't print the linebreak */
- if (pipe->str->str[0])
- _LOGD ("PTY(%s): %s", pipe->detail, pipe->str->str);
- g_string_erase (pipe->str, 0, (nl - pipe->str->str) + 1);
- }
+ if (!nl) {
+ /* there is no new-line, */
+ }
+ if (
+
+ /* Print each complete line and remove it from the buffer */
+ while (pipe->str->len) {
+ nl = strpbrk (pipe->str->str, "\n\r");
+ if (!nl)
+ break;
+ *nl = 0; /* Don't print the linebreak */
+ if (pipe->str->str[0])
+ _LOGD ("PTY(%s): %s", pipe->detail, pipe->str->str);
+ g_string_erase (pipe->str, 0, (nl - pipe->str->str) + 1);
+ }
+ }
return G_SOURCE_CONTINUE;
}
@@ -494,9 +599,6 @@ connect_cleanup (NMLibreswanPlugin *self)
priv->io_buf = NULL;
}
- pipe_cleanup (&priv->out);
- pipe_cleanup (&priv->err);
-
if (priv->password) {
memset (priv->password, 0, strlen (priv->password));
g_free (priv->password);
@@ -1664,8 +1766,8 @@ connect_step (NMLibreswanPlugin *self, GError **error)
g_io_channel_set_buffered (priv->channel, FALSE);
priv->io_id = g_io_add_watch (priv->channel, G_IO_IN | G_IO_ERR | G_IO_HUP, io_cb, self);
- pipe_init (&priv->out, up_stdout, "OUT");
- pipe_init (&priv->err, up_stderr, "ERR");
+ pipe_start (self, priv->pid, up_stdout, "OUT");
+ pipe_start (self, priv->pid, up_stderr, "ERR");
return TRUE;
case CONNECT_STEP_LAST:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]