* Implemented sigwait().

* Not sure if it works as intended, as the specs are a bit vague.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24717 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-04-01 12:15:14 +00:00
parent 4d3ebacc42
commit 10f0fc8f20
5 changed files with 92 additions and 10 deletions
+1
View File
@@ -40,6 +40,7 @@ extern status_t _user_sigprocmask(int how, const sigset_t *set,
extern status_t _user_sigaction(int sig, const struct sigaction *newAction, extern status_t _user_sigaction(int sig, const struct sigaction *newAction,
struct sigaction *oldAction); struct sigaction *oldAction);
extern bigtime_t _user_set_alarm(bigtime_t time, uint32 mode); extern bigtime_t _user_set_alarm(bigtime_t time, uint32 mode);
extern status_t _user_sigwait(const sigset_t *set, int *_signal);
extern status_t _user_sigsuspend(const sigset_t *mask); extern status_t _user_sigsuspend(const sigset_t *mask);
extern status_t _user_sigpending(sigset_t *set); extern status_t _user_sigpending(sigset_t *set);
extern status_t _user_set_signal_stack(const stack_t *newUserStack, extern status_t _user_set_signal_stack(const stack_t *newUserStack,
+1
View File
@@ -131,6 +131,7 @@ extern status_t _kern_sigprocmask(int how, const sigset_t *set,
extern status_t _kern_sigaction(int sig, const struct sigaction *action, extern status_t _kern_sigaction(int sig, const struct sigaction *action,
struct sigaction *oldAction); struct sigaction *oldAction);
extern bigtime_t _kern_set_alarm(bigtime_t time, uint32 mode); extern bigtime_t _kern_set_alarm(bigtime_t time, uint32 mode);
extern status_t _kern_sigwait(const sigset_t *set, int *_signal);
extern status_t _kern_sigsuspend(const sigset_t *mask); extern status_t _kern_sigsuspend(const sigset_t *mask);
extern status_t _kern_sigpending(sigset_t *set); extern status_t _kern_sigpending(sigset_t *set);
extern status_t _kern_set_signal_stack(const stack_t *newStack, extern status_t _kern_set_signal_stack(const stack_t *newStack,
+62 -1
View File
@@ -7,6 +7,8 @@
/*! POSIX signals handling routines */ /*! POSIX signals handling routines */
#include <ksignal.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
@@ -17,8 +19,8 @@
#include <debug.h> #include <debug.h>
#include <kernel.h> #include <kernel.h>
#include <kscheduler.h> #include <kscheduler.h>
#include <ksignal.h>
#include <sem.h> #include <sem.h>
#include <syscall_restart.h>
#include <team.h> #include <team.h>
#include <thread.h> #include <thread.h>
#include <tracing.h> #include <tracing.h>
@@ -798,6 +800,46 @@ set_alarm(bigtime_t time, uint32 mode)
} }
/*! Wait for the specified signals, and return the signal retrieved in
\a _signal.
*/
int
sigwait(const sigset_t *set, int *_signal)
{
struct thread *thread = thread_get_current_thread();
int signalsPending = 0;
ConditionVariable<sigset_t> conditionVar;
conditionVar.Publish(set, "sigwait");
while (true) {
ConditionVariableEntry<sigset_t> entry;
entry.Wait(set, B_CAN_INTERRUPT);
if (has_signals_pending(thread)) {
signalsPending = atomic_get(&thread->sig_pending) & *set;
break;
}
}
conditionVar.Unpublish();
update_current_thread_signals_flag();
if (signalsPending) {
// select the lowest pending signal to return in _signal
for (int signal = 1; signal < NSIG; signal++) {
if ((SIGNAL_TO_MASK(signal) & signalsPending) != 0) {
*_signal = signal;
return B_OK;
}
}
}
return B_INTERRUPTED;
}
/*! Replace the current signal block mask and wait for any event to happen. /*! Replace the current signal block mask and wait for any event to happen.
Before returning, the original signal block mask is reinstantiated. Before returning, the original signal block mask is reinstantiated.
*/ */
@@ -915,6 +957,25 @@ _user_sigaction(int signal, const struct sigaction *userAction,
} }
status_t
_user_sigwait(const sigset_t *userSet, int *_userSignal)
{
if (userSet == NULL || _userSignal == NULL)
return B_BAD_VALUE;
sigset_t set;
if (user_memcpy(&set, userSet, sizeof(sigset_t)) < B_OK)
return B_BAD_ADDRESS;
int signal;
status_t status = sigwait(&set, &signal);
if (status < B_OK)
return syscall_restart_handle_post(status);
return user_memcpy(_userSignal, &signal, sizeof(int));
}
status_t status_t
_user_sigsuspend(const sigset_t *userMask) _user_sigsuspend(const sigset_t *userMask)
{ {
+1
View File
@@ -19,5 +19,6 @@ MergeObject posix_signal.o :
sigrelse.cpp sigrelse.cpp
sigset.c sigset.c
sigsuspend.c sigsuspend.c
sigwait.c
strsignal.c strsignal.c
; ;
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <syscalls.h>
#include <signal.h>
int
sigwait(const sigset_t *set, int *_signal)
{
return _kern_sigwait(set, _signal);
// does not set errno, but returns the error value directly
}