From 2bbc6df8dc74508eee5a9a04d1b1fa56e6640bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 5 May 2006 15:33:34 +0000 Subject: [PATCH] * The kernel now remembers the signal that killed a thread (if it was killed). * As suggested by Korli, the signal is now encoded in the "reason" field of wait_for_child(). * waitpid() now sets the status passed in so that the signal can be read out (but it still doesn't do it's full job). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17338 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/thread_types.h | 10 ++++------ src/system/kernel/signal.c | 7 +++++-- src/system/kernel/team.c | 5 ++--- src/system/kernel/thread.c | 3 +++ src/system/libroot/posix/sys/wait.c | 19 +++++++++++++------ 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index b4cfe45db1..9c57c2b15c 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -30,10 +30,6 @@ extern spinlock team_spinlock; #define RELEASE_TEAM_LOCK() release_spinlock(&team_spinlock) enum additional_thread_state { -// THREAD_STATE_READY = 0, // ready to run -// THREAD_STATE_RUNNING, // running right now somewhere -// THREAD_STATE_WAITING, // blocked on something -// THREAD_STATE_SUSPENDED, // suspended, not in queue THREAD_STATE_FREE_ON_RESCHED = 7, // free the thread structure upon reschedule // THREAD_STATE_BIRTH // thread is being created }; @@ -55,7 +51,8 @@ struct death_entry { team_id team; thread_id thread; status_t status; - uint32 reason; + uint16 reason; + uint16 signal; }; struct process_session { @@ -174,7 +171,8 @@ struct thread { struct { sem_id sem; status_t status; - uint32 reason; + uint16 reason; + uint16 signal; struct list waiters; } exit; diff --git a/src/system/kernel/signal.c b/src/system/kernel/signal.c index 83ae0e7d58..c766ed95dd 100644 --- a/src/system/kernel/signal.c +++ b/src/system/kernel/signal.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. * Copyright 2002, Angelo Mottola, a.mottola@libero.it. * * Distributed under the terms of the MIT License. @@ -161,8 +161,11 @@ handle_signals(struct thread *thread) case SIGKILL: case SIGKILLTHR: default: - if (thread->exit.reason != THREAD_RETURN_EXIT) + // if the thread exited normally, the exit reason is already set + if (thread->exit.reason != THREAD_RETURN_EXIT) { thread->exit.reason = THREAD_RETURN_INTERRUPTED; + thread->exit.signal = (uint16)signal; + } // notify the debugger if (debugSignal && signal != SIGKILL && signal != SIGKILLTHR diff --git a/src/system/kernel/team.c b/src/system/kernel/team.c index 87712ef54e..e87510e661 100644 --- a/src/system/kernel/team.c +++ b/src/system/kernel/team.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -1648,7 +1648,6 @@ get_death_entry(struct team *team, pid_t child, struct death_entry *death, * to the reason why a thread has died than waitpid() can be. */ - static thread_id wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode) { @@ -1715,7 +1714,7 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC // when we got here, we have a valid death entry, and // already got unregistered from the team or group *_returnCode = death.status; - *_reason = death.reason; + *_reason = (death.signal << 16) | death.reason; return death.thread; diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index b905e27627..920c355dab 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -207,6 +207,7 @@ create_thread_struct(const char *name, thread_id threadID) thread->last_time = 0; thread->exit.status = 0; thread->exit.reason = 0; + thread->exit.signal = 0; list_init(&thread->exit.waiters); sprintf(temp, "thread_0x%lx_retcode_sem", thread->id); @@ -957,6 +958,7 @@ thread_exit(void) death->thread = thread->id; death->status = thread->exit.status; death->reason = thread->exit.reason; + death->signal = thread->exit.signal; } } @@ -1038,6 +1040,7 @@ thread_exit(void) while ((death = list_get_next_item(&thread->exit.waiters, death)) != NULL) { death->status = thread->exit.status; death->reason = thread->exit.reason; + death->signal = thread->exit.signal; } RELEASE_THREAD_LOCK(); diff --git a/src/system/libroot/posix/sys/wait.c b/src/system/libroot/posix/sys/wait.c index 7683a59aad..19abd1a7db 100644 --- a/src/system/libroot/posix/sys/wait.c +++ b/src/system/libroot/posix/sys/wait.c @@ -1,10 +1,11 @@ -/* -** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the Haiku License. -*/ +/* + * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include +#include #include #include @@ -30,8 +31,14 @@ waitpid(pid_t pid, int *_status, int options) thread_id thread = _kern_wait_for_child(pid, options, &reason, &returnCode); if (_status != NULL) { - // ToDo: fill in _status! - *_status = 0; + int status = returnCode & 0xff; + + // ToDo: fill in _status correctly! + // See kernel's wait_for_child() for how the return information is encoded + if (reason & THREAD_RETURN_INTERRUPTED) + status = (reason >> 8) & 0xff00; + + *_status = status; } if (thread < B_OK) {