2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley Software License Agreement
12 * specifies the terms and conditions for redistribution.
16 * 4.3BSD signal compatibility functions
18 * the implementation interprets signal masks equal to -1 as "all of the
19 * signals in the signal set", thereby allowing signals with numbers
20 * above 32 to be blocked when referenced in code such as:
22 * for (i = 0; i < NSIG; i++)
26 #include <sys/types.h>
27 #include <sys/siginfo.h>
34 #define set2mask(setp) ((setp)->__sigbits[0])
35 #define mask2set(mask, setp) \
36 ((mask) == -1 ? sigfillset(setp) : sigemptyset(setp), (((setp)->__sigbits[0]) = (mask)))
38 void (*_siguhandler
[NSIG
])() = { 0 };
41 * sigstack is emulated with sigaltstack by guessing an appropriate
42 * value for the stack size - on machines that have stacks that grow
43 * upwards, the ss_sp arguments for both functions mean the same thing,
44 * (the initial stack pointer sigstack() is also the stack base
45 * sigaltstack()), so a "very large" value should be chosen for the
46 * stack size - on machines that have stacks that grow downwards, the
47 * ss_sp arguments mean opposite things, so 0 should be used (hopefully
48 * these machines don't have hardware stack bounds registers that pay
49 * attention to sigaltstack()'s size argument.
53 #define SIGSTACKSIZE 0
58 * sigvechandler is the real signal handler installed for all
59 * signals handled in the 4.3BSD compatibility interface - it translates
60 * SVR4 signal hander arguments into 4.3BSD signal handler arguments
61 * and then calls the real handler
65 sigvechandler(int sig
, siginfo_t
*sip
, ucontext_t
*ucp
)
73 sc
.sc_onstack
= ((ucp
->uc_stack
.ss_flags
& SS_ONSTACK
) != 0);
74 sc
.sc_mask
= set2mask(&ucp
->uc_sigmask
);
77 * Machine dependent code begins
79 sc
.sc_sp
= (int) ucp
->uc_mcontext
.gregs
[UESP
];
80 sc
.sc_pc
= (int) ucp
->uc_mcontext
.gregs
[EIP
];
81 sc
.sc_ps
= (int) ucp
->uc_mcontext
.gregs
[EFL
];
82 sc
.sc_eax
= (int) ucp
->uc_mcontext
.gregs
[EAX
];
83 sc
.sc_edx
= (int) ucp
->uc_mcontext
.gregs
[EDX
];
86 * Machine dependent code ends
90 if ((code
= sip
->si_code
) == BUS_OBJERR
)
91 code
= SEGV_MAKE_ERR(sip
->si_errno
);
93 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
|| sig
== SIGBUS
)
95 addr
= (char *)sip
->si_addr
;
99 (*_siguhandler
[sig
])(sig
, code
, &sc
, addr
);
102 ucp
->uc_stack
.ss_flags
|= SS_ONSTACK
;
104 ucp
->uc_stack
.ss_flags
&= ~SS_ONSTACK
;
105 mask2set(sc
.sc_mask
, &ucp
->uc_sigmask
);
108 * Machine dependent code begins
110 ucp
->uc_mcontext
.gregs
[UESP
] = (int) sc
.sc_sp
;
111 ucp
->uc_mcontext
.gregs
[EIP
] = (int) sc
.sc_pc
;
112 ucp
->uc_mcontext
.gregs
[EFL
] = (int) sc
.sc_ps
;
113 ucp
->uc_mcontext
.gregs
[EAX
] = (int) sc
.sc_eax
;
114 ucp
->uc_mcontext
.gregs
[EDX
] = (int) sc
.sc_edx
;
116 * Machine dependent code ends
128 (void) sigprocmask(0, (sigset_t
*)0, &nset
);
129 mask2set(mask
, &nset
);
130 (void) sigprocmask(SIG_SETMASK
, &nset
, &oset
);
131 return set2mask(&oset
);
140 (void) sigprocmask(0, (sigset_t
*)0, &nset
);
141 mask2set(mask
, &nset
);
142 (void) sigprocmask(SIG_BLOCK
, &nset
, &oset
);
143 return set2mask(&oset
);
151 (void) sigprocmask(0, (sigset_t
*)0, &set
);
152 mask2set(mask
, &set
);
153 return (sigsuspend(&set
));
157 sigvec(int sig
, struct sigvec
*nvec
, struct sigvec
*ovec
)
159 struct sigaction nact
;
160 struct sigaction oact
;
161 struct sigaction
*nactp
;
162 void (*ohandler
)(), (*nhandler
)();
164 if (sig
<= 0 || sig
>= NSIG
) {
169 ohandler
= _siguhandler
[sig
];
172 _sigaction(sig
, (struct sigaction
*)0, &nact
);
173 nhandler
= nvec
->sv_handler
;
174 _siguhandler
[sig
] = nhandler
;
175 if (nhandler
!= SIG_DFL
&& nhandler
!= SIG_IGN
)
176 nact
.sa_handler
= (void (*)())sigvechandler
;
178 nact
.sa_handler
= nhandler
;
179 mask2set(nvec
->sv_mask
, &nact
.sa_mask
);
181 if ( sig == SIGTSTP || sig == SIGSTOP )
182 nact.sa_handler = SIG_DFL; */
183 nact
.sa_flags
= SA_SIGINFO
;
184 if (!(nvec
->sv_flags
& SV_INTERRUPT
))
185 nact
.sa_flags
|= SA_RESTART
;
186 if (nvec
->sv_flags
& SV_RESETHAND
)
187 nact
.sa_flags
|= SA_RESETHAND
;
188 if (nvec
->sv_flags
& SV_ONSTACK
)
189 nact
.sa_flags
|= SA_ONSTACK
;
192 nactp
= (struct sigaction
*)0;
194 if (_sigaction(sig
, nactp
, &oact
) < 0) {
195 _siguhandler
[sig
] = ohandler
;
200 if (oact
.sa_handler
== SIG_DFL
|| oact
.sa_handler
== SIG_IGN
)
201 ovec
->sv_handler
= oact
.sa_handler
;
203 ovec
->sv_handler
= ohandler
;
204 ovec
->sv_mask
= set2mask(&oact
.sa_mask
);
206 if (oact
.sa_flags
& SA_ONSTACK
)
207 ovec
->sv_flags
|= SV_ONSTACK
;
208 if (oact
.sa_flags
& SA_RESETHAND
)
209 ovec
->sv_flags
|= SV_RESETHAND
;
210 if (!(oact
.sa_flags
& SA_RESTART
))
211 ovec
->sv_flags
|= SV_INTERRUPT
;
219 signal(int s
, void (*a
)()))()
223 static int mask
[NSIG
];
224 static int flags
[NSIG
];
227 nsv
.sv_mask
= mask
[s
];
228 nsv
.sv_flags
= flags
[s
];
229 if (sigvec(s
, &nsv
, &osv
) < 0)
231 if (nsv
.sv_mask
!= osv
.sv_mask
|| nsv
.sv_flags
!= osv
.sv_flags
) {
232 mask
[s
] = nsv
.sv_mask
= osv
.sv_mask
;
233 flags
[s
] = nsv
.sv_flags
= osv
.sv_flags
& ~SV_RESETHAND
;
234 if (sigvec(s
, &nsv
, (struct sigvec
*)0) < 0)
237 return (osv
.sv_handler
);