+
+void Threads_PostSignalTo(tThread *Thread, int SignalNum)
+{
+ ASSERT(Thread);
+ Log_Debug("Threads", "Signalling %i(%s) with %i", Thread->TID, Thread->ThreadName, SignalNum);
+ Thread->PendingSignal = SignalNum;
+ Threads_PostEvent(Thread, THREAD_EVENT_SIGNAL);
+}
+void Threads_PostSignal(int SignalNum)
+{
+ Threads_PostSignalTo( Proc_GetCurThread(), SignalNum );
+}
+
+void Threads_SignalGroup(tPGID PGID, int Signal)
+{
+ for( tProcess *proc = gAllProcesses; proc; proc = proc->Next )
+ {
+ if(proc->PGID == PGID)
+ {
+ Threads_PostSignalTo(proc->FirstThread, Signal);
+ }
+ }
+}
+
+/**
+ */
+int Threads_GetPendingSignal(void)
+{
+ tThread *cur = Proc_GetCurThread();
+
+ // Atomic AND with 0 fetches and clears in one operation
+ int ret = __sync_fetch_and_and( &cur->PendingSignal, 0 );
+ if( ret )
+ {
+ Log_Debug("Threads", "Thread %i(%s) has signal %i pending",
+ cur->TID, cur->ThreadName, ret);
+ }
+ return ret;
+}
+
+/*
+ * \brief Update the current thread's signal handler
+ */
+void Threads_SetSignalHandler(int SignalNum, void *Handler)
+{
+ if( SignalNum <= 0 || SignalNum >= NSIGNALS )
+ return ;
+ if( !MM_IsUser(Handler) )
+ return ;
+ Proc_GetCurThread()->Process->SignalHandlers[SignalNum] = Handler;
+}
+
+/**
+ * \brief Gets the registered (or default, if none set) handler for a signal.
+ * \return Handler function pointer, OR NULL if no signal to be ignored
+ */
+void *Threads_GetSignalHandler(int SignalNum)
+{
+ // TODO: Core dump
+ void *User_Signal_Core = User_Signal_Kill;
+
+ if( SignalNum <= 0 || SignalNum >= NSIGNALS )
+ return NULL;
+ void *ret = Proc_GetCurThread()->Process->SignalHandlers[SignalNum];
+ if( !ret || (SignalNum == SIGKILL || SignalNum == SIGSTOP) )
+ {
+ // Defaults
+ switch(SignalNum)
+ {
+ case SIGHUP:
+ case SIGINT:
+ ret = User_Signal_Kill;
+ break;
+ case SIGQUIT:
+ case SIGILL:
+ case SIGABRT:
+ case SIGFPE:
+ ret = User_Signal_Core;
+ break;
+ case SIGKILL:
+ ret = User_Signal_Kill;
+ break;
+ case SIGSEGV:
+ ret = User_Signal_Core;
+ break;
+ case SIGPIPE:
+ case SIGALRM:
+ case SIGTERM:
+ ret = User_Signal_Kill;
+ break;
+ default:
+ ret = NULL;
+ break;
+ }
+ }
+ Log_Debug("Threads", "Handler %p for signal %i", ret, SignalNum);
+ return ret;
+}
+