2005-05-03 17:35:52 +02:00
|
|
|
/* This file handles signals, which are asynchronous events and are generally
|
|
|
|
* a messy and unpleasant business. Signals can be generated by the KILL
|
|
|
|
* system call, or from the keyboard (SIGINT) or from the clock (SIGALRM).
|
|
|
|
* In all cases control eventually passes to check_sig() to see which processes
|
|
|
|
* can be signaled. The actual signaling is done by sig_proc().
|
|
|
|
*
|
|
|
|
* The entry points into this file are:
|
|
|
|
* do_sigaction: perform the SIGACTION system call
|
|
|
|
* do_sigpending: perform the SIGPENDING system call
|
|
|
|
* do_sigprocmask: perform the SIGPROCMASK system call
|
|
|
|
* do_sigreturn: perform the SIGRETURN system call
|
|
|
|
* do_sigsuspend: perform the SIGSUSPEND system call
|
|
|
|
* do_kill: perform the KILL system call
|
|
|
|
* do_pause: perform the PAUSE system call
|
|
|
|
* ksig_pending: the kernel notified about pending signals
|
|
|
|
* sig_proc: interrupt or terminate a signaled process
|
|
|
|
* check_sig: check which processes to signal with sig_proc()
|
|
|
|
* check_pending: check if a pending signal can now be delivered
|
|
|
|
*/
|
|
|
|
|
2005-05-13 10:57:08 +02:00
|
|
|
#include "pm.h"
|
2005-05-03 17:35:52 +02:00
|
|
|
#include <sys/stat.h>
|
2005-07-27 14:03:09 +02:00
|
|
|
#include <sys/ptrace.h>
|
2005-05-03 17:35:52 +02:00
|
|
|
#include <minix/callnr.h>
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
#include <minix/endpoint.h>
|
2005-05-03 17:35:52 +02:00
|
|
|
#include <minix/com.h>
|
2008-11-19 13:26:10 +01:00
|
|
|
#include <minix/vm.h>
|
2005-05-03 17:35:52 +02:00
|
|
|
#include <signal.h>
|
2006-05-11 16:57:23 +02:00
|
|
|
#include <sys/resource.h>
|
2005-05-03 17:35:52 +02:00
|
|
|
#include <sys/sigcontext.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "mproc.h"
|
|
|
|
#include "param.h"
|
|
|
|
|
2006-05-11 16:57:23 +02:00
|
|
|
FORWARD _PROTOTYPE( void unpause, (int pro, int for_trace) );
|
2006-03-10 17:10:05 +01:00
|
|
|
FORWARD _PROTOTYPE( void handle_ksig, (int proc_nr, sigset_t sig_map) );
|
2005-05-03 17:35:52 +02:00
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* do_sigaction *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_sigaction()
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct sigaction svec;
|
|
|
|
struct sigaction *svp;
|
|
|
|
|
|
|
|
if (m_in.sig_nr == SIGKILL) return(OK);
|
|
|
|
if (m_in.sig_nr < 1 || m_in.sig_nr > _NSIG) return (EINVAL);
|
|
|
|
svp = &mp->mp_sigact[m_in.sig_nr];
|
|
|
|
if ((struct sigaction *) m_in.sig_osa != (struct sigaction *) NULL) {
|
|
|
|
r = sys_datacopy(PM_PROC_NR,(vir_bytes) svp,
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
who_e, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec));
|
2005-05-03 17:35:52 +02:00
|
|
|
if (r != OK) return(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((struct sigaction *) m_in.sig_nsa == (struct sigaction *) NULL)
|
|
|
|
return(OK);
|
|
|
|
|
|
|
|
/* Read in the sigaction structure. */
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
r = sys_datacopy(who_e, (vir_bytes) m_in.sig_nsa,
|
2005-05-03 17:35:52 +02:00
|
|
|
PM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec));
|
|
|
|
if (r != OK) return(r);
|
|
|
|
|
|
|
|
if (svec.sa_handler == SIG_IGN) {
|
|
|
|
sigaddset(&mp->mp_ignore, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_sigpending, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_catch, m_in.sig_nr);
|
2005-07-19 14:11:11 +02:00
|
|
|
sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
|
|
|
|
} else if (svec.sa_handler == SIG_DFL) {
|
|
|
|
sigdelset(&mp->mp_ignore, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_catch, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
|
|
|
|
} else if (svec.sa_handler == SIG_MESS) {
|
|
|
|
if (! (mp->mp_flags & PRIV_PROC)) return(EPERM);
|
|
|
|
sigdelset(&mp->mp_ignore, m_in.sig_nr);
|
|
|
|
sigaddset(&mp->mp_sig2mess, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_catch, m_in.sig_nr);
|
2005-05-03 17:35:52 +02:00
|
|
|
} else {
|
|
|
|
sigdelset(&mp->mp_ignore, m_in.sig_nr);
|
2005-07-19 14:11:11 +02:00
|
|
|
sigaddset(&mp->mp_catch, m_in.sig_nr);
|
|
|
|
sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|
|
|
|
mp->mp_sigact[m_in.sig_nr].sa_handler = svec.sa_handler;
|
|
|
|
sigdelset(&svec.sa_mask, SIGKILL);
|
2009-09-13 14:24:23 +02:00
|
|
|
sigdelset(&svec.sa_mask, SIGSTOP);
|
2005-05-03 17:35:52 +02:00
|
|
|
mp->mp_sigact[m_in.sig_nr].sa_mask = svec.sa_mask;
|
|
|
|
mp->mp_sigact[m_in.sig_nr].sa_flags = svec.sa_flags;
|
|
|
|
mp->mp_sigreturn = (vir_bytes) m_in.sig_ret;
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* do_sigpending *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_sigpending()
|
|
|
|
{
|
|
|
|
mp->mp_reply.reply_mask = (long) mp->mp_sigpending;
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* do_sigprocmask *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_sigprocmask()
|
|
|
|
{
|
|
|
|
/* Note that the library interface passes the actual mask in sigmask_set,
|
|
|
|
* not a pointer to the mask, in order to save a copy. Similarly,
|
|
|
|
* the old mask is placed in the return message which the library
|
|
|
|
* interface copies (if requested) to the user specified address.
|
|
|
|
*
|
|
|
|
* The library interface must set SIG_INQUIRE if the 'act' argument
|
|
|
|
* is NULL.
|
2005-12-12 14:11:22 +01:00
|
|
|
*
|
|
|
|
* KILL and STOP can't be masked.
|
2005-05-03 17:35:52 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mp->mp_reply.reply_mask = (long) mp->mp_sigmask;
|
|
|
|
|
|
|
|
switch (m_in.sig_how) {
|
|
|
|
case SIG_BLOCK:
|
|
|
|
sigdelset((sigset_t *)&m_in.sig_set, SIGKILL);
|
2005-12-12 14:11:22 +01:00
|
|
|
sigdelset((sigset_t *)&m_in.sig_set, SIGSTOP);
|
2005-05-03 17:35:52 +02:00
|
|
|
for (i = 1; i <= _NSIG; i++) {
|
|
|
|
if (sigismember((sigset_t *)&m_in.sig_set, i))
|
|
|
|
sigaddset(&mp->mp_sigmask, i);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIG_UNBLOCK:
|
|
|
|
for (i = 1; i <= _NSIG; i++) {
|
|
|
|
if (sigismember((sigset_t *)&m_in.sig_set, i))
|
|
|
|
sigdelset(&mp->mp_sigmask, i);
|
|
|
|
}
|
|
|
|
check_pending(mp);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIG_SETMASK:
|
|
|
|
sigdelset((sigset_t *) &m_in.sig_set, SIGKILL);
|
2005-12-12 14:11:22 +01:00
|
|
|
sigdelset((sigset_t *) &m_in.sig_set, SIGSTOP);
|
2005-05-03 17:35:52 +02:00
|
|
|
mp->mp_sigmask = (sigset_t) m_in.sig_set;
|
|
|
|
check_pending(mp);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIG_INQUIRE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return(EINVAL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* do_sigsuspend *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_sigsuspend()
|
|
|
|
{
|
|
|
|
mp->mp_sigmask2 = mp->mp_sigmask; /* save the old mask */
|
|
|
|
mp->mp_sigmask = (sigset_t) m_in.sig_set;
|
|
|
|
sigdelset(&mp->mp_sigmask, SIGKILL);
|
2009-09-13 14:24:23 +02:00
|
|
|
sigdelset(&mp->mp_sigmask, SIGSTOP);
|
2005-05-03 17:35:52 +02:00
|
|
|
mp->mp_flags |= SIGSUSPENDED;
|
|
|
|
check_pending(mp);
|
|
|
|
return(SUSPEND);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* do_sigreturn *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_sigreturn()
|
|
|
|
{
|
|
|
|
/* A user signal handler is done. Restore context and check for
|
|
|
|
* pending unblocked signals.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
mp->mp_sigmask = (sigset_t) m_in.sig_set;
|
|
|
|
sigdelset(&mp->mp_sigmask, SIGKILL);
|
2009-09-13 14:24:23 +02:00
|
|
|
sigdelset(&mp->mp_sigmask, SIGSTOP);
|
2005-05-03 17:35:52 +02:00
|
|
|
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context);
|
2005-05-03 17:35:52 +02:00
|
|
|
check_pending(mp);
|
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* do_kill *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_kill()
|
|
|
|
{
|
|
|
|
/* Perform the kill(pid, signo) system call. */
|
|
|
|
|
|
|
|
return check_sig(m_in.pid, m_in.sig_nr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-05-13 10:57:08 +02:00
|
|
|
* ksig_pending *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int ksig_pending()
|
|
|
|
{
|
2005-06-24 18:21:21 +02:00
|
|
|
/* Certain signals, such as segmentation violations originate in the kernel.
|
|
|
|
* When the kernel detects such signals, it notifies the PM to take further
|
|
|
|
* action. The PM requests the kernel to send messages with the process
|
|
|
|
* slot and bit map for all signaled processes. The File System, for example,
|
|
|
|
* uses this mechanism to signal writing on broken pipes (SIGPIPE).
|
2005-05-13 10:57:08 +02:00
|
|
|
*
|
|
|
|
* The kernel has notified the PM about pending signals. Request pending
|
2005-05-03 17:35:52 +02:00
|
|
|
* signals until all signals are handled. If there are no more signals,
|
|
|
|
* NONE is returned in the process number field.
|
|
|
|
*/
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
int proc_nr_e;
|
2005-05-03 17:35:52 +02:00
|
|
|
sigset_t sig_map;
|
|
|
|
|
|
|
|
while (TRUE) {
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
int r;
|
|
|
|
/* get an arbitrary pending signal */
|
|
|
|
if((r=sys_getksig(&proc_nr_e, &sig_map)) != OK)
|
|
|
|
panic(__FILE__,"sys_getksig failed", r);
|
|
|
|
if (NONE == proc_nr_e) { /* stop if no more pending signals */
|
2005-05-03 17:35:52 +02:00
|
|
|
break;
|
|
|
|
} else {
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
int proc_nr_p;
|
|
|
|
if(pm_isokendpt(proc_nr_e, &proc_nr_p) != OK)
|
|
|
|
panic(__FILE__,"sys_getksig strange process", proc_nr_e);
|
2006-03-10 17:10:05 +01:00
|
|
|
handle_ksig(proc_nr_e, sig_map); /* handle the received signal */
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
/* If the process still exists to the kernel after the signal
|
|
|
|
* has been handled ...
|
|
|
|
*/
|
2009-07-10 00:33:56 +02:00
|
|
|
if ((mproc[proc_nr_p].mp_flags & (IN_USE | EXITING)) == IN_USE)
|
2006-05-11 16:57:23 +02:00
|
|
|
{
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
if((r=sys_endksig(proc_nr_e)) != OK) /* ... tell kernel it's done */
|
|
|
|
panic(__FILE__,"sys_endksig failed", r);
|
2006-05-11 16:57:23 +02:00
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return(SUSPEND); /* prevents sending reply */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2006-03-10 17:10:05 +01:00
|
|
|
* handle_ksig *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
2006-03-10 17:10:05 +01:00
|
|
|
PRIVATE void handle_ksig(proc_nr_e, sig_map)
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
int proc_nr_e;
|
2005-05-03 17:35:52 +02:00
|
|
|
sigset_t sig_map;
|
|
|
|
{
|
|
|
|
register struct mproc *rmp;
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
int i, proc_nr;
|
2005-05-03 17:35:52 +02:00
|
|
|
pid_t proc_id, id;
|
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
if(pm_isokendpt(proc_nr_e, &proc_nr) != OK || proc_nr < 0) {
|
|
|
|
printf("PM: handle_ksig: %d?? not ok\n", proc_nr_e);
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
return;
|
2008-11-19 13:26:10 +01:00
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
rmp = &mproc[proc_nr];
|
2009-07-10 00:33:56 +02:00
|
|
|
if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
|
|
|
|
printf("PM: handle_ksig: %d?? exiting / not in use\n", proc_nr_e);
|
endpoint-aware conversion of servers.
'who', indicating caller number in pm and fs and some other servers, has
been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.).
In both PM and FS, isokendpt() convert endpoints to process slot
numbers, returning OK if it was a valid and consistent endpoint number.
okendpt() does the same but panic()s if it doesn't succeed. (In PM,
this is pm_isok..)
pm and fs keep their own records of process endpoints in their proc tables,
which are needed to make kernel calls about those processes.
message field names have changed.
fs drivers are endpoints.
fs now doesn't try to get out of driver deadlock, as the protocol isn't
supposed to let that happen any more. (A warning is printed if ELOCKED
is detected though.)
fproc[].fp_task (indicating which driver the process is suspended on)
became an int.
PM and FS now get endpoint numbers of initial boot processes from the
kernel. These happen to be the same as the old proc numbers, to let
user processes reach them with the old numbers, but FS and PM don't know
that. All new processes after INIT, even after the generation number
wraps around, get endpoint numbers with generation 1 and higher, so
the first instances of the boot processes are the only processes ever
to have endpoint numbers in the old proc number range.
More return code checks of sys_* functions have been added.
IS has become endpoint-aware. Ditched the 'text' and 'data' fields
in the kernel dump (which show locations, not sizes, so aren't terribly
useful) in favour of the endpoint number. Proc number is still visible.
Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got
the formatting changed.
PM reading segments using rw_seg() has changed - it uses other fields
in the message now instead of encoding the segment and process number and
fd in the fd field. For that it uses _read_pm() and _write_pm() which to
_taskcall()s directly in pm/misc.c.
PM now sys_exit()s itself on panic(), instead of sys_abort().
RS also talks in endpoints instead of process numbers.
2006-03-03 11:20:58 +01:00
|
|
|
return;
|
2009-07-06 00:48:18 +02:00
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
proc_id = rmp->mp_pid;
|
2005-07-14 17:16:12 +02:00
|
|
|
mp = &mproc[0]; /* pretend signals are from PM */
|
2005-05-03 17:35:52 +02:00
|
|
|
mp->mp_procgrp = rmp->mp_procgrp; /* get process group right */
|
|
|
|
|
|
|
|
/* Check each bit in turn to see if a signal is to be sent. Unlike
|
|
|
|
* kill(), the kernel may collect several unrelated signals for a
|
2005-05-13 10:57:08 +02:00
|
|
|
* process and pass them to PM in one blow. Thus loop on the bit
|
2009-08-15 23:37:26 +02:00
|
|
|
* map. For SIGVTALRM and SIGPROF, see if we need to restart a
|
|
|
|
* virtual timer. For SIGINT, SIGWINCH and SIGQUIT, use proc_id 0
|
|
|
|
* to indicate a broadcast to the recipient's process group. For
|
|
|
|
* SIGKILL, use proc_id -1 to indicate a systemwide broadcast.
|
2005-05-03 17:35:52 +02:00
|
|
|
*/
|
|
|
|
for (i = 1; i <= _NSIG; i++) {
|
|
|
|
if (!sigismember(&sig_map, i)) continue;
|
2008-11-19 13:26:10 +01:00
|
|
|
#if 0
|
|
|
|
printf("PM: sig %d for %d from kernel\n",
|
|
|
|
i, proc_nr_e);
|
|
|
|
#endif
|
2005-05-03 17:35:52 +02:00
|
|
|
switch (i) {
|
|
|
|
case SIGINT:
|
|
|
|
case SIGQUIT:
|
2005-10-03 14:03:57 +02:00
|
|
|
case SIGWINCH:
|
2005-05-03 17:35:52 +02:00
|
|
|
id = 0; break; /* broadcast to process group */
|
2009-08-15 23:37:26 +02:00
|
|
|
case SIGVTALRM:
|
|
|
|
case SIGPROF:
|
|
|
|
check_vtimer(proc_nr, i);
|
|
|
|
/* fall-through */
|
2005-05-03 17:35:52 +02:00
|
|
|
default:
|
|
|
|
id = proc_id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
check_sig(id, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* do_pause *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int do_pause()
|
|
|
|
{
|
|
|
|
/* Perform the pause() system call. */
|
|
|
|
|
|
|
|
mp->mp_flags |= PAUSED;
|
|
|
|
return(SUSPEND);
|
|
|
|
}
|
|
|
|
|
2009-09-21 16:48:19 +02:00
|
|
|
PRIVATE vm_notify_sig_wrapper(endpoint_t ep)
|
|
|
|
{
|
|
|
|
/* get IPC's endpoint,
|
|
|
|
* the reason that we directly get the endpoint
|
|
|
|
* instead of from DS server is that otherwise
|
|
|
|
* it will cause deadlock between PM, VM and DS.
|
|
|
|
*/
|
|
|
|
struct mproc *rmp;
|
|
|
|
endpoint_t ipc_ep = 0;
|
|
|
|
|
|
|
|
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
|
|
|
if (!(rmp->mp_flags & IN_USE))
|
|
|
|
continue;
|
|
|
|
if (!strcmp(rmp->mp_name, "ipc")) {
|
|
|
|
ipc_ep = rmp->mp_endpoint;
|
|
|
|
vm_notify_sig(ep, ipc_ep);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-03 17:35:52 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* sig_proc *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC void sig_proc(rmp, signo)
|
|
|
|
register struct mproc *rmp; /* pointer to the process to be signaled */
|
|
|
|
int signo; /* signal to send to process (1 to _NSIG) */
|
|
|
|
{
|
|
|
|
/* Send a signal to a process. Check to see if the signal is to be caught,
|
2005-07-19 14:11:11 +02:00
|
|
|
* ignored, tranformed into a message (for system processes) or blocked.
|
|
|
|
* - If the signal is to be transformed into a message, request the KERNEL to
|
|
|
|
* send the target process a system notification with the pending signal as an
|
|
|
|
* argument.
|
|
|
|
* - If the signal is to be caught, request the KERNEL to push a sigcontext
|
|
|
|
* structure and a sigframe structure onto the catcher's stack. Also, KERNEL
|
|
|
|
* will reset the program counter and stack pointer, so that when the process
|
|
|
|
* next runs, it will be executing the signal handler. When the signal handler
|
|
|
|
* returns, sigreturn(2) will be called. Then KERNEL will restore the signal
|
|
|
|
* context from the sigcontext structure.
|
2005-05-03 17:35:52 +02:00
|
|
|
* If there is insufficient stack space, kill the process.
|
|
|
|
*/
|
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
vir_bytes cur_sp;
|
2005-05-03 17:35:52 +02:00
|
|
|
int s;
|
|
|
|
int slot;
|
|
|
|
int sigflags;
|
|
|
|
|
|
|
|
slot = (int) (rmp - mproc);
|
2009-07-10 00:33:56 +02:00
|
|
|
if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
|
|
|
|
printf("PM: signal %d sent to exiting process %d\n", signo, slot);
|
2005-06-01 16:31:00 +02:00
|
|
|
panic(__FILE__,"", NO_NUM);
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|
2006-05-15 14:06:19 +02:00
|
|
|
if (rmp->mp_fs_call != PM_IDLE || rmp->mp_fs_call2 != PM_IDLE)
|
2006-05-11 16:57:23 +02:00
|
|
|
{
|
|
|
|
sigaddset(&rmp->mp_sigpending, signo);
|
|
|
|
rmp->mp_flags |= PM_SIG_PENDING;
|
|
|
|
/* keep the process from running */
|
|
|
|
sys_nice(rmp->mp_endpoint, PRIO_STOP);
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
if ((rmp->mp_flags & TRACED) && signo != SIGKILL) {
|
|
|
|
/* A traced process has special handling. */
|
2006-05-11 16:57:23 +02:00
|
|
|
unpause(slot, TRUE /*for_trace*/);
|
2005-05-03 17:35:52 +02:00
|
|
|
stop_proc(rmp, signo); /* a signal causes it to stop */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Some signals are ignored by default. */
|
2005-06-24 18:21:21 +02:00
|
|
|
if (sigismember(&rmp->mp_ignore, signo)) {
|
|
|
|
return;
|
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
if (sigismember(&rmp->mp_sigmask, signo)) {
|
|
|
|
/* Signal should be blocked. */
|
|
|
|
sigaddset(&rmp->mp_sigpending, signo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sigflags = rmp->mp_sigact[signo].sa_flags;
|
|
|
|
if (sigismember(&rmp->mp_catch, signo)) {
|
|
|
|
if (rmp->mp_flags & SIGSUSPENDED)
|
2006-05-11 16:57:23 +02:00
|
|
|
rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask2;
|
2005-05-03 17:35:52 +02:00
|
|
|
else
|
2006-05-11 16:57:23 +02:00
|
|
|
rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask;
|
|
|
|
rmp->mp_sigmsg.sm_signo = signo;
|
|
|
|
rmp->mp_sigmsg.sm_sighandler =
|
|
|
|
(vir_bytes) rmp->mp_sigact[signo].sa_handler;
|
|
|
|
rmp->mp_sigmsg.sm_sigreturn = rmp->mp_sigreturn;
|
2005-05-03 17:35:52 +02:00
|
|
|
rmp->mp_sigmask |= rmp->mp_sigact[signo].sa_mask;
|
2008-11-19 13:26:10 +01:00
|
|
|
|
2005-05-03 17:35:52 +02:00
|
|
|
if (sigflags & SA_NODEFER)
|
|
|
|
sigdelset(&rmp->mp_sigmask, signo);
|
|
|
|
else
|
|
|
|
sigaddset(&rmp->mp_sigmask, signo);
|
|
|
|
|
|
|
|
if (sigflags & SA_RESETHAND) {
|
|
|
|
sigdelset(&rmp->mp_catch, signo);
|
|
|
|
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
|
|
|
|
}
|
2006-05-11 16:57:23 +02:00
|
|
|
sigdelset(&rmp->mp_sigpending, signo);
|
2005-05-03 17:35:52 +02:00
|
|
|
|
2008-11-19 13:26:10 +01:00
|
|
|
/* Stop process from running before we fiddle with its stack. */
|
|
|
|
sys_nice(rmp->mp_endpoint, PRIO_STOP);
|
|
|
|
if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK)
|
|
|
|
goto doterminate;
|
|
|
|
|
|
|
|
rmp->mp_sigmsg.sm_stkptr = cur_sp;
|
|
|
|
|
2006-05-11 16:57:23 +02:00
|
|
|
/* Check to see if process is hanging on a PAUSE, WAIT or SIGSUSPEND
|
|
|
|
* call.
|
|
|
|
*/
|
|
|
|
if (rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED)) {
|
|
|
|
rmp->mp_flags &= ~(PAUSED | WAITING | SIGSUSPENDED);
|
|
|
|
setreply(slot, EINTR);
|
2005-06-24 18:21:21 +02:00
|
|
|
|
2006-05-11 16:57:23 +02:00
|
|
|
/* Ask the kernel to deliver the signal */
|
|
|
|
s= sys_sigsend(rmp->mp_endpoint, &rmp->mp_sigmsg);
|
|
|
|
if (s != OK)
|
|
|
|
panic(__FILE__, "sys_sigsend failed", s);
|
|
|
|
|
|
|
|
/* Done */
|
2005-06-24 18:21:21 +02:00
|
|
|
return;
|
|
|
|
}
|
2006-05-11 16:57:23 +02:00
|
|
|
|
|
|
|
/* Ask FS to unpause the process. Deliver the signal when FS is
|
|
|
|
* ready.
|
|
|
|
*/
|
|
|
|
unpause(slot, FALSE /*!for_trace*/);
|
2009-09-21 16:48:19 +02:00
|
|
|
vm_notify_sig_wrapper(rmp->mp_endpoint);
|
2006-05-11 16:57:23 +02:00
|
|
|
return;
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|
2005-07-19 14:11:11 +02:00
|
|
|
else if (sigismember(&rmp->mp_sig2mess, signo)) {
|
2006-03-10 17:10:05 +01:00
|
|
|
|
|
|
|
/* Mark event pending in process slot and send notification. */
|
|
|
|
sigaddset(&rmp->mp_sigpending, signo);
|
|
|
|
notify(rmp->mp_endpoint);
|
2005-07-19 14:11:11 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-05-03 17:35:52 +02:00
|
|
|
doterminate:
|
|
|
|
/* Signal should not or cannot be caught. Take default action. */
|
2008-11-19 13:26:10 +01:00
|
|
|
if (sigismember(&ign_sset, signo)) {
|
|
|
|
return;
|
|
|
|
}
|
2005-05-03 17:35:52 +02:00
|
|
|
|
2009-07-11 15:22:56 +02:00
|
|
|
/* Terminate process */
|
2005-05-03 17:35:52 +02:00
|
|
|
rmp->mp_sigstatus = (char) signo;
|
2006-03-10 18:35:55 +01:00
|
|
|
if (sigismember(&core_sset, signo) && slot != FS_PROC_NR) {
|
2009-07-08 19:16:53 +02:00
|
|
|
printf("PM: coredump signal %d for %d / %s\n", signo, rmp->mp_pid,
|
|
|
|
rmp->mp_name);
|
2009-07-11 15:22:56 +02:00
|
|
|
exit_proc(rmp, 0, TRUE /*dump_core*/);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
exit_proc(rmp, 0, FALSE /*dump_core*/);
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* check_sig *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int check_sig(proc_id, signo)
|
|
|
|
pid_t proc_id; /* pid of proc to sig, or 0 or -1, or -pgrp */
|
|
|
|
int signo; /* signal to send to process (0 to _NSIG) */
|
|
|
|
{
|
|
|
|
/* Check to see if it is possible to send a signal. The signal may have to be
|
|
|
|
* sent to a group of processes. This routine is invoked by the KILL system
|
|
|
|
* call, and also when the kernel catches a DEL or other signal.
|
|
|
|
*/
|
|
|
|
|
|
|
|
register struct mproc *rmp;
|
|
|
|
int count; /* count # of signals sent */
|
|
|
|
int error_code;
|
|
|
|
|
|
|
|
if (signo < 0 || signo > _NSIG) return(EINVAL);
|
|
|
|
|
|
|
|
/* Return EINVAL for attempts to send SIGKILL to INIT alone. */
|
|
|
|
if (proc_id == INIT_PID && signo == SIGKILL) return(EINVAL);
|
|
|
|
|
2006-03-10 17:10:05 +01:00
|
|
|
/* Search the proc table for processes to signal.
|
2009-07-10 00:33:56 +02:00
|
|
|
* (See forkexit.c about pid magic.)
|
2005-05-03 17:35:52 +02:00
|
|
|
*/
|
|
|
|
count = 0;
|
|
|
|
error_code = ESRCH;
|
2005-05-13 10:57:08 +02:00
|
|
|
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
2005-05-03 17:35:52 +02:00
|
|
|
if (!(rmp->mp_flags & IN_USE)) continue;
|
|
|
|
|
|
|
|
/* Check for selection. */
|
|
|
|
if (proc_id > 0 && proc_id != rmp->mp_pid) continue;
|
|
|
|
if (proc_id == 0 && mp->mp_procgrp != rmp->mp_procgrp) continue;
|
|
|
|
if (proc_id == -1 && rmp->mp_pid <= INIT_PID) continue;
|
|
|
|
if (proc_id < -1 && rmp->mp_procgrp != -proc_id) continue;
|
|
|
|
|
2006-03-10 17:10:05 +01:00
|
|
|
/* Do not kill servers and drivers when broadcasting SIGKILL. */
|
|
|
|
if (proc_id == -1 && signo == SIGKILL &&
|
|
|
|
(rmp->mp_flags & PRIV_PROC)) continue;
|
|
|
|
|
2005-05-03 17:35:52 +02:00
|
|
|
/* Check for permission. */
|
|
|
|
if (mp->mp_effuid != SUPER_USER
|
|
|
|
&& mp->mp_realuid != rmp->mp_realuid
|
|
|
|
&& mp->mp_effuid != rmp->mp_realuid
|
|
|
|
&& mp->mp_realuid != rmp->mp_effuid
|
|
|
|
&& mp->mp_effuid != rmp->mp_effuid) {
|
|
|
|
error_code = EPERM;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
2009-07-10 00:33:56 +02:00
|
|
|
if (signo == 0 || (rmp->mp_flags & EXITING)) continue;
|
2005-05-03 17:35:52 +02:00
|
|
|
|
|
|
|
/* 'sig_proc' will handle the disposition of the signal. The
|
|
|
|
* signal may be caught, blocked, ignored, or cause process
|
|
|
|
* termination, possibly with core dump.
|
|
|
|
*/
|
|
|
|
sig_proc(rmp, signo);
|
|
|
|
|
|
|
|
if (proc_id > 0) break; /* only one process being signaled */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the calling process has killed itself, don't reply. */
|
2009-07-10 00:33:56 +02:00
|
|
|
if ((mp->mp_flags & (IN_USE | EXITING)) != IN_USE) return(SUSPEND);
|
2005-05-03 17:35:52 +02:00
|
|
|
return(count > 0 ? OK : error_code);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2005-09-11 18:45:46 +02:00
|
|
|
* check_pending *
|
2005-05-03 17:35:52 +02:00
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC void check_pending(rmp)
|
|
|
|
register struct mproc *rmp;
|
|
|
|
{
|
|
|
|
/* Check to see if any pending signals have been unblocked. The
|
|
|
|
* first such signal found is delivered.
|
|
|
|
*
|
|
|
|
* If multiple pending unmasked signals are found, they will be
|
|
|
|
* delivered sequentially.
|
|
|
|
*
|
|
|
|
* There are several places in this file where the signal mask is
|
|
|
|
* changed. At each such place, check_pending() should be called to
|
|
|
|
* check for newly unblocked signals.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 1; i <= _NSIG; i++) {
|
|
|
|
if (sigismember(&rmp->mp_sigpending, i) &&
|
|
|
|
!sigismember(&rmp->mp_sigmask, i)) {
|
|
|
|
sigdelset(&rmp->mp_sigpending, i);
|
|
|
|
sig_proc(rmp, i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* unpause *
|
|
|
|
*===========================================================================*/
|
2006-05-11 16:57:23 +02:00
|
|
|
PRIVATE void unpause(pro, for_trace)
|
2005-05-03 17:35:52 +02:00
|
|
|
int pro; /* which process number */
|
2006-05-11 16:57:23 +02:00
|
|
|
int for_trace; /* for tracing */
|
2005-05-03 17:35:52 +02:00
|
|
|
{
|
|
|
|
/* A signal is to be sent to a process. If that process is hanging on a
|
|
|
|
* system call, the system call must be terminated with EINTR. Possible
|
|
|
|
* calls are PAUSE, WAIT, READ and WRITE, the latter two for pipes and ttys.
|
2005-05-13 10:57:08 +02:00
|
|
|
* First check if the process is hanging on an PM call. If not, tell FS,
|
2005-05-03 17:35:52 +02:00
|
|
|
* so it can check for READs and WRITEs from pipes, ttys and the like.
|
|
|
|
*/
|
|
|
|
register struct mproc *rmp;
|
2006-05-11 16:57:23 +02:00
|
|
|
int r;
|
2005-05-03 17:35:52 +02:00
|
|
|
|
|
|
|
rmp = &mproc[pro];
|
|
|
|
|
|
|
|
/* Check to see if process is hanging on a PAUSE, WAIT or SIGSUSPEND call. */
|
|
|
|
if (rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED)) {
|
|
|
|
rmp->mp_flags &= ~(PAUSED | WAITING | SIGSUSPENDED);
|
|
|
|
setreply(pro, EINTR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-05-13 10:57:08 +02:00
|
|
|
/* Process is not hanging on an PM call. Ask FS to take a look. */
|
2006-05-15 14:06:19 +02:00
|
|
|
if (for_trace)
|
|
|
|
{
|
|
|
|
if (rmp->mp_fs_call != PM_IDLE)
|
|
|
|
panic( __FILE__, "unpause: not idle", rmp->mp_fs_call);
|
|
|
|
rmp->mp_fs_call= PM_UNPAUSE_TR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (rmp->mp_fs_call2 != PM_IDLE)
|
|
|
|
panic( __FILE__, "unpause: not idle", rmp->mp_fs_call2);
|
|
|
|
rmp->mp_fs_call2= PM_UNPAUSE;
|
|
|
|
}
|
2006-05-11 16:57:23 +02:00
|
|
|
r= notify(FS_PROC_NR);
|
|
|
|
if (r != OK) panic("pm", "unpause: unable to notify FS", r);
|
2005-05-03 17:35:52 +02:00
|
|
|
}
|