XMMS2
src/xmms/compat/signal_unix.c
Go to the documentation of this file.
00001 /*  XMMS2 - X Music Multiplexer System
00002  *  Copyright (C) 2003-2011 XMMS2 Team
00003  *
00004  *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2.1 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Lesser General Public License for more details.
00015  */
00016 
00017 
00018 
00019 
00020 /** @file
00021  * Takes care of unix-signals.
00022  */
00023 
00024 
00025 #include "xmmspriv/xmms_signal.h"
00026 #include "xmmspriv/xmms_thread_name.h"
00027 #include "xmms/xmms_log.h"
00028 #include "xmms/xmms_object.h"
00029 
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <signal.h>
00033 #include <string.h>
00034 #include <glib.h>
00035 #include <unistd.h>
00036 
00037 static sigset_t osignals;
00038 
00039 static gpointer
00040 sigwaiter (gpointer data)
00041 {
00042     xmms_object_t *obj = (xmms_object_t *) data;
00043     xmms_object_cmd_arg_t arg;
00044     sigset_t signals;
00045     int caught;
00046 
00047     xmms_set_thread_name ("x2 sig waiter");
00048 
00049     sigemptyset(&signals);
00050     sigaddset (&signals, SIGINT);
00051     sigaddset (&signals, SIGTERM);
00052 
00053     while (1337) {
00054         sigwait (&signals, &caught);
00055 
00056         switch (caught){
00057             case SIGINT:
00058             case SIGTERM:
00059                 pthread_sigmask (SIG_UNBLOCK, &signals, NULL);
00060 
00061                 xmms_log_info ("Bye!");
00062 
00063                 xmms_object_cmd_arg_init (&arg);
00064                 memset (&arg, 0, sizeof (arg));
00065                 arg.args = xmmsv_new_list ();
00066                 xmms_error_reset (&arg.error);
00067                 xmms_object_cmd_call (obj, XMMS_IPC_CMD_QUIT, &arg);
00068                 xmmsv_unref (arg.args);
00069                 break;
00070         }
00071     }
00072 
00073     return 0;
00074 }
00075 
00076 void
00077 xmms_signal_block (void)
00078 {
00079     sigset_t signals;
00080 
00081     sigemptyset(&signals);
00082 
00083     sigaddset (&signals, SIGHUP);
00084     sigaddset (&signals, SIGTERM);
00085     sigaddset (&signals, SIGINT);
00086 
00087     pthread_sigmask (SIG_BLOCK, &signals, &osignals);
00088 
00089     /* Thanks to bug #8533731 in CoreServices on Mac OS X, calling
00090      * FindComponent/AudioComponentNext in the CoreAudio output
00091      * plugin will cause SIGPIPE to be unblocked. To solve this
00092      * we have to fend off SIGPIPE here instead of via sigmask.
00093      * Doesn't affect the behavior on other platforms.
00094      */
00095     signal (SIGPIPE, SIG_IGN);
00096 }
00097 
00098 void
00099 xmms_signal_restore (void)
00100 {
00101     pthread_sigmask (SIG_SETMASK, &osignals, NULL);
00102 }
00103 
00104 void
00105 xmms_signal_init (xmms_object_t *obj)
00106 {
00107     g_thread_create (sigwaiter, obj, FALSE, NULL);
00108 }