From 4a689f0b907d4a98582a9c4b7f6be811924db8ee Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Sat, 17 Oct 2009 12:59:14 -0700 Subject: some tweaks under libc/ needed for nptl * updated kernel-features.h * system is provided by pt-system with nptl * _exit should do exit_group with nptl * tsd tls ptr in libc * rt_sigwaitinfo impl added Signed-off-by: Austin Foxley --- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 103 +++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 libc/sysdeps/linux/common/__rt_sigwaitinfo.c (limited to 'libc/sysdeps/linux/common/__rt_sigwaitinfo.c') diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c new file mode 100644 index 000000000..1adc0fd73 --- /dev/null +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -0,0 +1,103 @@ +/* vi: set sw=4 ts=4: */ +/* + * __rt_sigwaitinfo() for uClibc + * + * Copyright (C) 2006 by Steven Hill + * Copyright (C) 2000-2004 by Erik Andersen + * + * GNU Library General Public License (LGPL) version 2 or later. + */ + +#include +#include +#include + +libc_hidden_proto(memcpy) + +#ifdef __NR_rt_sigtimedwait + +#include + +# ifdef __UCLIBC_HAS_THREADS_NATIVE__ +# include + +static int do_sigwaitinfo(const sigset_t *set, siginfo_t *info) +{ +# ifdef SIGCANCEL + sigset_t tmpset; + + if (set != NULL && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) +# ifdef SIGSETXID + || __builtin_expect (__sigismember (set, SIGSETXID), 0) +# endif + )) + { + /* Create a temporary mask without the bit for SIGCANCEL set. */ + // We are not copying more than we have to. + memcpy (&tmpset, set, _NSIG / 8); + __sigdelset (&tmpset, SIGCANCEL); +# ifdef SIGSETXID + __sigdelset (&tmpset, SIGSETXID); +# endif + set = &tmpset; + } +# endif + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + int result = INLINE_SYSCALL (rt_sigtimedwait, 4, set, info, + NULL, _NSIG / 8); + + /* The kernel generates a SI_TKILL code in si_code in case tkill is + used. tkill is transparently used in raise(). Since having + SI_TKILL as a code is useful in general we fold the results + here. */ + if (result != -1 && info != NULL && info->si_code == SI_TKILL) + info->si_code = SI_USER; + + return result; +} + +/* Return any pending signal or wait for one for the given time. */ +int __sigwaitinfo(const sigset_t *set, siginfo_t *info) +{ + if(SINGLE_THREAD_P) + return do_sigwaitinfo(set, info); + + int oldtype = LIBC_CANCEL_ASYNC(); + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + int result = do_sigwaitinfo(set, info); + + LIBC_CANCEL_RESET(oldtype); + + return result; +} +# else +# define __need_NULL +# include +# define __NR___rt_sigwaitinfo __NR_rt_sigtimedwait +static _syscall4(int, __rt_sigwaitinfo, const sigset_t *, set, + siginfo_t *, info, const struct timespec *, timeout, + size_t, setsize); + +int attribute_hidden __sigwaitinfo(const sigset_t * set, siginfo_t * info) +{ + return __rt_sigwaitinfo(set, info, NULL, _NSIG / 8); +} +# endif +#else +int attribute_hidden __sigwaitinfo(const sigset_t * set, siginfo_t * info) +{ + if (set == NULL) + __set_errno(EINVAL); + else + __set_errno(ENOSYS); + return -1; +} +#endif +libc_hidden_proto(sigwaitinfo) +weak_alias (__sigwaitinfo, sigwaitinfo) +libc_hidden_weak(sigwaitinfo) + -- cgit v1.2.3