Fixed a bug in send_signal_etc(): when using the group-wide form (negative

process ID), it also searched for a group with a negative ID.
Some minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12111 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-03-28 22:00:36 +00:00
parent 29b183b12c
commit 6e3baa44ff
+24 -21
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, [email protected].
* Copyright 2002, Angelo Mottola, [email protected]. * Copyright 2002, Angelo Mottola, [email protected].
* Copyright 2002-2004, Axel Dörfler, [email protected].
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -77,11 +77,12 @@ notify_debugger(struct thread *thread, int signal, struct sigaction *handler,
* caller must be aware that operations before calling this function and after * caller must be aware that operations before calling this function and after
* its return might not belong to the same atomic section. * its return might not belong to the same atomic section.
*/ */
int int
handle_signals(struct thread *thread, cpu_status *state) handle_signals(struct thread *thread, cpu_status *state)
{ {
uint32 signalMask = thread->sig_pending & (~thread->sig_block_mask); uint32 signalMask = thread->sig_pending & (~thread->sig_block_mask);
int i, sig, global_resched = 0; int i, signal, global_resched = 0;
struct sigaction *handler; struct sigaction *handler;
// If SIGKILL[THR] are pending, we ignore other signals. // If SIGKILL[THR] are pending, we ignore other signals.
@@ -108,12 +109,12 @@ handle_signals(struct thread *thread, cpu_status *state)
bool debugSignal = !(~atomic_get(&thread->team->debug_info.flags) bool debugSignal = !(~atomic_get(&thread->team->debug_info.flags)
& (B_TEAM_DEBUG_SIGNALS | B_TEAM_DEBUG_DEBUGGER_INSTALLED)); & (B_TEAM_DEBUG_SIGNALS | B_TEAM_DEBUG_DEBUGGER_INSTALLED));
sig = i + 1; signal = i + 1;
handler = &thread->sig_action[i]; handler = &thread->sig_action[i];
signalMask >>= 1; signalMask >>= 1;
thread->sig_pending &= ~(1L << i); thread->sig_pending &= ~SIGNAL_TO_MASK(signal);
TRACE(("Thread 0x%lx received signal %s\n", thread->id, sigstr[sig])); TRACE(("Thread 0x%lx received signal %s\n", thread->id, sigstr[signal]));
if (handler->sa_handler == SIG_IGN) { if (handler->sa_handler == SIG_IGN) {
// signal is to be ignored // signal is to be ignored
@@ -121,12 +122,12 @@ handle_signals(struct thread *thread, cpu_status *state)
// notify the debugger // notify the debugger
if (debugSignal) if (debugSignal)
notify_debugger(thread, sig, handler, false, state); notify_debugger(thread, signal, handler, false, state);
continue; continue;
} }
if (handler->sa_handler == SIG_DFL) { if (handler->sa_handler == SIG_DFL) {
// default signal behaviour // default signal behaviour
switch (sig) { switch (signal) {
case SIGCHLD: case SIGCHLD:
case SIGWINCH: case SIGWINCH:
case SIGTSTP: case SIGTSTP:
@@ -135,14 +136,14 @@ handle_signals(struct thread *thread, cpu_status *state)
case SIGCONT: case SIGCONT:
// notify the debugger // notify the debugger
if (debugSignal) { if (debugSignal) {
notify_debugger(thread, sig, handler, false, state); notify_debugger(thread, signal, handler, false, state);
} }
continue; continue;
case SIGSTOP: case SIGSTOP:
// notify the debugger // notify the debugger
if (debugSignal) { if (debugSignal) {
if (!notify_debugger(thread, sig, handler, false, if (!notify_debugger(thread, signal, handler, false,
state)) { state)) {
continue; continue;
} }
@@ -158,7 +159,7 @@ handle_signals(struct thread *thread, cpu_status *state)
case SIGABRT: case SIGABRT:
case SIGFPE: case SIGFPE:
case SIGSEGV: case SIGSEGV:
TRACE(("Shutting down thread 0x%lx due to signal #%d\n", thread->id, sig)); TRACE(("Shutting down thread 0x%lx due to signal #%d\n", thread->id, signal));
case SIGKILL: case SIGKILL:
case SIGKILLTHR: case SIGKILLTHR:
default: default:
@@ -166,9 +167,9 @@ handle_signals(struct thread *thread, cpu_status *state)
thread->exit.reason = THREAD_RETURN_INTERRUPTED; thread->exit.reason = THREAD_RETURN_INTERRUPTED;
// notify the debugger // notify the debugger
if (debugSignal && sig != SIGKILL if (debugSignal && signal != SIGKILL
&& sig != SIGKILLTHR) { && signal != SIGKILLTHR) {
if (!notify_debugger(thread, sig, handler, true, if (!notify_debugger(thread, signal, handler, true,
state)) { state)) {
continue; continue;
} }
@@ -191,7 +192,7 @@ handle_signals(struct thread *thread, cpu_status *state)
// notify the debugger // notify the debugger
if (debugSignal) { if (debugSignal) {
if (!notify_debugger(thread, sig, handler, false, state)) if (!notify_debugger(thread, signal, handler, false, state))
continue; continue;
} }
@@ -201,12 +202,12 @@ handle_signals(struct thread *thread, cpu_status *state)
// User defined signal handler // User defined signal handler
TRACE(("### Setting up custom signal handler frame...\n")); TRACE(("### Setting up custom signal handler frame...\n"));
arch_setup_signal_frame(thread, handler, sig, thread->sig_block_mask); arch_setup_signal_frame(thread, handler, signal, thread->sig_block_mask);
if (handler->sa_flags & SA_ONESHOT) if (handler->sa_flags & SA_ONESHOT)
handler->sa_handler = SIG_DFL; handler->sa_handler = SIG_DFL;
if (!(handler->sa_flags & SA_NOMASK)) if (!(handler->sa_flags & SA_NOMASK))
thread->sig_block_mask |= (handler->sa_mask | SIGNAL_TO_MASK(sig)) & BLOCKABLE_SIGS; thread->sig_block_mask |= (handler->sa_mask | SIGNAL_TO_MASK(signal)) & BLOCKABLE_SIGS;
return global_resched; return global_resched;
} else } else
@@ -285,6 +286,7 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags)
scheduler_enqueue_in_run_queue(thread); scheduler_enqueue_in_run_queue(thread);
} }
break; break;
default: default:
if (thread->sig_pending & (~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD))) { if (thread->sig_pending & (~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD))) {
// Interrupt thread if it was waiting // Interrupt thread if it was waiting
@@ -328,7 +330,7 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
thread = thread_get_thread_struct_locked(id); thread = thread_get_thread_struct_locked(-id);
if (thread != NULL) { if (thread != NULL) {
struct process_group *group; struct process_group *group;
struct team *team, *next; struct team *team, *next;
@@ -436,6 +438,7 @@ sigprocmask(int how, const sigset_t *set, sigset_t *oldSet)
* A \a threadID is < 0 specifies the current thread. * A \a threadID is < 0 specifies the current thread.
* *
*/ */
int int
sigaction_etc(thread_id threadID, int signal, const struct sigaction *act, sigaction_etc(thread_id threadID, int signal, const struct sigaction *act,
struct sigaction *oact) struct sigaction *oact)
@@ -492,7 +495,7 @@ sigaction(int signal, const struct sigaction *act, struct sigaction *oact)
} }
// Triggers a SIGALRM to the thread that issued the timer and reschedules /** Triggers a SIGALRM to the thread that issued the timer and reschedules */
static int32 static int32
alarm_event(timer *t) alarm_event(timer *t)
@@ -576,7 +579,7 @@ _user_sigprocmask(int how, const sigset_t *userSet, sigset_t *userOldSet)
int int
_user_sigaction(int sig, const struct sigaction *userAction, struct sigaction *userOldAction) _user_sigaction(int signal, const struct sigaction *userAction, struct sigaction *userOldAction)
{ {
struct sigaction act, oact; struct sigaction act, oact;
status_t status; status_t status;
@@ -585,7 +588,7 @@ _user_sigaction(int sig, const struct sigaction *userAction, struct sigaction *u
|| (userOldAction != NULL && user_memcpy(&oact, userOldAction, sizeof(struct sigaction)) < B_OK)) || (userOldAction != NULL && user_memcpy(&oact, userOldAction, sizeof(struct sigaction)) < B_OK))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
status = sigaction(sig, userAction ? &act : NULL, userOldAction ? &oact : NULL); status = sigaction(signal, userAction ? &act : NULL, userOldAction ? &oact : NULL);
// only copy the old action if a pointer has been given // only copy the old action if a pointer has been given
if (status >= B_OK && userOldAction != NULL if (status >= B_OK && userOldAction != NULL