1 #ifndef _SIGNAL_H_ 2 #define _SIGNAL_H_ 3 4 /* 5 ** Distributed under the terms of the OpenBeOS License. 6 */ 7 8 #include <sys/types.h> 9 10 11 typedef int sig_atomic_t; 12 typedef long sigset_t; 13 14 typedef void (*sig_func_t)(int); 15 typedef void (*__signal_func_ptr)(int); /* deprecated, for compatibility with BeOS only */ 16 17 18 /* 19 * macros defining the standard signal handling behavior 20 */ 21 #define SIG_DFL ((sig_func_t) 0) /* the signal was treated in the "default" manner */ 22 #define SIG_IGN ((sig_func_t) 1) /* the signal was ignored */ 23 #define SIG_ERR ((sig_func_t)-1) /* an error ocurred during signal processing */ 24 25 26 /* 27 * structure used by sigaction() 28 * 29 * Note: the 'sa_userdata' field is a non-Posix extension. 30 * See the SPECIAL NOTES below for an explanation of this. 31 * 32 */ 33 struct sigaction { 34 sig_func_t sa_handler; 35 sigset_t sa_mask; 36 int sa_flags; 37 void *sa_userdata; /* will be passed to the signal handler */ 38 }; 39 40 41 /* 42 * values for sa_flags 43 */ 44 #define SA_NOCLDSTOP 0x01 45 #define SA_ONESHOT 0x02 46 #define SA_NOMASK 0x04 47 #define SA_NODEFER SA_NOMASK 48 #define SA_RESTART 0x08 49 #define SA_STACK 0x10 50 51 52 53 /* 54 * for signals using an alternate stack 55 */ 56 typedef struct stack_t { 57 void *ss_sp; 58 size_t ss_size; 59 int ss_flags; 60 } stack_t; 61 62 63 /* 64 * for the 'how' arg of sigprocmask() 65 */ 66 #define SIG_BLOCK 1 67 #define SIG_UNBLOCK 2 68 #define SIG_SETMASK 3 69 70 71 72 /* 73 * The list of all defined signals: 74 * 75 * The numbering of signals for OpenBeOS attempts to maintain 76 * some consistency with UN*X conventions so that things 77 * like "kill -9" do what you expect. 78 */ 79 #define SIGHUP 1 /* hangup -- tty is gone! */ 80 #define SIGINT 2 /* interrupt */ 81 #define SIGQUIT 3 /* `quit' special character typed in tty */ 82 #define SIGILL 4 /* illegal instruction */ 83 #define SIGCHLD 5 /* child process exited */ 84 #define SIGABRT 6 /* abort() called, dont' catch */ 85 #define SIGPIPE 7 /* write to a pipe w/no readers */ 86 #define SIGFPE 8 /* floating point exception */ 87 #define SIGKILL 9 /* kill a team (not catchable) */ 88 #define SIGSTOP 10 /* suspend a thread (not catchable) */ 89 #define SIGSEGV 11 /* segmentation violation (read: invalid pointer) */ 90 #define SIGCONT 12 /* continue execution if suspended */ 91 #define SIGTSTP 13 /* `stop' special character typed in tty */ 92 #define SIGALRM 14 /* an alarm has gone off (see alarm()) */ 93 #define SIGTERM 15 /* termination requested */ 94 #define SIGTTIN 16 /* read of tty from bg process */ 95 #define SIGTTOU 17 /* write to tty from bg process */ 96 #define SIGUSR1 18 /* app defined signal 1 */ 97 #define SIGUSR2 19 /* app defined signal 2 */ 98 #define SIGWINCH 20 /* tty window size changed */ 99 #define SIGKILLTHR 21 /* be specific: kill just the thread, not team */ 100 #define SIGTRAP 22 101 102 #define SIGBUS SIGSEGV /* for old style code */ 103 104 105 /* 106 * Signal numbers 23-32 are currently free but may be used in future 107 * releases. Use them at your own peril (if you do use them, at least 108 * be smart and use them backwards from signal 32). 109 */ 110 #define MAX_SIGNO 32 /* the most signals that a single thread can reference */ 111 #define __signal_max 22 /* the largest signal number that is actually defined */ 112 #define NSIG (__signal_max+1) /* the number of defined signals */ 113 114 115 116 /* the global table of text strings containing descriptions for each signal */ 117 extern const char * const sys_siglist[NSIG]; 118 119 120 121 #ifdef __cplusplus 122 extern "C" { 123 #endif 124 125 sig_func_t signal(int sig, sig_func_t signal_handler); 126 int raise(int sig); 127 int kill(pid_t pid, int sig); 128 int send_signal(pid_t tid, uint sig); 129 130 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); 131 int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 132 int sigpending(sigset_t *set); 133 int sigsuspend(const sigset_t *mask); 134 135 int sigemptyset(sigset_t *set); 136 int sigfillset(sigset_t *set); 137 static int sigaddset(sigset_t *set, int signo); 138 static int sigdelset(sigset_t *set, int signo); 139 static int sigismember(const sigset_t *set, int signo); 140 141 const char *strsignal(int sig); 142 143 const void set_signal_stack(void *ptr, size_t size); 144 int sigaltstack(const stack_t *ss, stack_t *oss); /* XXXdbg */ 145 146 static inline int 147 sigismember(const sigset_t *set, int sig) 148 { 149 sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ; 150 return (*set & mask) ? 1 : 0 ; 151 } 152 153 static inline int 154 sigaddset(sigset_t *set, int sig) 155 { 156 sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ; 157 return ((*set |= mask), 0) ; 158 } 159 160 static inline int 161 sigdelset(sigset_t *set, int sig) 162 { 163 sigset_t mask = (((sigset_t) 1) << (( sig ) - 1)) ; 164 return ((*set &= ~mask), 0) ; 165 } 166 167 #ifdef __cplusplus 168 } 169 #endif 170 171 172 /* 173 * ================================================== 174 * !!! SPECIAL NOTES CONCERNING NON-POSIX EXTENSIONS: 175 * ================================================== 176 * 177 * The standard Posix interface for signal handlers is not as useful 178 * as it could be. The handler can define only one single argument 179 * (the signal number). For example: 180 * void 181 * my_signal_handler(int sig) 182 * { 183 * . . . 184 * } 185 * 186 * // install the handler 187 * signal(SIGINT, &my_signal_handler); 188 * 189 * The sigaction() function allows finer grained control of the signal 190 * handling. It also allows an opportunity, via the 'sigaction' struct, to 191 * enable additional data to be passed to the handler. For example: 192 * void 193 * my_signal_handler(int sig, char *somedata, vregs regs) 194 * { 195 * . . . 196 * } 197 * 198 * struct sigaction sa; 199 * char data_buffer[32]; 200 * 201 * sa.sa_handler = (sig_func_t) my_signal_handler; 202 * sigemptyset(&sa.sa_mask); 203 * sigaddset(&sa.sa_mask, SIGINT); 204 * sa.sa_userdata = data_buffer; 205 * 206 * // install the handler 207 * sigaction(SIGINT, &sa, NULL); 208 * 209 * The two additional arguments available to the signal handler are extensions 210 * to the Posix standard. This feature was introduced by the BeOS and retained 211 * by OpenBeOS. However, to remain compatible with Posix and ANSI C, the type 212 * of the sa_handler field is defined as 'sig_func_t'. This requires the handler 213 * to be cast when assigned to the sa_handler field, as in the example above. 214 * 215 * NOTE: C++ member functions can not be signal handlers! 216 * This is because they expect a "this" pointer as the first argument. 217 * 218 * 219 * The 3 arguments that OpenBeOS provides to signal handlers are as follows: 220 * 221 * - The first argument is the (usual) signal number. 222 * 223 * - The second argument is whatever value is put in the sa_userdata field 224 * of the sigaction struct. 225 * 226 * - The third argument is a pointer to a vregs struct (defined below). 227 * The vregs struct contains the contents of the volatile registers at 228 * the time the signal was delivered to your thread. You can change the fields 229 * of the structure. After your signal handler completes, the OS uses this struct 230 * to reload the registers for your thread (privileged registers are not loaded 231 * of course). The vregs struct is of course terribly machine dependent. 232 * If you use it, you should expect to have to re-work your code when new 233 * processors come out. Nonetheless, the ability to change the registers does 234 * open some interesting programming possibilities. 235 */ 236 237 238 239 240 /* 241 * the vregs struct: 242 * 243 * signal handlers get this as the last argument 244 */ 245 246 typedef struct vregs vregs; 247 248 #if __POWERPC__ 249 struct vregs 250 { 251 ulong pc, /* program counter */ 252 r0, /* scratch */ 253 r1, /* stack ptr */ 254 r2, /* TOC */ 255 r3,r4,r5,r6,r7,r8,r9,r10, /* volatile regs */ 256 r11,r12; /* scratch regs */ 257 258 double f0, /* fp scratch */ 259 f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13; /* fp volatile regs */ 260 261 ulong filler1, /* place holder */ 262 fpscr, /* fp condition codes */ 263 ctr, xer, cr, msr, lr; /* misc. status */ 264 }; 265 #endif /* __POWERPC__ */ 266 267 #if __INTEL__ 268 269 typedef struct packed_fp_stack { 270 unsigned char st0[10]; 271 unsigned char st1[10]; 272 unsigned char st2[10]; 273 unsigned char st3[10]; 274 unsigned char st4[10]; 275 unsigned char st5[10]; 276 unsigned char st6[10]; 277 unsigned char st7[10]; 278 } packed_fp_stack; 279 280 typedef struct packed_mmx_regs { 281 unsigned char mm0[10]; 282 unsigned char mm1[10]; 283 unsigned char mm2[10]; 284 unsigned char mm3[10]; 285 unsigned char mm4[10]; 286 unsigned char mm5[10]; 287 unsigned char mm6[10]; 288 unsigned char mm7[10]; 289 } packed_mmx_regs; 290 291 typedef struct old_extended_regs { 292 unsigned short fp_control; 293 unsigned short _reserved1; 294 unsigned short fp_status; 295 unsigned short _reserved2; 296 unsigned short fp_tag; 297 unsigned short _reserved3; 298 unsigned long fp_eip; 299 unsigned short fp_cs; 300 unsigned short fp_opcode; 301 unsigned long fp_datap; 302 unsigned short fp_ds; 303 unsigned short _reserved4; 304 union { 305 packed_fp_stack fp; 306 packed_mmx_regs mmx; 307 } fp_mmx; 308 } old_extended_regs; 309 310 typedef struct fp_stack { 311 unsigned char st0[10]; 312 unsigned char _reserved_42_47[6]; 313 unsigned char st1[10]; 314 unsigned char _reserved_58_63[6]; 315 unsigned char st2[10]; 316 unsigned char _reserved_74_79[6]; 317 unsigned char st3[10]; 318 unsigned char _reserved_90_95[6]; 319 unsigned char st4[10]; 320 unsigned char _reserved_106_111[6]; 321 unsigned char st5[10]; 322 unsigned char _reserved_122_127[6]; 323 unsigned char st6[10]; 324 unsigned char _reserved_138_143[6]; 325 unsigned char st7[10]; 326 unsigned char _reserved_154_159[6]; 327 } fp_stack; 328 329 typedef struct mmx_regs { 330 unsigned char mm0[10]; 331 unsigned char _reserved_42_47[6]; 332 unsigned char mm1[10]; 333 unsigned char _reserved_58_63[6]; 334 unsigned char mm2[10]; 335 unsigned char _reserved_74_79[6]; 336 unsigned char mm3[10]; 337 unsigned char _reserved_90_95[6]; 338 unsigned char mm4[10]; 339 unsigned char _reserved_106_111[6]; 340 unsigned char mm5[10]; 341 unsigned char _reserved_122_127[6]; 342 unsigned char mm6[10]; 343 unsigned char _reserved_138_143[6]; 344 unsigned char mm7[10]; 345 unsigned char _reserved_154_159[6]; 346 } mmx_regs; 347 348 typedef struct xmmx_regs { 349 unsigned char xmm0[16]; 350 unsigned char xmm1[16]; 351 unsigned char xmm2[16]; 352 unsigned char xmm3[16]; 353 unsigned char xmm4[16]; 354 unsigned char xmm5[16]; 355 unsigned char xmm6[16]; 356 unsigned char xmm7[16]; 357 } xmmx_regs; 358 359 typedef struct new_extended_regs { 360 unsigned short fp_control; 361 unsigned short fp_status; 362 unsigned short fp_tag; 363 unsigned short fp_opcode; 364 unsigned long fp_eip; 365 unsigned short fp_cs; 366 unsigned short res_14_15; 367 unsigned long fp_datap; 368 unsigned short fp_ds; 369 unsigned short _reserved_22_23; 370 unsigned long mxcsr; 371 unsigned long _reserved_28_31; 372 union { 373 fp_stack fp; 374 mmx_regs mmx; 375 } fp_mmx; 376 xmmx_regs xmmx; 377 unsigned char _reserved_288_511[224]; 378 } new_extended_regs; 379 380 typedef struct extended_regs { 381 union { 382 old_extended_regs old_format; 383 new_extended_regs new_format; 384 } state; 385 unsigned long format; 386 } extended_regs; 387 388 struct vregs { 389 unsigned long eip; 390 unsigned long eflags; 391 unsigned long eax; 392 unsigned long ecx; 393 unsigned long edx; 394 unsigned long esp; 395 unsigned long ebp; 396 unsigned long _reserved_1; 397 extended_regs xregs; 398 unsigned long _reserved_2[3]; 399 }; 400 401 #endif /* __INTEL__ */ 402 403 404 #endif /* _SIGNAL_H_ */ 405