minix/kernel/system/proctl.c
Jorrit Herder 0e2a7a9730 Kernel cleanup.
Reduced kernel size by 512KB by moving private buffer into cstart() function.
Replaced assertions with erroneous return values. Removed assertions relating
to isuserp(rp), since all processes should become user processes; system
processes are now treated similar to other processes.
2005-06-07 12:34:25 +00:00

223 lines
6.8 KiB
C

/* The system call implemented in this file:
* m_type: SYS_FORK
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (child's process table slot)
* m1_i2: PR_PPROC_NR (parent, process that forked)
* m1_i3: PR_PID (child pid received from PM)
*/
#include "../kernel.h"
#include "../system.h"
#include "../sendmask.h"
#include <signal.h>
#if (CHIP == INTEL)
#include "../protect.h"
#endif
#include "../debug.h"
/*===========================================================================*
* do_fork *
*===========================================================================*/
PUBLIC int do_fork(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_fork(). PR_PPROC_NR has forked. The child is PR_PROC_NR. */
#if (CHIP == INTEL)
reg_t old_ldt_sel;
#endif
register struct proc *rpc;
struct proc *rpp;
rpp = proc_addr(m_ptr->PR_PPROC_NR);
rpc = proc_addr(m_ptr->PR_PROC_NR);
if (! isemptyp(rpc)) return(EINVAL);
/* Copy parent 'proc' struct to child. */
#if (CHIP == INTEL)
old_ldt_sel = rpc->p_ldt_sel; /* stop this being obliterated by copy */
#endif
*rpc = *rpp; /* copy 'proc' struct */
#if (CHIP == INTEL)
rpc->p_ldt_sel = old_ldt_sel;
#endif
rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */
rpc->p_ntf_q = NULL; /* remove pending notifications */
rpc->p_flags |= NO_MAP; /* inhibit process from running */
rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
/* Only 1 in group should have PENDING, child does not inherit trace status*/
sigemptyset(&rpc->p_pending);
rpc->p_pendcount = 0;
rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
rpc->p_user_time = 0; /* set all the accounting times to 0 */
rpc->p_sys_time = 0;
return(OK);
}
/* The system call implemented in this file:
* m_type: SYS_NEWMAP
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (install new map for this process)
* m1_p1: PR_MEM_PTR (pointer to memory map)
*/
/*===========================================================================*
* do_newmap *
*===========================================================================*/
PUBLIC int do_newmap(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_newmap(). Fetch the memory map from PM. */
register struct proc *rp;
phys_bytes src_phys;
int caller; /* whose space has the new map (usually PM) */
int k; /* process whose map is to be loaded */
int old_flags; /* value of flags before modification */
struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
/* Extract message parameters and copy new memory map from PM. */
caller = m_ptr->m_source;
k = m_ptr->PR_PROC_NR;
map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
if (!isokprocn(k)) return(EINVAL);
rp = proc_addr(k); /* ptr to entry of user getting new map */
/* Copy the map from PM. */
src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr,
sizeof(rp->p_memmap));
if (src_phys == 0) return(EFAULT);
phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
#if (CHIP != M68000)
alloc_segments(rp);
#else
pmmu_init_proc(rp);
#endif
old_flags = rp->p_flags; /* save the previous value of the flags */
rp->p_flags &= ~NO_MAP;
if (old_flags != 0 && rp->p_flags == 0) lock_ready(rp);
return(OK);
}
/* The system call implemented in this file:
* m_type: SYS_EXEC
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (process that did exec call)
* m1_i3: PR_TRACING (flag to indicate tracing is on/ off)
* m1_p1: PR_STACK_PTR (new stack pointer)
* m1_p2: PR_NAME_PTR (pointer to program name)
* m1_p3: PR_IP_PTR (new instruction pointer)
*/
/*===========================================================================*
* do_exec *
*===========================================================================*/
PUBLIC int do_exec(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */
register struct proc *rp;
reg_t sp; /* new sp */
phys_bytes phys_name;
char *np;
rp = proc_addr(m_ptr->PR_PROC_NR);
if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP);
sp = (reg_t) m_ptr->PR_STACK_PTR;
rp->p_reg.sp = sp; /* set the stack pointer */
#if (CHIP == M68000)
rp->p_splow = sp; /* set the stack pointer low water */
#ifdef FPP
/* Initialize fpp for this process */
fpp_new_state(rp);
#endif
#endif
#if (CHIP == INTEL) /* wipe extra LDT entries */
kmemset(&rp->p_ldt[EXTRA_LDT_INDEX], 0,
(LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0]));
#endif
rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */
rp->p_flags &= ~RECEIVING; /* PM does not reply to EXEC call */
if (rp->p_flags == 0) lock_ready(rp);
/* Save command name for debugging, ps(1) output, etc. */
phys_name = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->PR_NAME_PTR,
(vir_bytes) P_NAME_LEN - 1);
if (phys_name != 0) {
phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1);
for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
*np = 0; /* mark end */
} else {
kstrncpy(rp->p_name, "<unset>", P_NAME_LEN);
}
return(OK);
}
/* The system call implemented in this file:
* m_type: SYS_XIT
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (slot number of exiting process)
* m1_i2: PR_PPROC_NR (slot number of parent process)
*/
/*===========================================================================*
* do_xit *
*===========================================================================*/
PUBLIC int do_xit(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_exit. A user process has exited (the PM sent the request).
*/
register struct proc *rp, *rc;
struct proc *np, *xp;
int exit_proc_nr;
/* Get a pointer to the process that exited. */
exit_proc_nr = m_ptr->PR_PROC_NR;
if (exit_proc_nr == SELF) exit_proc_nr = m_ptr->m_source;
if (! isokprocn(exit_proc_nr)) return(EINVAL);
rc = proc_addr(exit_proc_nr);
#if DEAD_CODE
/* If this is a user process and the PM passed in a valid parent process,
* accumulate the child times at the parent.
*/
if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
rp = proc_addr(m_ptr->PR_PPROC_NR);
lock(15, "do_xit");
rp->child_utime += rc->user_time + rc->child_utime;
rp->child_stime += rc->sys_time + rc->child_stime;
unlock(15);
}
#endif
/* Now call the routine to clean up of the process table slot. This cancels
* outstanding timers, possibly removes the process from the message queues,
* and resets important process table fields.
*/
clear_proc(exit_proc_nr);
return(OK); /* tell PM that cleanup succeeded */
}