/* sigaction() for MiNT; placed in the public domain */ #include #include #include #include /* vector of signal handlers (for TOS, or for MiNT with -mshort) */ extern __Sigfunc _sig_handler[NSIG]; #ifdef __MSHORT__ typedef void __CDECL (*__KerSigfunc) __PROTO((long)); __EXTERN void __CDECL _trampoline __PROTO((long sig)); #else typedef void __CDECL (*__KerSigfunc) __PROTO((int)); #endif int sigaction(sig, act, oact) int sig; const struct sigaction *act; struct sigaction *oact; { long r; extern int __mint; __Sigfunc oldfunc; if (__mint >= 95) { struct ksigact { __KerSigfunc sa_handler; /* pointer to signal handler */ long sa_mask; /* additional signals masked during delivery */ union { short kernel; int posix; } sa_flags; /* signal specific flags, kernel */ } temp; #ifdef __MSHORT__ /* NOTE: MiNT passes 32 bit numbers for signals, so we want our * own signal dispatcher to switch these to 16 bit ints */ if (sig < 0 || sig >= NSIG) { errno = ERANGE; return -1; } oldfunc = _sig_handler[sig]; if (act) { temp = *(struct ksigact *)act; _sig_handler[sig] = (__Sigfunc)temp.sa_handler; if (_sig_handler[sig] != SIG_DFL && _sig_handler[sig] != SIG_IGN) { temp.sa_handler = _trampoline; } act = (struct sigaction *)&temp; } #else if (act) { temp = *(struct ksigact *)act; /* dept. of sleaze */ temp.sa_flags.kernel = temp.sa_flags.posix; act = (struct sigaction *)&temp; } #endif r = Psigaction(sig, act, oact); #ifdef __MSHORT__ if (oact && oact->sa_handler == (__Sigfunc) _trampoline) oact->sa_handler = oldfunc; #else if (oact) oact->sa_flags = ((struct ksigact *)oact)->sa_flags.kernel; #endif if (r < 0) { errno = (int) -r; return -1; } } else { if (act) oldfunc = signal(sig, act->sa_handler); else { long omask; omask = sigblock(sig); oldfunc = signal(sig, SIG_DFL); signal(sig, oldfunc); /* need to put it back */ sigsetmask(omask); /* may remask sig (this is what we want) */ } if (oldfunc == SIG_ERR) return -1; if (oact) { oact->sa_handler = oldfunc; /* we could do something useful with sa_mask when __mint */ oact->sa_flags = 0; oact->sa_mask = 0; } } return 0; }