add: case SIGPOLL: case SIGPROF: case SIGSYS: case SIGVTALRM: case SIGXCPU: case SIGXFSZ:
context: handle_signals(struct thread *thread){	uint32 signalMask = atomic_get(&thread->sig_pending)		& ~atomic_get(&thread->sig_block_mask);	struct sigaction *handler;	bool reschedule = false;	int32 i;	// If SIGKILL[THR] are pending, we ignore other signals.	// Otherwise check, if the thread shall stop for debugging.	if (signalMask & KILL_SIGNALS) {		signalMask &= KILL_SIGNALS;	} else if (thread->debug_info.flags & B_THREAD_DEBUG_STOP) {		user_debug_stop_thread();	}	if (signalMask == 0)		return 0;	for (i = 0; i < NSIG; i++) {		bool debugSignal;		int32 signal = i + 1;		if ((signalMask & SIGNAL_TO_MASK(signal)) == 0)			continue;		// clear the signal that we will handle		atomic_and(&thread->sig_pending, ~SIGNAL_TO_MASK(signal));		debugSignal = !(~atomic_get(&thread->team->debug_info.flags)				& (B_TEAM_DEBUG_SIGNALS | B_TEAM_DEBUG_DEBUGGER_INSTALLED));		// ToDo: since sigaction_etc() could clobber the fields at any time,		//		we should actually copy the relevant fields atomically before		//		accessing them (only the debugger is calling sigaction_etc()		//		right now).		handler = &thread->sig_action[i];		TRACE(("Thread 0x%lx received signal %s\n", thread->id, sigstr[signal]));		if (handler->sa_handler == SIG_IGN) {			// signal is to be ignored			// ToDo: apply zombie cleaning on SIGCHLD			// notify the debugger			if (debugSignal)				notify_debugger(thread, signal, handler, false);			continue;		}		if (handler->sa_handler == SIG_DFL) {			// default signal behaviour			switch (signal) {				case SIGCHLD:				case SIGWINCH:				case SIGTSTP:				case SIGTTIN:				case SIGTTOU:				case SIGCONT:					// notify the debugger					if (debugSignal)						notify_debugger(thread, signal, handler, false);					continue;				case SIGSTOP:					// notify the debugger					if (debugSignal						&& !notify_debugger(thread, signal, handler, false))						continue;					thread->next_state = B_THREAD_SUSPENDED;					reschedule = true;					continue;				case SIGQUIT:				case SIGILL:				case SIGTRAP:				case SIGABRT:				case SIGFPE:				case SIGSEGV:					TRACE(("Shutting down thread 0x%lx due to signal #%d\n",						thread->id, signal));				case SIGKILL:				case SIGKILLTHR:				default:					if (thread->exit.reason != THREAD_RETURN_EXIT)						thread->exit.reason = THREAD_RETURN_INTERRUPTED;					// notify the debugger					if (debugSignal && signal != SIGKILL && signal != SIGKILLTHR						&& !notify_debugger(thread, signal, handler, true))						continue;					// ToDo: when we have more than a thread per process,					// it can likely happen (for any thread other than the first)					// that here, interrupts are still disabled.					// Just search for the cause if it still happens!					thread_exit();						// won't return			}		}		// notify the debugger		if (debugSignal && !notify_debugger(thread, signal, handler, false))			continue;		// User defined signal handler		TRACE(("### Setting up custom signal handler frame...\n"));		arch_setup_signal_frame(thread, handler, signal, atomic_get(&thread->sig_block_mask));		if (handler->sa_flags & SA_ONESHOT)			handler->sa_handler = SIG_DFL;		if ((handler->sa_flags & SA_NOMASK) == 0) {			// Update the block mask while the signal handler is running - it			// will be automatically restored when the signal frame is left.			atomic_or(&thread->sig_block_mask,				(handler->sa_mask | SIGNAL_TO_MASK(signal)) & BLOCKABLE_SIGNALS);		}		return reschedule;	}	arch_check_syscall_restart(thread);	return reschedule;}