home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
mint
/
mint095s
/
dossig.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
4KB
|
202 lines
/*
Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
*/
/* dossig.c:: dos signal handling routines */
#include "mint.h"
/*
* send a signal to another process. If pid > 0, send the signal just to
* that process. If pid < 0, send the signal to all processes whose process
* group is -pid. If pid == 0, send the signal to all processes with the
* same process group id.
*
* note: post_sig just posts the signal to the process.
*/
long
p_kill(pid, sig)
int pid, sig;
{
PROC *p;
TRACE("Pkill(%d, %d)", pid, sig);
if (sig < 0 || sig >= NSIG) {
DEBUG("Pkill: signal out of range");
return ERANGE;
}
if (pid < 0)
return killgroup(-pid, sig);
else if (pid == 0)
return killgroup(curproc->pgrp, sig);
else {
p = pid2proc(pid);
if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
DEBUG("Pkill: pid %d not found", pid);
return EFILNF;
}
if (curproc->euid && curproc->ruid != p->ruid) {
DEBUG("Pkill: wrong user");
return EACCDN;
}
/* if the user sends signal 0, don't deliver it -- for users, signal
* 0 is a null signal used to test the existence of a process
*/
if (sig != 0)
post_sig(p, sig);
}
check_sigs();
TRACE("Pkill: returning OK");
return 0;
}
/*
* set a user-specified signal handler, POSIX.1 style
* "oact", if non-null, gets the old signal handling
* behaviour; "act", if non-null, specifies new
* behaviour
*/
long
p_sigaction(sig, act, oact)
int sig;
const struct sigaction *act;
struct sigaction *oact;
{
TRACE("Psigaction(%d)", sig);
if (sig < 1 || sig >= NSIG)
return ERANGE;
if (act && (sig == SIGKILL || sig == SIGSTOP))
return EACCDN;
if (oact) {
oact->sa_handler = curproc->sighandle[sig];
oact->sa_mask = curproc->sigextra[sig];
oact->sa_flags = curproc->sigflags[sig];
}
if (act) {
curproc->sighandle[sig] = act->sa_handler;
curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
curproc->sigflags[sig] = act->sa_flags;
/* various special things that should happen */
if (act->sa_handler == SIG_IGN) {
/* discard pending signals */
curproc->sigpending &= ~(1L<<sig);
}
/* I dunno if this is right, but bash seems to expect it */
curproc->sigmask &= ~(1L<<sig);
}
return 0;
}
/*
* set a user-specified signal handler
*/
long
p_signal(sig, handler)
int sig;
long handler;
{
long oldhandle;
TRACE("Psignal(%d, %lx)", sig, handler);
if (sig < 1 || sig >= NSIG)
return ERANGE;
if (sig == SIGKILL || sig == SIGSTOP)
return EACCDN;
oldhandle = curproc->sighandle[sig];
curproc->sighandle[sig] = handler;
curproc->sigextra[sig] = 0;
curproc->sigflags[sig] = 0;
/* various special things that should happen */
if (handler == SIG_IGN) {
/* discard pending signals */
curproc->sigpending &= ~(1L<<sig);
}
/* I dunno if this is right, but bash seems to expect it */
curproc->sigmask &= ~(1L<<sig);
return oldhandle;
}
/*
* block some signals. Returns the old signal mask.
*/
long
p_sigblock(mask)
ulong mask;
{
ulong oldmask;
TRACE("Psigblock(%lx)",mask);
/* some signals (e.g. SIGKILL) can't be masked */
mask &= ~(UNMASKABLE);
oldmask = curproc->sigmask;
curproc->sigmask |= mask;
return oldmask;
}
/*
* set the signals that we're blocking. Some signals (e.g. SIGKILL)
* can't be masked.
* Returns the old mask.
*/
long
p_sigsetmask(mask)
ulong mask;
{
ulong oldmask;
TRACE("Psigsetmask(%lx)",mask);
oldmask = curproc->sigmask;
curproc->sigmask = mask & ~(UNMASKABLE);
check_sigs(); /* maybe we unmasked something */
return oldmask;
}
/*
* p_sigpending: return which signals are pending delivery
*/
long
p_sigpending()
{
TRACE("Psigpending()");
check_sigs(); /* clear out any that are going to be delivered soon */
return curproc->sigpending;
}
/*
* p_sigpause: atomically set the signals that we're blocking, then pause.
* Some signals (e.g. SIGKILL) can't be masked.
*/
long
p_sigpause(mask)
ulong mask;
{
ulong oldmask;
TRACE("Psigpause(%lx)", mask);
oldmask = curproc->sigmask;
curproc->sigmask = mask & ~(UNMASKABLE);
if (curproc->sigpending & ~(curproc->sigmask))
check_sigs(); /* a signal is immediately pending */
else
sleep(IO_Q, -1L);
curproc->sigmask = oldmask;
check_sigs(); /* maybe we unmasked something */
TRACE("Psigpause: returning OK");
return 0;
}