2005-03-15 Jakub Jelinek <jakub@redhat.com>
[glibc-ports.git] / sysdeps / unix / bsd / sun / m68k / sigtramp.c
blob5a3ca3cf10cbcfff9cdd042505db633f26ec49d9
1 /* Copyright (C) 1993, 1996, 1997, 2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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. */
19 #ifndef __GNUC__
20 #error This file uses GNU C extensions; you must compile with GCC.
21 #endif
23 /* Get the definition of `struct sigcontext'. */
24 #define KERNEL
25 #define sigvec sun_sigvec
26 #define sigstack sun_sigstack
27 #define sigcontext sun_sigcontext
28 #include "/usr/include/sys/signal.h"
29 #undef sigvec
30 #undef sigstack
31 #undef sigcontext
32 #undef NSIG
33 #undef SIGABRT
34 #undef SIGCLD
35 #undef SV_ONSTACK
36 #undef SV_RESETHAND
37 #undef SV_INTERRUPT
38 #undef SA_ONSTACK
39 #undef SA_NOCLDSTOP
40 #undef SIG_ERR
41 #undef SIG_DFL
42 #undef SIG_IGN
43 #undef sigmask
44 #undef SIG_BLOCK
45 #undef SIG_UNBLOCK
46 #undef SIG_SETMASK
48 #include <signal.h>
49 #include <stddef.h>
50 #include <errno.h>
52 /* Defined in __sigvec.S. */
53 extern int __raw_sigvec (int sig, const struct sigvec *vec,
54 struct sigvec *ovec);
56 /* User-specified signal handlers. */
57 #define mytramp 1
58 #ifdef mytramp
59 static __sighandler_t handlers[NSIG];
60 #else
61 #define handlers _sigfunc
62 extern __sighandler_t _sigfunc[];
63 #endif
65 #if mytramp
67 /* Handler for all signals that are handled by a user-specified function.
68 Saves and restores the general regs %g2-%g7, the %y register, and
69 all the FPU regs (including %fsr), around calling the user's handler. */
70 static void
71 trampoline (sig, code, context, addr)
72 int sig;
73 int code;
74 struct sigcontext *context;
75 void *addr;
77 int save[4];
79 /* Save the call-clobbered registers. */
80 asm volatile ("movem%.l d0-d1/a0-a1, %0" : : "m" (save[0]));
82 /* XXX should save/restore FP regs */
84 /* Call the user's handler. */
85 (*((void (*) (int sig, int code, struct sigcontext *context,
86 PTR addr)) handlers[sig]))
87 (sig, code, context, addr);
89 /* Restore the call-clobbered registers. */
90 asm volatile ("movem%.l %0, d0-d1/a0-a1" : : "g" (save[0]) :
91 "d0", "d1", "a0", "a1");
93 __sigreturn (context);
96 #endif
98 int
99 __sigvec (sig, vec, ovec)
100 int sig;
101 const struct sigvec *vec;
102 struct sigvec *ovec;
104 #ifndef mytramp
105 extern void _sigtramp (int);
106 #define trampoline _sigtramp
107 #endif
108 struct sigvec myvec;
109 int mask;
110 __sighandler_t ohandler;
112 if (sig <= 0 || sig >= NSIG)
114 __set_errno (EINVAL);
115 return -1;
118 mask = __sigblock(sigmask(sig));
120 ohandler = handlers[sig];
122 if (vec != NULL &&
123 vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL)
125 handlers[sig] = vec->sv_handler;
126 myvec = *vec;
127 myvec.sv_handler = trampoline;
128 vec = &myvec;
131 if (__raw_sigvec(sig, vec, ovec) < 0)
133 int save = errno;
134 (void) __sigsetmask(mask);
135 errno = save;
136 return -1;
139 if (ovec != NULL && ovec->sv_handler == trampoline)
140 ovec->sv_handler = ohandler;
142 (void) __sigsetmask(mask);
144 return 0;