[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