(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / unix / sysv / linux / mips / sigaction.c
blob09fbe79316f5bb814b23457109ad05d023f5f7d9
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
18 02111-1307 USA. */
20 #include <errno.h>
21 #include <sgidefs.h>
22 #include <signal.h>
23 #include <string.h>
25 #include <sysdep.h>
26 #include <sys/syscall.h>
28 #include <sgidefs.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
34 translate it here. */
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;
42 #endif
44 #if _MIPS_SIM != _ABIO32
46 # ifdef __NR_rt_sigreturn
47 static void restore_rt (void) asm ("__restore_rt");
48 # endif
49 # ifdef __NR_sigreturn
50 static void restore (void) asm ("__restore");
51 # endif
52 #endif
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. */
56 int
57 __libc_sigaction (sig, act, oact)
58 int sig;
59 const struct sigaction *act;
60 struct sigaction *oact;
62 #if __ASSUME_REALTIME_SIGNALS == 0
63 struct old_kernel_sigaction k_sigact, k_osigact;
64 #endif
65 int result;
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)
71 # endif
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;
78 # endif
80 if (act)
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;
88 # else
89 kact.sa_restorer = &restore_rt;
90 # endif
91 # endif
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)
103 # endif
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;
113 # endif
115 return result;
118 # if __ASSUME_REALTIME_SIGNALS == 0
119 __set_errno (saved_errno);
120 __libc_missing_rt_sigs = 1;
121 # endif
123 #endif
125 #if __ASSUME_REALTIME_SIGNALS == 0
126 if (act)
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;
133 # endif
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;
146 # else
147 oact->sa_restorer = &restore;
148 # endif
149 # endif
151 return result;
152 #endif
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)
160 #endif
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) \
172 asm \
174 ".align 4\n" \
175 "__" #name ":\n" \
176 " li $2, " #syscall "\n" \
177 " 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)
184 # endif
185 # ifdef __NR_sigreturn
186 RESTORE (restore, __NR_sigreturn)
187 # endif
188 #endif