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
= ucp
->uc_mcontext
.gregs
[REG_O6
];
80 sc
.sc_pc
= ucp
->uc_mcontext
.gregs
[REG_PC
];
81 sc
.sc_npc
= ucp
->uc_mcontext
.gregs
[REG_nPC
];
82 sc
.sc_psr
= ucp
->uc_mcontext
.gregs
[REG_PSR
];
83 sc
.sc_g1
= ucp
->uc_mcontext
.gregs
[REG_G1
];
84 sc
.sc_o0
= ucp
->uc_mcontext
.gregs
[REG_O0
];
85 if (ucp
->uc_mcontext
.gwins
!= (gwindows_t
*)0) {
87 sc
.sc_wbcnt
= ucp
->uc_mcontext
.gwins
->wbcnt
;
88 for (i
= 0; i
< MAXWINDOW
; i
++) {
89 for (j
= 0; j
< 16; j
++)
90 sc
.sc_spbuf
[i
][j
] = (int)ucp
->uc_mcontext
.gwins
->spbuf
[j
];
91 for (j
= 0; j
< 8; j
++)
92 sc
.sc_wbuf
[i
][j
] = ucp
->uc_mcontext
.gwins
->wbuf
[i
].rw_local
[j
];
93 for (j
= 0; j
< 8; j
++)
94 sc
.sc_wbuf
[i
][j
+8] = ucp
->uc_mcontext
.gwins
->wbuf
[i
].rw_in
[j
];
98 * Machine dependent code ends
102 if ((code
= sip
->si_code
) == BUS_OBJERR
)
103 code
= SEGV_MAKE_ERR(sip
->si_errno
);
105 if (sig
== SIGILL
|| sig
== SIGFPE
|| sig
== SIGSEGV
|| sig
== SIGBUS
)
107 addr
= (char *)sip
->si_addr
;
111 (*_siguhandler
[sig
])(sig
, code
, &sc
, addr
);
114 ucp
->uc_stack
.ss_flags
|= SS_ONSTACK
;
116 ucp
->uc_stack
.ss_flags
&= ~SS_ONSTACK
;
117 mask2set(sc
.sc_mask
, &ucp
->uc_sigmask
);
120 * Machine dependent code begins
122 ucp
->uc_mcontext
.gregs
[REG_O6
] = sc
.sc_sp
;
123 ucp
->uc_mcontext
.gregs
[REG_PC
] = sc
.sc_pc
;
124 ucp
->uc_mcontext
.gregs
[REG_nPC
] = sc
.sc_npc
;
125 ucp
->uc_mcontext
.gregs
[REG_PSR
] = sc
.sc_psr
;
126 ucp
->uc_mcontext
.gregs
[REG_G1
] = sc
.sc_g1
;
127 ucp
->uc_mcontext
.gregs
[REG_O0
] = sc
.sc_o0
;
128 if (gwinswitch
== 1) {
129 ucp
->uc_mcontext
.gwins
->wbcnt
= sc
.sc_wbcnt
;
130 for (i
= 0; i
< MAXWINDOW
; i
++) {
131 for (j
= 0; j
< 16; j
++)
132 ucp
->uc_mcontext
.gwins
->spbuf
[j
] = (greg_t
*)sc
.sc_spbuf
[i
][j
];
133 for (j
= 0; j
< 8; j
++)
134 ucp
->uc_mcontext
.gwins
->wbuf
[i
].rw_local
[j
] = sc
.sc_wbuf
[i
][j
];
135 for (j
= 0; j
< 8; j
++)
136 ucp
->uc_mcontext
.gwins
->wbuf
[i
].rw_in
[j
] = sc
.sc_wbuf
[i
][j
+8];
140 * Machine dependent code ends
152 (void) sigprocmask(0, (sigset_t
*)0, &nset
);
153 mask2set(mask
, &nset
);
154 (void) sigprocmask(SIG_SETMASK
, &nset
, &oset
);
155 return set2mask(&oset
);
164 (void) sigprocmask(0, (sigset_t
*)0, &nset
);
165 mask2set(mask
, &nset
);
166 (void) sigprocmask(SIG_BLOCK
, &nset
, &oset
);
167 return set2mask(&oset
);
175 (void) sigprocmask(0, (sigset_t
*)0, &set
);
176 mask2set(mask
, &set
);
177 return (sigsuspend(&set
));
181 sigvec(int sig
, struct sigvec
*nvec
, struct sigvec
*ovec
)
183 struct sigaction nact
;
184 struct sigaction oact
;
185 struct sigaction
*nactp
;
186 void (*ohandler
)(), (*nhandler
)();
188 if (sig
<= 0 || sig
>= NSIG
) {
193 ohandler
= _siguhandler
[sig
];
196 _sigaction(sig
, (struct sigaction
*)0, &nact
);
197 nhandler
= nvec
->sv_handler
;
198 _siguhandler
[sig
] = nhandler
;
199 if (nhandler
!= SIG_DFL
&& nhandler
!= SIG_IGN
)
200 nact
.sa_handler
= (void (*)())sigvechandler
;
202 nact
.sa_handler
= nhandler
;
203 mask2set(nvec
->sv_mask
, &nact
.sa_mask
);
205 if ( sig == SIGTSTP || sig == SIGSTOP )
206 nact.sa_handler = SIG_DFL; */
207 nact
.sa_flags
= SA_SIGINFO
;
208 if (!(nvec
->sv_flags
& SV_INTERRUPT
))
209 nact
.sa_flags
|= SA_RESTART
;
210 if (nvec
->sv_flags
& SV_RESETHAND
)
211 nact
.sa_flags
|= SA_RESETHAND
;
212 if (nvec
->sv_flags
& SV_ONSTACK
)
213 nact
.sa_flags
|= SA_ONSTACK
;
216 nactp
= (struct sigaction
*)0;
218 if (_sigaction(sig
, nactp
, &oact
) < 0) {
219 _siguhandler
[sig
] = ohandler
;
224 if (oact
.sa_handler
== SIG_DFL
|| oact
.sa_handler
== SIG_IGN
)
225 ovec
->sv_handler
= oact
.sa_handler
;
227 ovec
->sv_handler
= ohandler
;
228 ovec
->sv_mask
= set2mask(&oact
.sa_mask
);
230 if (oact
.sa_flags
& SA_ONSTACK
)
231 ovec
->sv_flags
|= SV_ONSTACK
;
232 if (oact
.sa_flags
& SA_RESETHAND
)
233 ovec
->sv_flags
|= SV_RESETHAND
;
234 if (!(oact
.sa_flags
& SA_RESTART
))
235 ovec
->sv_flags
|= SV_INTERRUPT
;
243 signal(int s
, void (*a
)()))()
247 static int mask
[NSIG
];
248 static int flags
[NSIG
];
251 nsv
.sv_mask
= mask
[s
];
252 nsv
.sv_flags
= flags
[s
];
253 if (sigvec(s
, &nsv
, &osv
) < 0)
255 if (nsv
.sv_mask
!= osv
.sv_mask
|| nsv
.sv_flags
!= osv
.sv_flags
) {
256 mask
[s
] = nsv
.sv_mask
= osv
.sv_mask
;
257 flags
[s
] = nsv
.sv_flags
= osv
.sv_flags
& ~SV_RESETHAND
;
258 if (sigvec(s
, &nsv
, (struct sigvec
*)0) < 0)
261 return (osv
.sv_handler
);