]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/mips/sigaction.c
Replace FSF snail mail address by URL.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / mips / sigaction.c
CommitLineData
44422d11
RM
1/* Copyright (C) 1997,1998,1999,2000,2002,2003,2004,2006
2 Free Software Foundation, Inc.
f0fe91e7
AJ
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
3214b89b
AJ
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.
f0fe91e7
AJ
9
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
3214b89b
AJ
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
f0fe91e7 14
3214b89b 15 You should have received a copy of the GNU Lesser General Public
ab84e3ff
PE
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
f0fe91e7
AJ
18
19#include <errno.h>
b8ddf7a1 20#include <sgidefs.h>
f0fe91e7
AJ
21#include <signal.h>
22#include <string.h>
23
24#include <sysdep.h>
25#include <sys/syscall.h>
26
24c4c341
AJ
27#include <sgidefs.h>
28
44422d11 29#include <kernel-features.h>
f0fe91e7
AJ
30
31/* The difference here is that the sigaction structure used in the
32 kernel is not the same as we use in the libc. Therefore we must
33 translate it here. */
34#include <kernel_sigaction.h>
35
36#if __ASSUME_REALTIME_SIGNALS == 0
37/* The variable is shared between all wrappers around signal handling
38 functions which have RT equivalents. This is the definition. */
39int __libc_missing_rt_sigs;
40
f0fe91e7 41#endif
f0fe91e7 42
b8ddf7a1 43#if _MIPS_SIM != _ABIO32
ab35974e
AO
44
45# ifdef __NR_rt_sigreturn
46static void restore_rt (void) asm ("__restore_rt");
47# endif
48# ifdef __NR_sigreturn
49static void restore (void) asm ("__restore");
50# endif
51#endif
f0fe91e7
AJ
52
53/* If ACT is not NULL, change the action for SIG to *ACT.
54 If OACT is not NULL, put the old action for SIG in *OACT. */
55int
56__libc_sigaction (sig, act, oact)
57 int sig;
58 const struct sigaction *act;
59 struct sigaction *oact;
60{
61#if __ASSUME_REALTIME_SIGNALS == 0
62 struct old_kernel_sigaction k_sigact, k_osigact;
63#endif
64 int result;
65
66#if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0
67 /* First try the RT signals. */
68# if __ASSUME_REALTIME_SIGNALS == 0
69 if (!__libc_missing_rt_sigs)
70# endif
71 {
72 struct kernel_sigaction kact, koact;
73 /* Save the current error value for later. We need not do this
74 if we are guaranteed to have realtime signals. */
75# if __ASSUME_REALTIME_SIGNALS == 0
76 int saved_errno = errno;
77# endif
78
79 if (act)
80 {
81 kact.k_sa_handler = act->sa_handler;
82 memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t));
83 kact.sa_flags = act->sa_flags;
84# ifdef HAVE_SA_RESTORER
b8ddf7a1 85# if _MIPS_SIM == _ABIO32
f0fe91e7 86 kact.sa_restorer = act->sa_restorer;
ab35974e
AO
87# else
88 kact.sa_restorer = &restore_rt;
89# endif
f0fe91e7
AJ
90# endif
91 }
92
93 /* XXX The size argument hopefully will have to be changed to the
94 real size of the user-level sigset_t. */
95 result = INLINE_SYSCALL (rt_sigaction, 4, sig,
96 act ? __ptrvalue (&kact) : NULL,
97 oact ? __ptrvalue (&koact) : NULL,
98 sizeof (kernel_sigset_t));
99
100# if __ASSUME_REALTIME_SIGNALS == 0
101 if (result >= 0 || errno != ENOSYS)
102# endif
103 {
104 if (oact && result >= 0)
105 {
106 oact->sa_handler = koact.k_sa_handler;
107 memcpy (&oact->sa_mask, &koact.sa_mask,
108 sizeof (kernel_sigset_t));
109 oact->sa_flags = koact.sa_flags;
110# ifdef HAVE_SA_RESTORER
111 oact->sa_restorer = koact.sa_restorer;
112# endif
113 }
114 return result;
115 }
116
117# if __ASSUME_REALTIME_SIGNALS == 0
118 __set_errno (saved_errno);
119 __libc_missing_rt_sigs = 1;
120# endif
121 }
122#endif
123
124#if __ASSUME_REALTIME_SIGNALS == 0
125 if (act)
126 {
127 k_sigact.k_sa_handler = act->sa_handler;
128 k_sigact.sa_mask = act->sa_mask.__val[0];
129 k_sigact.sa_flags = act->sa_flags;
130# ifdef HAVE_SA_RESTORER
131 k_sigact.sa_restorer = act->sa_restorer;
132# endif
133 }
134 result = INLINE_SYSCALL (sigaction, 3, sig,
135 act ? __ptrvalue (&k_sigact) : NULL,
136 oact ? __ptrvalue (&k_osigact) : NULL);
137 if (oact && result >= 0)
138 {
139 oact->sa_handler = k_osigact.k_sa_handler;
140 oact->sa_mask.__val[0] = k_osigact.sa_mask;
141 oact->sa_flags = k_osigact.sa_flags;
142# ifdef HAVE_SA_RESTORER
b8ddf7a1 143# if _MIPS_SIM == _ABIO32
f0fe91e7 144 oact->sa_restorer = k_osigact.sa_restorer;
ab35974e
AO
145# else
146 oact->sa_restorer = &restore;
147# endif
f0fe91e7
AJ
148# endif
149 }
150 return result;
151#endif
152}
c5947147 153libc_hidden_def (__libc_sigaction)
eb22472e 154
bb600a60
DJ
155#ifdef WRAPPER_INCLUDE
156# include WRAPPER_INCLUDE
157#endif
158
eb22472e 159#ifndef LIBC_SIGACTION
f0fe91e7 160weak_alias (__libc_sigaction, __sigaction)
da5f5f79 161libc_hidden_weak (__sigaction)
f0fe91e7 162weak_alias (__libc_sigaction, sigaction)
eb22472e 163#endif
ab35974e
AO
164
165/* NOTE: Please think twice before making any changes to the bits of
166 code below. GDB needs some intimate knowledge about it to
167 recognize them as signal trampolines, and make backtraces through
168 signal handlers work right. Important are both the names
169 (__restore_rt) and the exact instruction sequence.
170 If you ever feel the need to make any changes, please notify the
171 appropriate GDB maintainer. */
172
173#define RESTORE(name, syscall) RESTORE2 (name, syscall)
174#define RESTORE2(name, syscall) \
175asm \
176 ( \
177 ".align 4\n" \
178 "__" #name ":\n" \
179 " li $2, " #syscall "\n" \
180 " syscall\n" \
181 );
182
183/* The return code for realtime-signals. */
b8ddf7a1 184#if _MIPS_SIM != _ABIO32
ab35974e
AO
185# ifdef __NR_rt_sigreturn
186RESTORE (restore_rt, __NR_rt_sigreturn)
187# endif
188# ifdef __NR_sigreturn
189RESTORE (restore, __NR_sigreturn)
190# endif
191#endif