1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <signal.h>
32 #include "signalmap.h"
33
34 static void signal_init(void);
35 #pragma init(signal_init)
36
37 extern void (*handlers[])();
38 extern void maphandler(int, int, struct sigcontext *, char *);
39 extern void (*_siguhandler[])(); /* libucb */
40 extern void _sigvechandler(int, void*, void*); /* libucb */
41
42 extern int maptonewsig();
43 extern int _sigaction();
44 extern int maptonewmask();
45 extern int maptooldmask();
46 extern int _signal();
47 extern int _sigprocmask();
48 extern char *memset();
49 extern int _sigpending();
50
51 typedef struct {
52 unsigned long __sigbits[4];
53 } S5_sigset_t;
54
55 typedef struct {
56 int sa_flags;
57 void (*sa_handler)();
58 S5_sigset_t sa_mask;
59 int sa_resv[2];
60 } S5_sigaction;
61
62 #define S5_SA_ONSTACK 0x00000001
63 #define S5_SA_RESETHAND 0x00000002
64 #define S5_SA_RESTART 0x00000004
65 #define S5_SA_NOCLDSTOP 0x00020000
66
67 int
sigaction(sig,act,oact)68 sigaction(sig, act, oact)
69 int sig;
70 struct sigaction *act, *oact;
71 {
72 S5_sigaction S5_act;
73 S5_sigaction S5_oact;
74 int ret;
75 int newsig;
76 void (*oldhand)();
77 void (*oldsiguhand)();
78
79 newsig = maptonewsig(sig);
80 oldhand = handlers[newsig];
81 oldsiguhand = _siguhandler[newsig];
82 if (act == NULL) {
83 ret = _sigaction(newsig, (S5_sigaction *)NULL, &S5_oact);
84 } else {
85 S5_act.sa_flags = 0;
86 if (act->sa_flags & SA_ONSTACK)
87 S5_act.sa_flags |= S5_SA_ONSTACK;
88 if (act->sa_flags & SA_RESETHAND)
89 S5_act.sa_flags |= S5_SA_RESETHAND;
90 if (act->sa_flags & SA_NOCLDSTOP)
91 S5_act.sa_flags |= S5_SA_NOCLDSTOP;
92 if (!(act->sa_flags & SA_INTERRUPT))
93 S5_act.sa_flags |= S5_SA_RESTART;
94 /*
95 * _sigvechandler() receives control from the OS.
96 * It calls through _siguhandler[] to maphandler(),
97 * which maps the signal number new-to-old, and
98 * calls the user's handler through handlers[].
99 */
100 handlers[newsig] = act->sa_handler;
101 _siguhandler[newsig] = maphandler;
102 if ((act->sa_handler == SIG_DFL) ||
103 (act->sa_handler == SIG_IGN))
104 S5_act.sa_handler = act->sa_handler;
105 else
106 S5_act.sa_handler = _sigvechandler;
107 S5_act.sa_mask.__sigbits[0] = maptonewmask(act->sa_mask);
108 S5_act.sa_mask.__sigbits[1] = 0;
109 S5_act.sa_mask.__sigbits[2] = 0;
110 S5_act.sa_mask.__sigbits[3] = 0;
111
112 ret = _sigaction(newsig, &S5_act, &S5_oact);
113 }
114
115 if ((oact != NULL) && (ret != -1)) {
116 oact->sa_flags = 0;
117 if (S5_oact.sa_flags & S5_SA_ONSTACK)
118 oact->sa_flags |= SA_ONSTACK;
119 if (S5_oact.sa_flags & S5_SA_RESETHAND)
120 oact->sa_flags |= SA_RESETHAND;
121 if (S5_oact.sa_flags & S5_SA_NOCLDSTOP)
122 oact->sa_flags |= SA_NOCLDSTOP;
123 if (!(S5_oact.sa_flags & S5_SA_RESTART))
124 oact->sa_flags |= SA_INTERRUPT;
125 if ((S5_oact.sa_handler == SIG_DFL) ||
126 (S5_oact.sa_handler == SIG_IGN))
127 oact->sa_handler = S5_oact.sa_handler;
128 else
129 oact->sa_handler = oldhand;
130 oact->sa_mask = maptooldmask(S5_oact.sa_mask.__sigbits[0]);
131 }
132 if (ret == -1) {
133 handlers[newsig] = oldhand;
134 _siguhandler[newsig] = oldsiguhand;
135 }
136 return (ret);
137 }
138
139 static void
signal_init()140 signal_init() {
141 #define S5_SIGPOLL 22
142 _signal(S5_SIGPOLL, SIG_IGN);
143 #undef S5_SIGPOLL
144 }
145
146 int
sigprocmask(how,set,oset)147 sigprocmask(how, set, oset)
148 int how;
149 sigset_t *set, *oset;
150 {
151 int how_map[] = {0, 1, 2, 0, 3};
152 int ret;
153 S5_sigset_t s5_set, s5_oset;
154
155 if (set == NULL) /* query */
156 ret = _sigprocmask(how_map[how], NULL, &s5_oset);
157 else {
158 memset(&s5_set, 0, sizeof (S5_sigset_t));
159 s5_set.__sigbits[0] = maptonewmask(*set);
160 ret = _sigprocmask(how_map[how], &s5_set, &s5_oset);
161 }
162 if ((oset != NULL) && (ret == 0))
163 *oset = maptooldmask(s5_oset.__sigbits[0]);
164 return (ret);
165 }
166
167 int
sigpending(set)168 sigpending(set)
169 sigset_t *set;
170 {
171 S5_sigset_t s5_set;
172 int ret;
173
174 ret = _sigpending(&s5_set);
175 *set = maptooldmask(s5_set.__sigbits[0]);
176 return (ret);
177 }
178