[gnome-online-accounts/wip/rishi/identity-kernel-keyring-notification: 2/3] Add GoaLinuxNotificationStream



commit a133a916c10003ae9d53f433627f005302c09c36
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Feb 7 19:18:04 2020 +0100

    Add GoaLinuxNotificationStream
    
    This is a custom GUnixInputStream that's meant to be used with Linux's
    notification pipes. Notifications are sent by the Linux kernel to the
    read end of the pipe. The write end is unused, but should be kept open
    as long as the read end is in use.
    
    A GoaLinuxNotificationStream takes file descriptors for both the read
    and write ends of a pipe, and closes the write end when the stream is
    closed. This makes it easier to track the lifetime of both file
    descriptors.
    
    https://gitlab.gnome.org/GNOME/gnome-online-accounts/merge_requests/47

 po/POTFILES.in                               |   1 +
 src/goaidentity/Makefile.am                  |   2 +
 src/goaidentity/goalinuxnotificationstream.c | 164 +++++++++++++++++++++++++++
 src/goaidentity/goalinuxnotificationstream.h |  36 ++++++
 src/goaidentity/meson.build                  |   4 +-
 5 files changed, 206 insertions(+), 1 deletion(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 279fb64d..f83ad3fb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,3 +25,4 @@ src/goabackend/goawindowsliveprovider.c
 src/goaidentity/goaidentityservice.c
 src/goaidentity/goakerberosidentity.c
 src/goaidentity/goakerberosidentitymanager.c
+src/goaidentity/goalinuxnotificationstream.c
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
index da09a0e4..9273e80e 100644
--- a/src/goaidentity/Makefile.am
+++ b/src/goaidentity/Makefile.am
@@ -34,6 +34,7 @@ identity_headers =                                            \
        goakerberosidentity.h                                   \
        goakerberosidentityinquiry.h                            \
        goakerberosidentitymanager.h                            \
+       goalinuxnotificationstream.h                            \
        $(NULL)
 
 identity_sources =                                             \
@@ -48,6 +49,7 @@ identity_sources =                                            \
        goakerberosidentity.c                                   \
        goakerberosidentityinquiry.c                            \
        goakerberosidentitymanager.c                            \
+       goalinuxnotificationstream.c                            \
        main.c                                                  \
        $(NULL)
 
diff --git a/src/goaidentity/goalinuxnotificationstream.c b/src/goaidentity/goalinuxnotificationstream.c
new file mode 100644
index 00000000..32e05f26
--- /dev/null
+++ b/src/goaidentity/goalinuxnotificationstream.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+
+#include "goalinuxnotificationstream.h"
+
+struct _GoaLinuxNotificationStream
+{
+  GUnixInputStream parent_instance;
+  gint fd_write;
+};
+
+enum
+{
+  PROP_O,
+  PROP_FD_WRITE
+};
+
+G_DEFINE_TYPE (GoaLinuxNotificationStream, goa_linux_notification_stream, G_TYPE_UNIX_INPUT_STREAM);
+
+static gboolean
+goa_linux_notification_stream_close (GInputStream *stream, GCancellable *cancellable, GError **error)
+{
+  GoaLinuxNotificationStream *self = GOA_LINUX_NOTIFICATION_STREAM (stream);
+  gboolean ret_val = FALSE;
+  gint error_code;
+
+  error_code = close (self->fd_write);
+  if (error_code == -1)
+    {
+      GIOErrorEnum error_enum;
+      const gchar *error_str;
+      gint errno_saved = errno;
+
+      error_enum = g_io_error_from_errno (errno_saved);
+      error_str = g_strerror (errno_saved);
+      g_set_error (error, G_IO_ERROR, error_enum, _("Error closing file descriptor: %s"), error_str);
+      goto out;
+    }
+
+  if (!G_INPUT_STREAM_CLASS (goa_linux_notification_stream_parent_class)->close_fn (stream, cancellable, 
error))
+    goto out;
+
+  ret_val = TRUE;
+
+ out:
+  return ret_val;
+}
+
+static void
+goa_linux_notification_stream_close_async (GInputStream *stream,
+                                           gint io_priority,
+                                           GCancellable *cancellable,
+                                           GAsyncReadyCallback callback,
+                                           gpointer user_data)
+{
+  g_autoptr (GTask) task = NULL;
+
+  task = g_task_new (stream, cancellable, callback, user_data);
+  g_task_set_source_tag (task, goa_linux_notification_stream_close_async);
+  g_task_set_priority (task, io_priority);
+
+  {
+    g_autoptr (GError) error = NULL;
+
+    if (!goa_linux_notification_stream_close (stream, cancellable, &error))
+      {
+        g_task_return_error (task, error);
+        goto out;
+      }
+  }
+
+  g_task_return_boolean (task, TRUE);
+
+ out:
+  return;
+}
+
+static gboolean
+goa_linux_notification_stream_close_finish (GInputStream *stream, GAsyncResult *result, GError **error)
+{
+  GTask *task;
+
+  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+  task = G_TASK (result);
+
+  g_return_val_if_fail (g_task_get_source_tag (task) == goa_linux_notification_stream_close_async, FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
+
+static void
+goa_linux_notification_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec 
*pspec)
+{
+  GoaLinuxNotificationStream *self = GOA_LINUX_NOTIFICATION_STREAM (object);
+
+  switch (prop_id)
+    {
+    case PROP_FD_WRITE:
+      self->fd_write = g_value_get_int (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+goa_linux_notification_stream_init (GoaLinuxNotificationStream *self)
+{
+}
+
+static void
+goa_linux_notification_stream_class_init (GoaLinuxNotificationStreamClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
+
+  object_class->set_property = goa_linux_notification_stream_set_property;
+  stream_class->close_async = goa_linux_notification_stream_close_async;
+  stream_class->close_finish = goa_linux_notification_stream_close_finish;
+  stream_class->close_fn = goa_linux_notification_stream_close;
+
+  g_object_class_install_property (object_class,
+                                   PROP_FD_WRITE,
+                                   g_param_spec_int ("fd-write",
+                                                     "A file descriptor for writing to the pipe",
+                                                     "The write end of Linux's notification pipe",
+                                                     G_MININT,
+                                                     G_MAXINT,
+                                                     -1,
+                                                     G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | 
G_PARAM_WRITABLE));
+}
+
+GInputStream *
+goa_linux_notification_stream_new (gint fd_read, gint fd_write)
+{
+  g_return_val_if_fail (fd_read != -1, NULL);
+  g_return_val_if_fail (fd_write != -1, NULL);
+
+  return g_object_new (GOA_TYPE_LINUX_NOTIFICATION_STREAM, "close-fd", TRUE, "fd", fd_read, "fd-write", 
fd_write, NULL);
+}
diff --git a/src/goaidentity/goalinuxnotificationstream.h b/src/goaidentity/goalinuxnotificationstream.h
new file mode 100644
index 00000000..c0e0729e
--- /dev/null
+++ b/src/goaidentity/goalinuxnotificationstream.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GOA_LINUX_NOTIFICATION_STREAM_H__
+#define __GOA_LINUX_NOTIFICATION_STREAM_H__
+
+#include <gio/gunixinputstream.h>
+
+G_BEGIN_DECLS
+
+#define GOA_TYPE_LINUX_NOTIFICATION_STREAM (goa_linux_notification_stream_get_type ())
+G_DECLARE_FINAL_TYPE (GoaLinuxNotificationStream,
+                      goa_linux_notification_stream,
+                      GOA,
+                      LINUX_NOTIFICATION_STREAM,
+                      GUnixInputStream);
+
+GInputStream *goa_linux_notification_stream_new (gint fd_read, gint fd_write);
+
+G_END_DECLS
+
+#endif /* __GOA_KERBEROS_IDENTITY_MANAGER_H__ */
diff --git a/src/goaidentity/meson.build b/src/goaidentity/meson.build
index 0cd6ad1f..dae94d5a 100644
--- a/src/goaidentity/meson.build
+++ b/src/goaidentity/meson.build
@@ -12,7 +12,8 @@ headers = files(
   'goaidentityutils.h',
   'goakerberosidentity.h',
   'goakerberosidentityinquiry.h',
-  'goakerberosidentitymanager.h'
+  'goakerberosidentitymanager.h',
+  'goalinuxnotificationstream.h',
 )
 
 dbus = 'org.gnome.Identity'
@@ -38,6 +39,7 @@ sources = identity_manager_error_src + files(
   'goakerberosidentity.c',
   'goakerberosidentityinquiry.c',
   'goakerberosidentitymanager.c',
+  'goalinuxnotificationstream.c',
   'main.c'
 )
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]