[Xfce4-commits] r26484 - in libxfce4util/trunk: . libxfce4util

Brian Tarricone kelnos at xfce.org
Sun Dec 16 01:18:02 CET 2007


Author: kelnos
Date: 2007-12-16 00:18:02 +0000 (Sun, 16 Dec 2007)
New Revision: 26484

Added:
   libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.c
   libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.h
Modified:
   libxfce4util/trunk/ChangeLog
   libxfce4util/trunk/configure.in.in
   libxfce4util/trunk/libxfce4util/Makefile.am
   libxfce4util/trunk/libxfce4util/libxfce4util.h
   libxfce4util/trunk/libxfce4util/libxfce4util.symbols
Log:
2007-12-15  Brian Tarricone <bjt23 at cornell.edu>

    * libxfce4util/xfce-posix-signal-handler.{c,h}: new util functions
      for setting up safe POSIX signal handling using pipe(),
      GIOChannel, and the glib main loop.


Modified: libxfce4util/trunk/ChangeLog
===================================================================
--- libxfce4util/trunk/ChangeLog	2007-12-15 22:05:39 UTC (rev 26483)
+++ libxfce4util/trunk/ChangeLog	2007-12-16 00:18:02 UTC (rev 26484)
@@ -1,3 +1,9 @@
+2007-12-15  Brian Tarricone <bjt23 at cornell.edu>
+
+    * libxfce4util/xfce-posix-signal-handler.{c,h}: new util functions
+      for setting up safe POSIX signal handling using pipe(),
+      GIOChannel, and the glib main loop.
+
 2007-05-09	Benedikt Meurer <benny at xfce.org>
 
 	* INSTALL, configure.in.in: Update for latest autoconf.

Modified: libxfce4util/trunk/configure.in.in
===================================================================
--- libxfce4util/trunk/configure.in.in	2007-12-15 22:05:39 UTC (rev 26483)
+++ libxfce4util/trunk/configure.in.in	2007-12-16 00:18:02 UTC (rev 26484)
@@ -98,7 +98,7 @@
 dnl ***************************************
 AC_HEADER_STDC()
 AC_CHECK_HEADERS([err.h errno.h grp.h limits.h locale.h pwd.h \
-                  sys/stat.h sys/types.h sys/utsname.h \
+                  signal.h sys/stat.h sys/types.h sys/utsname.h \
                   sys/wait.h time.h unistd.h])
 AC_CHECK_FUNCS([gethostname getpwnam setenv setlocale strdup unsetenv])
 

Modified: libxfce4util/trunk/libxfce4util/Makefile.am
===================================================================
--- libxfce4util/trunk/libxfce4util/Makefile.am	2007-12-15 22:05:39 UTC (rev 26483)
+++ libxfce4util/trunk/libxfce4util/Makefile.am	2007-12-16 00:18:02 UTC (rev 26484)
@@ -30,6 +30,7 @@
 	xfce-kiosk.h							\
 	xfce-license.h							\
 	xfce-miscutils.h						\
+	xfce-posix-signal-handler.h					\
 	xfce-rc.h							\
 	xfce-resource.h							\
 	xfce-utf8.h
@@ -62,6 +63,7 @@
 	xfce-kiosk.c							\
 	xfce-license.c							\
 	xfce-miscutils.c						\
+	xfce-posix-signal-handler.c					\
 	xfce-private.h							\
 	xfce-rc.c							\
 	xfce-rc-config.c						\

Modified: libxfce4util/trunk/libxfce4util/libxfce4util.h
===================================================================
--- libxfce4util/trunk/libxfce4util/libxfce4util.h	2007-12-15 22:05:39 UTC (rev 26483)
+++ libxfce4util/trunk/libxfce4util/libxfce4util.h	2007-12-16 00:18:02 UTC (rev 26484)
@@ -35,6 +35,7 @@
 #include <libxfce4util/xfce-kiosk.h>
 #include <libxfce4util/xfce-license.h>
 #include <libxfce4util/xfce-miscutils.h>
+#include <libxfce4util/xfce-posix-signal-handler.h>
 #include <libxfce4util/xfce-rc.h>
 #include <libxfce4util/xfce-resource.h>
 #include <libxfce4util/xfce-utf8.h>

Modified: libxfce4util/trunk/libxfce4util/libxfce4util.symbols
===================================================================
--- libxfce4util/trunk/libxfce4util/libxfce4util.symbols	2007-12-15 22:05:39 UTC (rev 26483)
+++ libxfce4util/trunk/libxfce4util/libxfce4util.symbols	2007-12-16 00:18:02 UTC (rev 26484)
@@ -125,6 +125,16 @@
 #endif
 #endif
 
+/* xfce-posix-signal-handler functions */
+#if IN_HEADER(__XFCE_POSIX_SIGNAL_HANDLER_H__)
+#if IN_SOURCE(__XFCE_POSIX_SIGNAL_HANDLER_C__)
+xfce_posix_signal_handler_init
+xfce_posix_signal_handler_shutdown
+xfce_posix_signal_handler_set_handler
+xfce_posix_signal_handler_restore_handler
+#endif
+#endif
+
 /* xfce-resource functions */
 #if IN_HEADER(__XFCE_RESOURCE_H__)
 #if IN_SOURCE(__XFCE_RESOURCE_C__)

Added: libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.c
===================================================================
--- libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.c	                        (rev 0)
+++ libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.c	2007-12-16 00:18:02 UTC (rev 26484)
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2007 Brian Tarricone <bjt23 at cornell.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4util/libxfce4util-alias.h>
+
+#define SIGNAL_PIPE_READ   __signal_pipe[0]
+#define SIGNAL_PIPE_WRITE  __signal_pipe[1]
+
+typedef struct
+{
+    gint signal;
+    XfcePosixSignalHandler handler;
+    gpointer user_data;
+    struct sigaction old_sa;
+} XfcePosixSignalHandlerData;
+
+static gboolean __inited = FALSE;
+static int __signal_pipe[2] = { -1, -1 };
+static GHashTable *__handlers = NULL;
+static GIOChannel *__signal_io = NULL;
+static guint __io_watch_id = 0;
+
+
+static void
+xfce_posix_signal_handler_data_free(XfcePosixSignalHandlerData *hdata)
+{
+    if(!hdata)
+        return;
+    
+    sigaction(hdata->signal, &hdata->old_sa, NULL);
+    g_free(hdata);
+}
+
+static gboolean
+xfce_posix_signal_handler_pipe_io(GIOChannel *source,
+                                  GIOCondition condition,
+                                  gpointer data)
+{
+    int signal = 0;
+    GError *error = NULL;
+    gsize bin = 0;
+    XfcePosixSignalHandlerData *hdata;
+    
+    if(G_IO_STATUS_NORMAL == g_io_channel_read_chars(source, (gchar *)&signal,
+                                                     sizeof(signal), &bin,
+                                                     &error)
+       && bin == sizeof(signal))
+    {
+        hdata = g_hash_table_lookup(__handlers, GINT_TO_POINTER(signal));
+        if(hdata)
+            hdata->handler(signal, hdata->user_data);
+    } else {
+        if(error) {
+            g_critical("Signal pipe read failed: %s\n", error->message);
+            g_error_free(error);
+        } else {
+            g_critical("Short read from signal pipe (expected %d, got %d)\n",
+                       sizeof(signal), bin);
+        }
+    }
+    
+    return TRUE;
+}
+
+static void
+xfce_posix_signal_handler(int signal)
+{
+    write(SIGNAL_PIPE_WRITE, &signal, sizeof(signal));
+}
+
+
+/**
+ * xfce_posix_signal_handler_init:
+ * @error: Location of a #GError to store any possible errors.
+ *
+ * Initializes the POSIX signal handler system.  Must be called
+ * before setting any POSIX signal handlers.
+ *
+ * Returns: %TRUE on success, %FALSE on failure, in which case
+ *          @error will be set.
+ **/
+gboolean
+xfce_posix_signal_handler_init(GError **error)
+{
+    if(G_UNLIKELY(__inited))
+        return TRUE;
+    
+    if(pipe(__signal_pipe)) {
+        if(error) {
+            g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
+                        _("pipe() failed: %s"), strerror(errno));
+        }
+        return FALSE;
+    }
+    
+    __handlers = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+                                       (GDestroyNotify)xfce_posix_signal_handler_data_free);
+    
+    __signal_io = g_io_channel_unix_new(SIGNAL_PIPE_READ);
+    g_io_channel_set_close_on_unref(__signal_io, FALSE);
+    g_io_channel_set_encoding(__signal_io, NULL, NULL);
+    g_io_channel_set_buffered(__signal_io, FALSE);
+    __io_watch_id = g_io_add_watch(__signal_io, G_IO_IN,
+                                   xfce_posix_signal_handler_pipe_io, NULL);
+    
+    __inited = TRUE;
+    return TRUE;
+}
+
+/**
+ * xfce_posix_signal_handler_shutdown:
+ *
+ * Frees all memory associated with the POSIX signal handling system
+ * and restores all default signal handlers.
+ **/
+void
+xfce_posix_signal_handler_shutdown()
+{
+    if(G_UNLIKELY(!__inited))
+        return;
+    
+    g_source_remove(__io_watch_id);
+    __io_watch_id = 0;
+    g_io_channel_unref(__signal_io);
+    __signal_io = NULL;
+    
+    g_hash_table_destroy(__handlers);
+    __handlers = NULL;
+    
+    close(SIGNAL_PIPE_READ);
+    SIGNAL_PIPE_READ = -1;
+    close(SIGNAL_PIPE_WRITE);
+    SIGNAL_PIPE_WRITE = -1;
+    
+    __inited = FALSE;
+}
+
+/**
+ * xfce_posix_signal_handler_set_handler:
+ * @signal: A POSIX signal id number.
+ * @handler: A callback function.
+ * @user_data: Arbitrary data that will be passed to @handler.
+ * @error: Location of a #GError to store any possible errors.
+ *
+ * Sets @handler to be called whenever @signal is caught by the
+ * application.  The @user_data parameter will be passed as an argument
+ * to @handler.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise, in which case
+ *          @error will be set.
+ **/
+gboolean
+xfce_posix_signal_handler_set_handler(gint signal,
+                                      XfcePosixSignalHandler handler,
+                                      gpointer user_data,
+                                      GError **error)
+{
+    XfcePosixSignalHandlerData *hdata;
+    struct sigaction sa;
+    
+    if(G_UNLIKELY(!__inited)) {
+        if(error) {
+            g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                        _("xfce_posix_signal_handler_init() must be called first"));
+        }
+        return FALSE;
+    }
+    
+    if(!handler) {
+        g_warning("NULL signal handler supplied; removing existing handler");
+        xfce_posix_signal_handler_restore_handler(signal);
+        return TRUE;
+    }
+    
+    if(g_hash_table_lookup(__handlers, GINT_TO_POINTER(signal)))
+        xfce_posix_signal_handler_restore_handler(signal);
+    
+    hdata = g_new0(XfcePosixSignalHandlerData, 1);
+    hdata->signal = signal;
+    hdata->handler = handler;
+    hdata->user_data = user_data;
+    
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = xfce_posix_signal_handler;
+    sa.sa_flags = SA_RESTART;
+    
+    if(sigaction(signal, &sa, &hdata->old_sa)) {
+        if(error) {
+            g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
+                        _("sigaction() failed: %s\n"), strerror(errno));
+        }
+        g_free(hdata);
+        return FALSE;
+    }
+    
+    g_hash_table_insert(__handlers, GINT_TO_POINTER(signal), hdata);
+    
+    return TRUE;
+}
+
+/**
+ * xfce_posix_signal_handler_restore_handler:
+ * @signal: A POSIX signal id number.
+ *
+ * Restores the default handler for @signal.
+ **/
+void
+xfce_posix_signal_handler_restore_handler(gint signal)
+{
+    if(G_UNLIKELY(!__inited))
+        return;
+    
+    g_hash_table_remove(__handlers, GINT_TO_POINTER(signal));
+}
+
+
+
+#define __XFCE_POSIX_SIGNAL_HANDLER_C__
+#include <libxfce4util/libxfce4util-aliasdef.c>

Added: libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.h
===================================================================
--- libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.h	                        (rev 0)
+++ libxfce4util/trunk/libxfce4util/xfce-posix-signal-handler.h	2007-12-16 00:18:02 UTC (rev 26484)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007 Brian Tarricone <bjt23 at cornell.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined(LIBXFCE4UTIL_INSIDE_LIBXFCE4UTIL_H) && !defined(LIBXFCE4UTIL_COMPILATION)
+#error "Only <libxfce4util/libxfce4util.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __XFCE_POSIX_SIGNAL_HANDLER_H__
+#define __XFCE_POSIX_SIGNAL_HANDLER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef void (*XfcePosixSignalHandler)(gint signal, gpointer user_data);
+
+gboolean xfce_posix_signal_handler_init(GError **error);
+void xfce_posix_signal_handler_shutdown();
+
+gboolean xfce_posix_signal_handler_set_handler(gint signal,
+                                               XfcePosixSignalHandler handler,
+                                               gpointer user_data,
+                                               GError **error);
+void xfce_posix_signal_handler_restore_handler(gint signal);
+
+G_END_DECLS
+
+#endif  /* __XFCE_POSIX_SIGNAL_HANDLER_H__ */



More information about the Xfce4-commits mailing list