1 /* Copyright (C) 1997,1998,1999,2000,2002,2003, 2004
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 #include <sys/syscall.h>
30 #include "kernel-features.h"
32 /* The difference here is that the sigaction structure used in the
33 kernel is not the same as we use in the libc. Therefore we must
35 #include <kernel_sigaction.h>
37 #if __ASSUME_REALTIME_SIGNALS == 0
38 /* The variable is shared between all wrappers around signal handling
39 functions which have RT equivalents. This is the definition. */
40 int __libc_missing_rt_sigs
;
44 #if _MIPS_SIM != _ABIO32
46 # ifdef __NR_rt_sigreturn
47 static void restore_rt (void) asm ("__restore_rt");
49 # ifdef __NR_sigreturn
50 static void restore (void) asm ("__restore");
54 /* If ACT is not NULL, change the action for SIG to *ACT.
55 If OACT is not NULL, put the old action for SIG in *OACT. */
57 __libc_sigaction (sig
, act
, oact
)
59 const struct sigaction
*act
;
60 struct sigaction
*oact
;
62 #if __ASSUME_REALTIME_SIGNALS == 0
63 struct old_kernel_sigaction k_sigact
, k_osigact
;
67 #if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0
68 /* First try the RT signals. */
69 # if __ASSUME_REALTIME_SIGNALS == 0
70 if (!__libc_missing_rt_sigs
)
73 struct kernel_sigaction kact
, koact
;
74 /* Save the current error value for later. We need not do this
75 if we are guaranteed to have realtime signals. */
76 # if __ASSUME_REALTIME_SIGNALS == 0
77 int saved_errno
= errno
;
82 kact
.k_sa_handler
= act
->sa_handler
;
83 memcpy (&kact
.sa_mask
, &act
->sa_mask
, sizeof (kernel_sigset_t
));
84 kact
.sa_flags
= act
->sa_flags
;
85 # ifdef HAVE_SA_RESTORER
86 # if _MIPS_SIM == _ABIO32
87 kact
.sa_restorer
= act
->sa_restorer
;
89 kact
.sa_restorer
= &restore_rt
;
94 /* XXX The size argument hopefully will have to be changed to the
95 real size of the user-level sigset_t. */
96 result
= INLINE_SYSCALL (rt_sigaction
, 4, sig
,
97 act
? __ptrvalue (&kact
) : NULL
,
98 oact
? __ptrvalue (&koact
) : NULL
,
99 sizeof (kernel_sigset_t
));
101 # if __ASSUME_REALTIME_SIGNALS == 0
102 if (result
>= 0 || errno
!= ENOSYS
)
105 if (oact
&& result
>= 0)
107 oact
->sa_handler
= koact
.k_sa_handler
;
108 memcpy (&oact
->sa_mask
, &koact
.sa_mask
,
109 sizeof (kernel_sigset_t
));
110 oact
->sa_flags
= koact
.sa_flags
;
111 # ifdef HAVE_SA_RESTORER
112 oact
->sa_restorer
= koact
.sa_restorer
;
118 # if __ASSUME_REALTIME_SIGNALS == 0
119 __set_errno (saved_errno
);
120 __libc_missing_rt_sigs
= 1;
125 #if __ASSUME_REALTIME_SIGNALS == 0
128 k_sigact
.k_sa_handler
= act
->sa_handler
;
129 k_sigact
.sa_mask
= act
->sa_mask
.__val
[0];
130 k_sigact
.sa_flags
= act
->sa_flags
;
131 # ifdef HAVE_SA_RESTORER
132 k_sigact
.sa_restorer
= act
->sa_restorer
;
135 result
= INLINE_SYSCALL (sigaction
, 3, sig
,
136 act
? __ptrvalue (&k_sigact
) : NULL
,
137 oact
? __ptrvalue (&k_osigact
) : NULL
);
138 if (oact
&& result
>= 0)
140 oact
->sa_handler
= k_osigact
.k_sa_handler
;
141 oact
->sa_mask
.__val
[0] = k_osigact
.sa_mask
;
142 oact
->sa_flags
= k_osigact
.sa_flags
;
143 # ifdef HAVE_SA_RESTORER
144 # if _MIPS_SIM == _ABIO32
145 oact
->sa_restorer
= k_osigact
.sa_restorer
;
147 oact
->sa_restorer
= &restore
;
154 libc_hidden_def (__libc_sigaction
)
156 #ifndef LIBC_SIGACTION
157 weak_alias (__libc_sigaction
, __sigaction
)
158 libc_hidden_weak (__sigaction
)
159 weak_alias (__libc_sigaction
, sigaction
)
162 /* NOTE: Please think twice before making any changes to the bits of
163 code below. GDB needs some intimate knowledge about it to
164 recognize them as signal trampolines, and make backtraces through
165 signal handlers work right. Important are both the names
166 (__restore_rt) and the exact instruction sequence.
167 If you ever feel the need to make any changes, please notify the
168 appropriate GDB maintainer. */
170 #define RESTORE(name, syscall) RESTORE2 (name, syscall)
171 #define RESTORE2(name, syscall) \
176 " li $2, " #syscall "\n" \
180 /* The return code for realtime-signals. */
181 #if _MIPS_SIM != _ABIO32
182 # ifdef __NR_rt_sigreturn
183 RESTORE (restore_rt
, __NR_rt_sigreturn
)
185 # ifdef __NR_sigreturn
186 RESTORE (restore
, __NR_sigreturn
)