]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/sigwait.c
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / sigwait.c
1 /* Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
18
19 #include <errno.h>
20 #include <signal.h>
21 #define __need_NULL
22 #include <stddef.h>
23
24 #include <sysdep-cancel.h>
25 #include <sys/syscall.h>
26 #include <bp-checks.h>
27
28 #ifdef __NR_rt_sigtimedwait
29 extern int __syscall_rt_sigtimedwait (const sigset_t *__unbounded, siginfo_t *__unbounded,
30 const struct timespec *__unbounded, size_t);
31
32
33 /* Return any pending signal or wait for one for the given time. */
34 static int
35 do_sigwait (const sigset_t *set, int *sig)
36 {
37 int ret;
38
39 #ifdef SIGCANCEL
40 sigset_t tmpset;
41 if (set != NULL && __sigismember (set, SIGCANCEL))
42 {
43 /* Create a temporary mask without the bit for SIGCANCEL set. */
44 // We are not copying more than we have to.
45 memcpy (&tmpset, set, _NSIG / 8);
46 __sigdelset (&tmpset, SIGCANCEL);
47 set = &tmpset;
48 }
49 #endif
50
51 /* XXX The size argument hopefully will have to be changed to the
52 real size of the user-level sigset_t. */
53 #ifdef INTERNAL_SYSCALL
54 INTERNAL_SYSCALL_DECL (err);
55 ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, CHECK_SIGSET (set),
56 NULL, NULL, _NSIG / 8);
57 if (! INTERNAL_SYSCALL_ERROR_P (ret, err))
58 {
59 *sig = ret;
60 ret = 0;
61 }
62 else
63 ret = INTERNAL_SYSCALL_ERRNO (ret, err);
64 #else
65 ret = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
66 NULL, NULL, _NSIG / 8);
67 if (ret != -1)
68 {
69 *sig = ret;
70 ret = 0;
71 }
72 else
73 ret = errno;
74 #endif
75
76 return ret;
77 }
78
79 int
80 __sigwait (set, sig)
81 const sigset_t *set;
82 int *sig;
83 {
84 if (SINGLE_THREAD_P)
85 return do_sigwait (set, sig);
86
87 int oldtype = LIBC_CANCEL_ASYNC ();
88
89 int result = do_sigwait (set, sig);
90
91 LIBC_CANCEL_RESET (oldtype);
92
93 return result;
94 }
95 libc_hidden_def (__sigwait)
96 weak_alias (__sigwait, sigwait)
97 #else
98 # include <sysdeps/posix/sigwait.c>
99 #endif
100 strong_alias (__sigwait, __libc_sigwait)