Allow a process to kill itself. Remove the endpoint of a process that kills
itself before reporting the singal to pm.
This commit is contained in:
parent
b351811f18
commit
c1da6e6e24
6 changed files with 100 additions and 56 deletions
|
@ -42,6 +42,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
/* Scheduling and message passing functions. The functions are available to
|
/* Scheduling and message passing functions. The functions are available to
|
||||||
* other parts of the kernel through lock_...(). The lock temporarily disables
|
* other parts of the kernel through lock_...(). The lock temporarily disables
|
||||||
|
@ -295,6 +296,8 @@ unsigned flags; /* system call flags */
|
||||||
dst_p = _ENDPOINT_P(dst_e);
|
dst_p = _ENDPOINT_P(dst_e);
|
||||||
dst_ptr = proc_addr(dst_p);
|
dst_ptr = proc_addr(dst_p);
|
||||||
|
|
||||||
|
if (dst_ptr->p_rts_flags & NO_ENDPOINT) return EDSTDIED;
|
||||||
|
|
||||||
/* Check if 'dst' is blocked waiting for this message. The destination's
|
/* Check if 'dst' is blocked waiting for this message. The destination's
|
||||||
* SENDING flag may be set when its SENDREC call blocked while sending.
|
* SENDING flag may be set when its SENDREC call blocked while sending.
|
||||||
*/
|
*/
|
||||||
|
@ -345,7 +348,12 @@ unsigned flags; /* system call flags */
|
||||||
int i, src_id, src_proc_nr, src_p;
|
int i, src_id, src_proc_nr, src_p;
|
||||||
|
|
||||||
if(src_e == ANY) src_p = ANY;
|
if(src_e == ANY) src_p = ANY;
|
||||||
else okendpt(src_e, &src_p);
|
else
|
||||||
|
{
|
||||||
|
okendpt(src_e, &src_p);
|
||||||
|
if (proc_addr(src_p)->p_rts_flags & NO_ENDPOINT) return ESRCDIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check to see if a message from desired source is already available.
|
/* Check to see if a message from desired source is already available.
|
||||||
* The caller's SENDING flag may be set if SENDREC couldn't send. If it is
|
* The caller's SENDING flag may be set if SENDREC couldn't send. If it is
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct proc {
|
||||||
#define P_STOP 0x40 /* set when process is being traced */
|
#define P_STOP 0x40 /* set when process is being traced */
|
||||||
#define NO_PRIV 0x80 /* keep forked system process from running */
|
#define NO_PRIV 0x80 /* keep forked system process from running */
|
||||||
#define NO_PRIORITY 0x100 /* process has been stopped */
|
#define NO_PRIORITY 0x100 /* process has been stopped */
|
||||||
|
#define NO_ENDPOINT 0x200 /* process cannot send or receive messages */
|
||||||
|
|
||||||
/* Misc flags */
|
/* Misc flags */
|
||||||
#define REPLY_PENDING 0x01 /* reply to IPC_REQUEST is pending */
|
#define REPLY_PENDING 0x01 /* reply to IPC_REQUEST is pending */
|
||||||
|
|
|
@ -59,6 +59,7 @@ _PROTOTYPE( phys_bytes umap_remote, (struct proc *rp, int seg,
|
||||||
vir_bytes vir_addr, vir_bytes bytes) );
|
vir_bytes vir_addr, vir_bytes bytes) );
|
||||||
_PROTOTYPE( phys_bytes umap_bios, (struct proc *rp, vir_bytes vir_addr,
|
_PROTOTYPE( phys_bytes umap_bios, (struct proc *rp, vir_bytes vir_addr,
|
||||||
vir_bytes bytes) );
|
vir_bytes bytes) );
|
||||||
|
_PROTOTYPE( void clear_endpoint, (struct proc *rc) );
|
||||||
|
|
||||||
#if (CHIP == INTEL)
|
#if (CHIP == INTEL)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
* umap_bios: map virtual address in BIOS_SEG to physical
|
* umap_bios: map virtual address in BIOS_SEG to physical
|
||||||
* virtual_copy: copy bytes from one virtual address to another
|
* virtual_copy: copy bytes from one virtual address to another
|
||||||
* get_randomness: accumulate randomness in a buffer
|
* get_randomness: accumulate randomness in a buffer
|
||||||
|
* clear_endpoint: remove a process' ability to send and receive messages
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
* Aug 04, 2005 check if system call is allowed (Jorrit N. Herder)
|
* Aug 04, 2005 check if system call is allowed (Jorrit N. Herder)
|
||||||
|
@ -471,3 +472,76 @@ vir_bytes bytes; /* # of bytes to copy */
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* clear_endpoint *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC void clear_endpoint(rc)
|
||||||
|
register struct proc *rc; /* slot of process to clean up */
|
||||||
|
{
|
||||||
|
register struct proc *rp; /* iterate over process table */
|
||||||
|
register struct proc **xpp; /* iterate over caller queue */
|
||||||
|
int i;
|
||||||
|
int sys_id;
|
||||||
|
|
||||||
|
if(isemptyp(rc)) panic("clear_proc: empty process", proc_nr(rc));
|
||||||
|
|
||||||
|
/* Make sure that the exiting process is no longer scheduled. */
|
||||||
|
if (rc->p_rts_flags == 0) lock_dequeue(rc);
|
||||||
|
rc->p_rts_flags |= NO_ENDPOINT;
|
||||||
|
|
||||||
|
/* If the process happens to be queued trying to send a
|
||||||
|
* message, then it must be removed from the message queues.
|
||||||
|
*/
|
||||||
|
if (rc->p_rts_flags & SENDING) {
|
||||||
|
int target_proc;
|
||||||
|
|
||||||
|
okendpt(rc->p_sendto_e, &target_proc);
|
||||||
|
xpp = &proc_addr(target_proc)->p_caller_q; /* destination's queue */
|
||||||
|
while (*xpp != NIL_PROC) { /* check entire queue */
|
||||||
|
if (*xpp == rc) { /* process is on the queue */
|
||||||
|
*xpp = (*xpp)->p_q_link; /* replace by next process */
|
||||||
|
#if DEBUG_ENABLE_IPC_WARNINGS
|
||||||
|
kprintf("Proc %d removed from queue at %d\n",
|
||||||
|
proc_nr(rc), rc->p_sendto_e);
|
||||||
|
#endif
|
||||||
|
break; /* can only be queued once */
|
||||||
|
}
|
||||||
|
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
|
||||||
|
}
|
||||||
|
rc->p_rts_flags &= ~SENDING;
|
||||||
|
}
|
||||||
|
rc->p_rts_flags &= ~RECEIVING;
|
||||||
|
|
||||||
|
/* Likewise, if another process was sending or receive a message to or from
|
||||||
|
* the exiting process, it must be alerted that process no longer is alive.
|
||||||
|
* Check all processes.
|
||||||
|
*/
|
||||||
|
for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
|
||||||
|
if(isemptyp(rp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Unset pending notification bits. */
|
||||||
|
unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
|
||||||
|
|
||||||
|
/* Check if process is receiving from exiting process. */
|
||||||
|
if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
|
||||||
|
rp->p_reg.retreg = ESRCDIED; /* report source died */
|
||||||
|
rp->p_rts_flags &= ~RECEIVING; /* no longer receiving */
|
||||||
|
#if DEBUG_ENABLE_IPC_WARNINGS
|
||||||
|
kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
|
||||||
|
#endif
|
||||||
|
if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
|
||||||
|
}
|
||||||
|
if ((rp->p_rts_flags & SENDING) && rp->p_sendto_e == rc->p_endpoint) {
|
||||||
|
rp->p_reg.retreg = EDSTDIED; /* report destination died */
|
||||||
|
rp->p_rts_flags &= ~SENDING; /* no longer sending */
|
||||||
|
#if DEBUG_ENABLE_IPC_WARNINGS
|
||||||
|
kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
|
||||||
|
#endif
|
||||||
|
if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ register struct proc *rc; /* slot of process to clean up */
|
||||||
/* Don't clear if already cleared. */
|
/* Don't clear if already cleared. */
|
||||||
if(isemptyp(rc)) return;
|
if(isemptyp(rc)) return;
|
||||||
|
|
||||||
|
/* Remove the process' ability to send and receive messages */
|
||||||
|
clear_endpoint(rc);
|
||||||
|
|
||||||
/* Turn off any alarm timers at the clock. */
|
/* Turn off any alarm timers at the clock. */
|
||||||
reset_timer(&priv(rc)->s_alarm_timer);
|
reset_timer(&priv(rc)->s_alarm_timer);
|
||||||
|
|
||||||
|
@ -81,57 +84,6 @@ register struct proc *rc; /* slot of process to clean up */
|
||||||
rc->p_rts_flags = SLOT_FREE;
|
rc->p_rts_flags = SLOT_FREE;
|
||||||
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
|
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
|
||||||
|
|
||||||
/* If the process being terminated happens to be queued trying to send a
|
|
||||||
* message (e.g., the process was killed by a signal, rather than it doing
|
|
||||||
* a normal exit), then it must be removed from the message queues.
|
|
||||||
*/
|
|
||||||
if (saved_rts_flags & SENDING) {
|
|
||||||
int target_proc;
|
|
||||||
okendpt(rc->p_sendto_e, &target_proc);
|
|
||||||
xpp = &proc_addr(target_proc)->p_caller_q; /* destination's queue */
|
|
||||||
while (*xpp != NIL_PROC) { /* check entire queue */
|
|
||||||
if (*xpp == rc) { /* process is on the queue */
|
|
||||||
*xpp = (*xpp)->p_q_link; /* replace by next process */
|
|
||||||
#if DEBUG_ENABLE_IPC_WARNINGS
|
|
||||||
kprintf("Proc %d removed from queue at %d\n",
|
|
||||||
proc_nr(rc), rc->p_sendto_e);
|
|
||||||
#endif
|
|
||||||
break; /* can only be queued once */
|
|
||||||
}
|
|
||||||
xpp = &(*xpp)->p_q_link; /* proceed to next queued */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Likewise, if another process was sending or receive a message to or from
|
|
||||||
* the exiting process, it must be alerted that process no longer is alive.
|
|
||||||
* Check all processes.
|
|
||||||
*/
|
|
||||||
for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
|
|
||||||
if(isemptyp(rp))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Unset pending notification bits. */
|
|
||||||
unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
|
|
||||||
|
|
||||||
/* Check if process is receiving from exiting process. */
|
|
||||||
if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
|
|
||||||
rp->p_reg.retreg = ESRCDIED; /* report source died */
|
|
||||||
rp->p_rts_flags &= ~RECEIVING; /* no longer receiving */
|
|
||||||
#if DEBUG_ENABLE_IPC_WARNINGS
|
|
||||||
kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
|
|
||||||
#endif
|
|
||||||
if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
|
|
||||||
}
|
|
||||||
if ((rp->p_rts_flags & SENDING) && rp->p_sendto_e == rc->p_endpoint) {
|
|
||||||
rp->p_reg.retreg = EDSTDIED; /* report destination died */
|
|
||||||
rp->p_rts_flags &= ~SENDING; /* no longer sending */
|
|
||||||
#if DEBUG_ENABLE_IPC_WARNINGS
|
|
||||||
kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
|
|
||||||
#endif
|
|
||||||
if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean up virtual memory */
|
/* Clean up virtual memory */
|
||||||
if (rc->p_misc_flags & MF_VM)
|
if (rc->p_misc_flags & MF_VM)
|
||||||
vm_map_default(rc);
|
vm_map_default(rc);
|
||||||
|
|
|
@ -26,15 +26,23 @@ message *m_ptr; /* pointer to request message */
|
||||||
* are usually blocked on a RECEIVE), they can request the PM to transform
|
* are usually blocked on a RECEIVE), they can request the PM to transform
|
||||||
* signals into messages. This is done by the PM with a call to sys_kill().
|
* signals into messages. This is done by the PM with a call to sys_kill().
|
||||||
*/
|
*/
|
||||||
proc_nr_t proc_nr;
|
proc_nr_t proc_nr, proc_nr_e;
|
||||||
int sig_nr = m_ptr->SIG_NUMBER;
|
int sig_nr = m_ptr->SIG_NUMBER;
|
||||||
|
|
||||||
if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL);
|
proc_nr_e= m_ptr->SIG_ENDPT;
|
||||||
|
|
||||||
|
if (proc_nr_e == SELF)
|
||||||
|
proc_nr_e= m_ptr->m_source;
|
||||||
|
|
||||||
|
if (!isokendpt(proc_nr_e, &proc_nr)) return(EINVAL);
|
||||||
|
|
||||||
if (sig_nr > _NSIG) return(EINVAL);
|
if (sig_nr > _NSIG) return(EINVAL);
|
||||||
if (iskerneln(proc_nr)) return(EPERM);
|
if (iskerneln(proc_nr)) return(EPERM);
|
||||||
|
|
||||||
/* Set pending signal to be processed by the PM. */
|
/* Set pending signal to be processed by the PM. */
|
||||||
cause_sig(proc_nr, sig_nr);
|
cause_sig(proc_nr, sig_nr);
|
||||||
|
if (sig_nr == SIGKILL)
|
||||||
|
clear_endpoint(proc_addr(proc_nr));
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue