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 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 140 signal_init() { 141 #define S5_SIGPOLL 22 142 _signal(S5_SIGPOLL, SIG_IGN); 143 #undef S5_SIGPOLL 144 } 145 146 int 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 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