home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari FTP
/
ATARI_FTP_0693.zip
/
ATARI_FTP_0693
/
Mint
/
mntlib32.zoo
/
sigactio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-17
|
4KB
|
235 lines
/* sigaction() and sigset functions for MiNT; placed in the public domain */
#include <errno.h>
#include <osbind.h>
#include <mintbind.h>
#include <signal.h>
/* 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;
}
int
sigaddset(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
set->_sigset_data[idx] |= sigmask(pos);
return 0;
}
int
sigdelset(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
set->_sigset_data[idx] &= ~(sigmask(pos));
return 0;
}
int
sigemptyset(set)
sigset_t *set;
{
int idx;
if (!set) {
errno = EINVAL;
return -1;
}
for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
set->_sigset_data[idx] = 0UL;
}
return 0;
}
int
sigfillset(set)
sigset_t *set;
{
int idx;
if (!set) {
errno = EINVAL;
return -1;
}
for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
set->_sigset_data[idx] = ~0UL;
}
return 0;
}
int
sigismember(set, signo)
sigset_t *set;
int signo;
{
int idx;
int pos;
if ((!set) || (signo >= NSIG)) {
errno = EINVAL;
return -1;
}
idx = _SIGSET_INDEX(signo);
pos = _SIGSET_BITPOS(signo);
return (set->_sigset_data[idx] & sigmask(pos)) ? 1 : 0;
}
int
sigpending(set)
sigset_t *set;
{
if (!set) {
errno = EINVAL;
return -1;
}
(void) sigemptyset(set);
set->_sigset_data[0] = Psigpending();
}
int
sigprocmask(how, set, oset)
int how;
const sigset_t *set;
sigset_t *oset;
{
int rv = 0;
long omask = 0L;
if (!set) {
errno = EINVAL;
return -1;
}
switch (how) {
case SIG_BLOCK:
omask = Psigblock(set->_sigset_data[0]);
break;
case SIG_UNBLOCK:
omask = Psigblock(0L);
(void) Psigsetmask(omask & ~(set->_sigset_data[0]));
break;
case SIG_SETMASK:
omask = Psigsetmask(set->_sigset_data[0]);
break;
default:
errno = EINVAL;
rv = -1;
}
if (oset) oset->_sigset_data[0] = omask;
return rv;
}
int
sigsuspend(sigmask)
const sigset_t *sigmask;
{
Psigpause(sigmask->_sigset_data[0]);
errno = EINTR;
return -1;
}