Index: trunk/minix/servers/pm/.depend
===================================================================
--- trunk/minix/servers/pm/.depend	(revision 11)
+++ 	(revision )
@@ -1,421 +1,0 @@
-
-alloc.o:	../../kernel/config.h
-alloc.o:	../../kernel/const.h
-alloc.o:	../../kernel/type.h
-alloc.o:	/usr/include/ansi.h
-alloc.o:	/usr/include/errno.h
-alloc.o:	/usr/include/fcntl.h
-alloc.o:	/usr/include/ibm/bios.h
-alloc.o:	/usr/include/ibm/cpu.h
-alloc.o:	/usr/include/ibm/interrupt.h
-alloc.o:	/usr/include/ibm/ports.h
-alloc.o:	/usr/include/limits.h
-alloc.o:	/usr/include/minix/callnr.h
-alloc.o:	/usr/include/minix/com.h
-alloc.o:	/usr/include/minix/config.h
-alloc.o:	/usr/include/minix/const.h
-alloc.o:	/usr/include/minix/devio.h
-alloc.o:	/usr/include/minix/ipc.h
-alloc.o:	/usr/include/minix/sys_config.h
-alloc.o:	/usr/include/minix/syslib.h
-alloc.o:	/usr/include/minix/sysutil.h
-alloc.o:	/usr/include/minix/type.h
-alloc.o:	/usr/include/signal.h
-alloc.o:	/usr/include/stdlib.h
-alloc.o:	/usr/include/string.h
-alloc.o:	/usr/include/sys/dir.h
-alloc.o:	/usr/include/sys/types.h
-alloc.o:	/usr/include/timers.h
-alloc.o:	/usr/include/unistd.h
-alloc.o:	alloc.c
-alloc.o:	const.h
-alloc.o:	glo.h
-alloc.o:	mproc.h
-alloc.o:	pm.h
-alloc.o:	proto.h
-alloc.o:	type.h
-
-break.o:	/usr/include/ansi.h
-break.o:	/usr/include/errno.h
-break.o:	/usr/include/fcntl.h
-break.o:	/usr/include/limits.h
-break.o:	/usr/include/minix/config.h
-break.o:	/usr/include/minix/const.h
-break.o:	/usr/include/minix/devio.h
-break.o:	/usr/include/minix/ipc.h
-break.o:	/usr/include/minix/sys_config.h
-break.o:	/usr/include/minix/syslib.h
-break.o:	/usr/include/minix/sysutil.h
-break.o:	/usr/include/minix/type.h
-break.o:	/usr/include/signal.h
-break.o:	/usr/include/sys/dir.h
-break.o:	/usr/include/sys/types.h
-break.o:	/usr/include/timers.h
-break.o:	/usr/include/unistd.h
-break.o:	break.c
-break.o:	const.h
-break.o:	glo.h
-break.o:	mproc.h
-break.o:	param.h
-break.o:	pm.h
-break.o:	proto.h
-break.o:	type.h
-
-exec.o:	/usr/include/a.out.h
-exec.o:	/usr/include/ansi.h
-exec.o:	/usr/include/errno.h
-exec.o:	/usr/include/fcntl.h
-exec.o:	/usr/include/limits.h
-exec.o:	/usr/include/minix/callnr.h
-exec.o:	/usr/include/minix/com.h
-exec.o:	/usr/include/minix/config.h
-exec.o:	/usr/include/minix/const.h
-exec.o:	/usr/include/minix/devio.h
-exec.o:	/usr/include/minix/endpoint.h
-exec.o:	/usr/include/minix/ipc.h
-exec.o:	/usr/include/minix/sys_config.h
-exec.o:	/usr/include/minix/syslib.h
-exec.o:	/usr/include/minix/sysutil.h
-exec.o:	/usr/include/minix/type.h
-exec.o:	/usr/include/signal.h
-exec.o:	/usr/include/string.h
-exec.o:	/usr/include/sys/dir.h
-exec.o:	/usr/include/sys/stat.h
-exec.o:	/usr/include/sys/types.h
-exec.o:	/usr/include/timers.h
-exec.o:	/usr/include/unistd.h
-exec.o:	const.h
-exec.o:	exec.c
-exec.o:	glo.h
-exec.o:	mproc.h
-exec.o:	param.h
-exec.o:	pm.h
-exec.o:	proto.h
-exec.o:	type.h
-
-forkexit.o:	/usr/include/ansi.h
-forkexit.o:	/usr/include/errno.h
-forkexit.o:	/usr/include/fcntl.h
-forkexit.o:	/usr/include/limits.h
-forkexit.o:	/usr/include/minix/callnr.h
-forkexit.o:	/usr/include/minix/com.h
-forkexit.o:	/usr/include/minix/config.h
-forkexit.o:	/usr/include/minix/const.h
-forkexit.o:	/usr/include/minix/devio.h
-forkexit.o:	/usr/include/minix/ipc.h
-forkexit.o:	/usr/include/minix/sys_config.h
-forkexit.o:	/usr/include/minix/syslib.h
-forkexit.o:	/usr/include/minix/sysutil.h
-forkexit.o:	/usr/include/minix/type.h
-forkexit.o:	/usr/include/signal.h
-forkexit.o:	/usr/include/sys/dir.h
-forkexit.o:	/usr/include/sys/resource.h
-forkexit.o:	/usr/include/sys/types.h
-forkexit.o:	/usr/include/sys/wait.h
-forkexit.o:	/usr/include/timers.h
-forkexit.o:	/usr/include/unistd.h
-forkexit.o:	const.h
-forkexit.o:	forkexit.c
-forkexit.o:	glo.h
-forkexit.o:	mproc.h
-forkexit.o:	param.h
-forkexit.o:	pm.h
-forkexit.o:	proto.h
-forkexit.o:	type.h
-
-getset.o:	/usr/include/ansi.h
-getset.o:	/usr/include/errno.h
-getset.o:	/usr/include/fcntl.h
-getset.o:	/usr/include/limits.h
-getset.o:	/usr/include/minix/callnr.h
-getset.o:	/usr/include/minix/com.h
-getset.o:	/usr/include/minix/config.h
-getset.o:	/usr/include/minix/const.h
-getset.o:	/usr/include/minix/devio.h
-getset.o:	/usr/include/minix/endpoint.h
-getset.o:	/usr/include/minix/ipc.h
-getset.o:	/usr/include/minix/sys_config.h
-getset.o:	/usr/include/minix/syslib.h
-getset.o:	/usr/include/minix/sysutil.h
-getset.o:	/usr/include/minix/type.h
-getset.o:	/usr/include/signal.h
-getset.o:	/usr/include/sys/dir.h
-getset.o:	/usr/include/sys/types.h
-getset.o:	/usr/include/timers.h
-getset.o:	/usr/include/unistd.h
-getset.o:	const.h
-getset.o:	getset.c
-getset.o:	glo.h
-getset.o:	mproc.h
-getset.o:	param.h
-getset.o:	pm.h
-getset.o:	proto.h
-getset.o:	type.h
-
-main.o:	../../kernel/config.h
-main.o:	../../kernel/const.h
-main.o:	../../kernel/priv.h
-main.o:	../../kernel/proc.h
-main.o:	../../kernel/protect.h
-main.o:	../../kernel/type.h
-main.o:	/usr/include/ansi.h
-main.o:	/usr/include/errno.h
-main.o:	/usr/include/fcntl.h
-main.o:	/usr/include/ibm/bios.h
-main.o:	/usr/include/ibm/cpu.h
-main.o:	/usr/include/ibm/interrupt.h
-main.o:	/usr/include/ibm/ports.h
-main.o:	/usr/include/limits.h
-main.o:	/usr/include/minix/callnr.h
-main.o:	/usr/include/minix/com.h
-main.o:	/usr/include/minix/config.h
-main.o:	/usr/include/minix/const.h
-main.o:	/usr/include/minix/devio.h
-main.o:	/usr/include/minix/endpoint.h
-main.o:	/usr/include/minix/ipc.h
-main.o:	/usr/include/minix/keymap.h
-main.o:	/usr/include/minix/sys_config.h
-main.o:	/usr/include/minix/syslib.h
-main.o:	/usr/include/minix/sysutil.h
-main.o:	/usr/include/minix/type.h
-main.o:	/usr/include/signal.h
-main.o:	/usr/include/stdlib.h
-main.o:	/usr/include/string.h
-main.o:	/usr/include/sys/dir.h
-main.o:	/usr/include/sys/resource.h
-main.o:	/usr/include/sys/types.h
-main.o:	/usr/include/timers.h
-main.o:	/usr/include/unistd.h
-main.o:	const.h
-main.o:	glo.h
-main.o:	main.c
-main.o:	mproc.h
-main.o:	param.h
-main.o:	pm.h
-main.o:	proto.h
-main.o:	type.h
-
-misc.o:	../../kernel/config.h
-misc.o:	../../kernel/const.h
-misc.o:	../../kernel/priv.h
-misc.o:	../../kernel/proc.h
-misc.o:	../../kernel/protect.h
-misc.o:	../../kernel/type.h
-misc.o:	/usr/include/ansi.h
-misc.o:	/usr/include/errno.h
-misc.o:	/usr/include/fcntl.h
-misc.o:	/usr/include/ibm/bios.h
-misc.o:	/usr/include/ibm/cpu.h
-misc.o:	/usr/include/ibm/interrupt.h
-misc.o:	/usr/include/ibm/ports.h
-misc.o:	/usr/include/lib.h
-misc.o:	/usr/include/limits.h
-misc.o:	/usr/include/minix/callnr.h
-misc.o:	/usr/include/minix/com.h
-misc.o:	/usr/include/minix/config.h
-misc.o:	/usr/include/minix/const.h
-misc.o:	/usr/include/minix/devio.h
-misc.o:	/usr/include/minix/dmap.h
-misc.o:	/usr/include/minix/ioctl.h
-misc.o:	/usr/include/minix/ipc.h
-misc.o:	/usr/include/minix/sys_config.h
-misc.o:	/usr/include/minix/syslib.h
-misc.o:	/usr/include/minix/sysutil.h
-misc.o:	/usr/include/minix/type.h
-misc.o:	/usr/include/signal.h
-misc.o:	/usr/include/string.h
-misc.o:	/usr/include/sys/dir.h
-misc.o:	/usr/include/sys/resource.h
-misc.o:	/usr/include/sys/svrctl.h
-misc.o:	/usr/include/sys/types.h
-misc.o:	/usr/include/timers.h
-misc.o:	/usr/include/unistd.h
-misc.o:	const.h
-misc.o:	glo.h
-misc.o:	misc.c
-misc.o:	mproc.h
-misc.o:	param.h
-misc.o:	pm.h
-misc.o:	proto.h
-misc.o:	type.h
-
-signal.o:	/usr/include/ansi.h
-signal.o:	/usr/include/errno.h
-signal.o:	/usr/include/fcntl.h
-signal.o:	/usr/include/limits.h
-signal.o:	/usr/include/minix/callnr.h
-signal.o:	/usr/include/minix/com.h
-signal.o:	/usr/include/minix/config.h
-signal.o:	/usr/include/minix/const.h
-signal.o:	/usr/include/minix/devio.h
-signal.o:	/usr/include/minix/endpoint.h
-signal.o:	/usr/include/minix/ipc.h
-signal.o:	/usr/include/minix/sys_config.h
-signal.o:	/usr/include/minix/syslib.h
-signal.o:	/usr/include/minix/sysutil.h
-signal.o:	/usr/include/minix/type.h
-signal.o:	/usr/include/signal.h
-signal.o:	/usr/include/string.h
-signal.o:	/usr/include/sys/dir.h
-signal.o:	/usr/include/sys/ptrace.h
-signal.o:	/usr/include/sys/sigcontext.h
-signal.o:	/usr/include/sys/stat.h
-signal.o:	/usr/include/sys/types.h
-signal.o:	/usr/include/timers.h
-signal.o:	/usr/include/unistd.h
-signal.o:	const.h
-signal.o:	glo.h
-signal.o:	mproc.h
-signal.o:	param.h
-signal.o:	pm.h
-signal.o:	proto.h
-signal.o:	signal.c
-signal.o:	type.h
-
-table.o:	/usr/include/ansi.h
-table.o:	/usr/include/errno.h
-table.o:	/usr/include/fcntl.h
-table.o:	/usr/include/limits.h
-table.o:	/usr/include/minix/callnr.h
-table.o:	/usr/include/minix/config.h
-table.o:	/usr/include/minix/const.h
-table.o:	/usr/include/minix/devio.h
-table.o:	/usr/include/minix/ipc.h
-table.o:	/usr/include/minix/sys_config.h
-table.o:	/usr/include/minix/syslib.h
-table.o:	/usr/include/minix/sysutil.h
-table.o:	/usr/include/minix/type.h
-table.o:	/usr/include/signal.h
-table.o:	/usr/include/sys/dir.h
-table.o:	/usr/include/sys/types.h
-table.o:	/usr/include/timers.h
-table.o:	/usr/include/unistd.h
-table.o:	const.h
-table.o:	glo.h
-table.o:	mproc.h
-table.o:	param.h
-table.o:	pm.h
-table.o:	proto.h
-table.o:	table.c
-table.o:	type.h
-
-time.o:	/usr/include/ansi.h
-time.o:	/usr/include/errno.h
-time.o:	/usr/include/fcntl.h
-time.o:	/usr/include/limits.h
-time.o:	/usr/include/minix/callnr.h
-time.o:	/usr/include/minix/com.h
-time.o:	/usr/include/minix/config.h
-time.o:	/usr/include/minix/const.h
-time.o:	/usr/include/minix/devio.h
-time.o:	/usr/include/minix/ipc.h
-time.o:	/usr/include/minix/sys_config.h
-time.o:	/usr/include/minix/syslib.h
-time.o:	/usr/include/minix/sysutil.h
-time.o:	/usr/include/minix/type.h
-time.o:	/usr/include/signal.h
-time.o:	/usr/include/sys/dir.h
-time.o:	/usr/include/sys/types.h
-time.o:	/usr/include/timers.h
-time.o:	/usr/include/unistd.h
-time.o:	const.h
-time.o:	glo.h
-time.o:	mproc.h
-time.o:	param.h
-time.o:	pm.h
-time.o:	proto.h
-time.o:	time.c
-time.o:	type.h
-
-timers.o:	/usr/include/ansi.h
-timers.o:	/usr/include/errno.h
-timers.o:	/usr/include/fcntl.h
-timers.o:	/usr/include/limits.h
-timers.o:	/usr/include/minix/com.h
-timers.o:	/usr/include/minix/config.h
-timers.o:	/usr/include/minix/const.h
-timers.o:	/usr/include/minix/devio.h
-timers.o:	/usr/include/minix/ipc.h
-timers.o:	/usr/include/minix/sys_config.h
-timers.o:	/usr/include/minix/syslib.h
-timers.o:	/usr/include/minix/sysutil.h
-timers.o:	/usr/include/minix/type.h
-timers.o:	/usr/include/sys/dir.h
-timers.o:	/usr/include/sys/types.h
-timers.o:	/usr/include/timers.h
-timers.o:	/usr/include/unistd.h
-timers.o:	const.h
-timers.o:	glo.h
-timers.o:	pm.h
-timers.o:	proto.h
-timers.o:	timers.c
-timers.o:	type.h
-
-trace.o:	/usr/include/ansi.h
-trace.o:	/usr/include/errno.h
-trace.o:	/usr/include/fcntl.h
-trace.o:	/usr/include/limits.h
-trace.o:	/usr/include/minix/com.h
-trace.o:	/usr/include/minix/config.h
-trace.o:	/usr/include/minix/const.h
-trace.o:	/usr/include/minix/devio.h
-trace.o:	/usr/include/minix/ipc.h
-trace.o:	/usr/include/minix/sys_config.h
-trace.o:	/usr/include/minix/syslib.h
-trace.o:	/usr/include/minix/sysutil.h
-trace.o:	/usr/include/minix/type.h
-trace.o:	/usr/include/signal.h
-trace.o:	/usr/include/sys/dir.h
-trace.o:	/usr/include/sys/ptrace.h
-trace.o:	/usr/include/sys/types.h
-trace.o:	/usr/include/timers.h
-trace.o:	/usr/include/unistd.h
-trace.o:	const.h
-trace.o:	glo.h
-trace.o:	mproc.h
-trace.o:	param.h
-trace.o:	pm.h
-trace.o:	proto.h
-trace.o:	trace.c
-trace.o:	type.h
-
-utility.o:	../../kernel/config.h
-utility.o:	../../kernel/const.h
-utility.o:	../../kernel/priv.h
-utility.o:	../../kernel/proc.h
-utility.o:	../../kernel/protect.h
-utility.o:	../../kernel/type.h
-utility.o:	/usr/include/ansi.h
-utility.o:	/usr/include/errno.h
-utility.o:	/usr/include/fcntl.h
-utility.o:	/usr/include/ibm/bios.h
-utility.o:	/usr/include/ibm/cpu.h
-utility.o:	/usr/include/ibm/interrupt.h
-utility.o:	/usr/include/ibm/ports.h
-utility.o:	/usr/include/limits.h
-utility.o:	/usr/include/minix/callnr.h
-utility.o:	/usr/include/minix/com.h
-utility.o:	/usr/include/minix/config.h
-utility.o:	/usr/include/minix/const.h
-utility.o:	/usr/include/minix/devio.h
-utility.o:	/usr/include/minix/endpoint.h
-utility.o:	/usr/include/minix/ipc.h
-utility.o:	/usr/include/minix/sys_config.h
-utility.o:	/usr/include/minix/syslib.h
-utility.o:	/usr/include/minix/sysutil.h
-utility.o:	/usr/include/minix/type.h
-utility.o:	/usr/include/signal.h
-utility.o:	/usr/include/string.h
-utility.o:	/usr/include/sys/dir.h
-utility.o:	/usr/include/sys/stat.h
-utility.o:	/usr/include/sys/types.h
-utility.o:	/usr/include/timers.h
-utility.o:	/usr/include/unistd.h
-utility.o:	const.h
-utility.o:	glo.h
-utility.o:	mproc.h
-utility.o:	param.h
-utility.o:	pm.h
-utility.o:	proto.h
-utility.o:	type.h
-utility.o:	utility.c
Index: trunk/minix/servers/pm/Makefile
===================================================================
--- trunk/minix/servers/pm/Makefile	(revision 11)
+++ 	(revision )
@@ -1,39 +1,0 @@
-# Makefile for Process Manager (PM)
-SERVER = pm
-
-# directories
-u = /usr
-i = $u/include
-s = $i/sys
-h = $i/minix
-k = $u/src/kernel
-
-# programs, flags, etc.
-CC =	exec cc
-CFLAGS = -I$i
-LDFLAGS = -i
-
-OBJ = 	main.o forkexit.o break.o exec.o time.o timers.o \
-	signal.o alloc.o utility.o table.o trace.o getset.o misc.o
-
-# build local binary
-all build:	$(SERVER)
-$(SERVER):	$(OBJ)
-	$(CC) -o $@ $(LDFLAGS) $(OBJ) -lsys -lsysutil -ltimers
-	install -S 256w $@
-
-# install with other servers
-install:	/usr/sbin/$(SERVER)
-/usr/sbin/$(SERVER):	$(SERVER)
-	install -o root -cs $? $@
-
-# clean up local files
-clean:
-	rm -f $(SERVER) *.o *.bak 
-
-depend: 
-	/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
-
-# Include generated dependencies.
-include .depend
-
Index: trunk/minix/servers/pm/alloc.c
===================================================================
--- trunk/minix/servers/pm/alloc.c	(revision 11)
+++ 	(revision )
@@ -1,445 +1,0 @@
-/* This file is concerned with allocating and freeing arbitrary-size blocks of
- * physical memory on behalf of the FORK and EXEC system calls.  The key data
- * structure used is the hole table, which maintains a list of holes in memory.
- * It is kept sorted in order of increasing memory address. The addresses
- * it contains refers to physical memory, starting at absolute address 0
- * (i.e., they are not relative to the start of PM).  During system
- * initialization, that part of memory containing the interrupt vectors,
- * kernel, and PM are "allocated" to mark them as not available and to
- * remove them from the hole list.
- *
- * The entry points into this file are:
- *   alloc_mem:	allocate a given sized chunk of memory
- *   free_mem:	release a previously allocated chunk of memory
- *   mem_init:	initialize the tables when PM start up
- *   max_hole:	returns the largest hole currently available
- *   mem_holes_copy: for outsiders who want a copy of the hole-list
- */
-
-#include "pm.h"
-#include <minix/com.h>
-#include <minix/callnr.h>
-#include <minix/type.h>
-#include <minix/config.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include "mproc.h"
-#include "../../kernel/const.h"
-#include "../../kernel/config.h"
-#include "../../kernel/type.h"
-
-#define NIL_HOLE (struct hole *) 0
-
-PRIVATE struct hole hole[_NR_HOLES];
-PRIVATE u32_t high_watermark = 0;
-
-PRIVATE struct hole *hole_head;	/* pointer to first hole */
-PRIVATE struct hole *free_slots;/* ptr to list of unused table slots */
-#if ENABLE_SWAP
-PRIVATE int swap_fd = -1;	/* file descriptor of open swap file/device */
-PRIVATE u32_t swap_offset;	/* offset to start of swap area on swap file */
-PRIVATE phys_clicks swap_base;	/* memory offset chosen as swap base */
-PRIVATE phys_clicks swap_maxsize;/* maximum amount of swap "memory" possible */
-PRIVATE struct mproc *in_queue;	/* queue of processes wanting to swap in */
-PRIVATE struct mproc *outswap = &mproc[0]; 	 /* outswap candidate? */
-#else /* ! ENABLE_SWAP */
-#define swap_base ((phys_clicks) -1)
-#endif /* ENABLE_SWAP */
-
-FORWARD _PROTOTYPE( void del_slot, (struct hole *prev_ptr, struct hole *hp) );
-FORWARD _PROTOTYPE( void merge, (struct hole *hp)			    );
-#if ENABLE_SWAP
-FORWARD _PROTOTYPE( int swap_out, (void)				    );
-#else
-#define swap_out()	(0)
-#endif
-
-/*===========================================================================*
- *				alloc_mem				     *
- *===========================================================================*/
-PUBLIC phys_clicks alloc_mem(clicks)
-phys_clicks clicks;		/* amount of memory requested */
-{
-/* Allocate a block of memory from the free list using first fit. The block
- * consists of a sequence of contiguous bytes, whose length in clicks is
- * given by 'clicks'.  A pointer to the block is returned.  The block is
- * always on a click boundary.  This procedure is called when memory is
- * needed for FORK or EXEC.  Swap other processes out if needed.
- */
-  register struct hole *hp, *prev_ptr;
-  phys_clicks old_base;
-
-  do {
-        prev_ptr = NIL_HOLE;
-	hp = hole_head;
-	while (hp != NIL_HOLE && hp->h_base < swap_base) {
-		if (hp->h_len >= clicks) {
-			/* We found a hole that is big enough.  Use it. */
-			old_base = hp->h_base;	/* remember where it started */
-			hp->h_base += clicks;	/* bite a piece off */
-			hp->h_len -= clicks;	/* ditto */
-
-			/* Remember new high watermark of used memory. */
-			if(hp->h_base > high_watermark)
-				high_watermark = hp->h_base;
-
-			/* Delete the hole if used up completely. */
-			if (hp->h_len == 0) del_slot(prev_ptr, hp);
-
-			/* Return the start address of the acquired block. */
-			return(old_base);
-		}
-
-		prev_ptr = hp;
-		hp = hp->h_next;
-	}
-  } while (swap_out());		/* try to swap some other process out */
-  return(NO_MEM);
-}
-
-/*===========================================================================*
- *				free_mem				     *
- *===========================================================================*/
-PUBLIC void free_mem(base, clicks)
-phys_clicks base;		/* base address of block to free */
-phys_clicks clicks;		/* number of clicks to free */
-{
-/* Return a block of free memory to the hole list.  The parameters tell where
- * the block starts in physical memory and how big it is.  The block is added
- * to the hole list.  If it is contiguous with an existing hole on either end,
- * it is merged with the hole or holes.
- */
-  register struct hole *hp, *new_ptr, *prev_ptr;
-
-  if (clicks == 0) return;
-  if ( (new_ptr = free_slots) == NIL_HOLE) 
-  	panic(__FILE__,"hole table full", NO_NUM);
-  new_ptr->h_base = base;
-  new_ptr->h_len = clicks;
-  free_slots = new_ptr->h_next;
-  hp = hole_head;
-
-  /* If this block's address is numerically less than the lowest hole currently
-   * available, or if no holes are currently available, put this hole on the
-   * front of the hole list.
-   */
-  if (hp == NIL_HOLE || base <= hp->h_base) {
-	/* Block to be freed goes on front of the hole list. */
-	new_ptr->h_next = hp;
-	hole_head = new_ptr;
-	merge(new_ptr);
-	return;
-  }
-
-  /* Block to be returned does not go on front of hole list. */
-  prev_ptr = NIL_HOLE;
-  while (hp != NIL_HOLE && base > hp->h_base) {
-	prev_ptr = hp;
-	hp = hp->h_next;
-  }
-
-  /* We found where it goes.  Insert block after 'prev_ptr'. */
-  new_ptr->h_next = prev_ptr->h_next;
-  prev_ptr->h_next = new_ptr;
-  merge(prev_ptr);		/* sequence is 'prev_ptr', 'new_ptr', 'hp' */
-}
-
-/*===========================================================================*
- *				del_slot				     *
- *===========================================================================*/
-PRIVATE void del_slot(prev_ptr, hp)
-/* pointer to hole entry just ahead of 'hp' */
-register struct hole *prev_ptr;
-/* pointer to hole entry to be removed */
-register struct hole *hp;	
-{
-/* Remove an entry from the hole list.  This procedure is called when a
- * request to allocate memory removes a hole in its entirety, thus reducing
- * the numbers of holes in memory, and requiring the elimination of one
- * entry in the hole list.
- */
-  if (hp == hole_head)
-	hole_head = hp->h_next;
-  else
-	prev_ptr->h_next = hp->h_next;
-
-  hp->h_next = free_slots;
-  hp->h_base = hp->h_len = 0;
-  free_slots = hp;
-}
-
-/*===========================================================================*
- *				merge					     *
- *===========================================================================*/
-PRIVATE void merge(hp)
-register struct hole *hp;	/* ptr to hole to merge with its successors */
-{
-/* Check for contiguous holes and merge any found.  Contiguous holes can occur
- * when a block of memory is freed, and it happens to abut another hole on
- * either or both ends.  The pointer 'hp' points to the first of a series of
- * three holes that can potentially all be merged together.
- */
-  register struct hole *next_ptr;
-
-  /* If 'hp' points to the last hole, no merging is possible.  If it does not,
-   * try to absorb its successor into it and free the successor's table entry.
-   */
-  if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
-  if (hp->h_base + hp->h_len == next_ptr->h_base) {
-	hp->h_len += next_ptr->h_len;	/* first one gets second one's mem */
-	del_slot(hp, next_ptr);
-  } else {
-	hp = next_ptr;
-  }
-
-  /* If 'hp' now points to the last hole, return; otherwise, try to absorb its
-   * successor into it.
-   */
-  if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
-  if (hp->h_base + hp->h_len == next_ptr->h_base) {
-	hp->h_len += next_ptr->h_len;
-	del_slot(hp, next_ptr);
-  }
-}
-
-/*===========================================================================*
- *				mem_init				     *
- *===========================================================================*/
-PUBLIC void mem_init(chunks, free)
-struct memory *chunks;		/* list of free memory chunks */
-phys_clicks *free;		/* memory size summaries */
-{
-/* Initialize hole lists.  There are two lists: 'hole_head' points to a linked
- * list of all the holes (unused memory) in the system; 'free_slots' points to
- * a linked list of table entries that are not in use.  Initially, the former
- * list has one entry for each chunk of physical memory, and the second
- * list links together the remaining table slots.  As memory becomes more
- * fragmented in the course of time (i.e., the initial big holes break up into
- * smaller holes), new table slots are needed to represent them.  These slots
- * are taken from the list headed by 'free_slots'.
- */
-  int i;
-  register struct hole *hp;
-
-  /* Put all holes on the free list. */
-  for (hp = &hole[0]; hp < &hole[_NR_HOLES]; hp++) {
-	hp->h_next = hp + 1;
-	hp->h_base = hp->h_len = 0;
-  }
-  hole[_NR_HOLES-1].h_next = NIL_HOLE;
-  hole_head = NIL_HOLE;
-  free_slots = &hole[0];
-
-  /* Use the chunks of physical memory to allocate holes. */
-  *free = 0;
-  for (i=NR_MEMS-1; i>=0; i--) {
-  	if (chunks[i].size > 0) {
-		free_mem(chunks[i].base, chunks[i].size);
-		*free += chunks[i].size;
-#if ENABLE_SWAP
-		if (swap_base < chunks[i].base + chunks[i].size) 
-			swap_base = chunks[i].base + chunks[i].size;
-#endif
-	}
-  }
-
-#if ENABLE_SWAP
-  /* The swap area is represented as a hole above and separate of regular
-   * memory.  A hole at the size of the swap file is allocated on "swapon".
-   */
-  swap_base++;				/* make separate */
-  swap_maxsize = 0 - swap_base;		/* maximum we can possibly use */
-#endif
-}
-
-/*===========================================================================*
- *				mem_holes_copy				     *
- *===========================================================================*/
-PUBLIC int mem_holes_copy(struct hole *holecopies, size_t *bytes, u32_t *hi)
-{
-	if(*bytes < sizeof(hole)) return ENOSPC;
-	memcpy(holecopies, hole, sizeof(hole));
-	*bytes = sizeof(hole);
-	*hi = high_watermark;
-	return OK;
-}
-
-#if ENABLE_SWAP
-/*===========================================================================*
- *				swap_on					     *
- *===========================================================================*/
-PUBLIC int swap_on(file, offset, size)
-char *file;				/* file to swap on */
-u32_t offset, size;			/* area on swap file to use */
-{
-/* Turn swapping on. */
-
-  if (swap_fd != -1) return(EBUSY);	/* already have swap? */
-
-  tell_fs(CHDIR, who_e, FALSE, 0);	/* be like the caller for open() */
-  if ((swap_fd = open(file, O_RDWR)) < 0) return(-errno);
-  swap_offset = offset;
-  size >>= CLICK_SHIFT;
-  if (size > swap_maxsize) size = swap_maxsize;
-  if (size > 0) free_mem(swap_base, (phys_clicks) size);
-  return(OK);
-}
-
-/*===========================================================================*
- *				swap_off				     *
- *===========================================================================*/
-PUBLIC int swap_off()
-{
-/* Turn swapping off. */
-  struct mproc *rmp;
-  struct hole *hp, *prev_ptr;
-
-  if (swap_fd == -1) return(OK);	/* can't turn off what isn't on */
-
-  /* Put all swapped out processes on the inswap queue and swap in. */
-  for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-	if (rmp->mp_flags & ONSWAP) swap_inqueue(rmp);
-  }
-  swap_in();
-
-  /* All in memory? */
-  for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-	if (rmp->mp_flags & ONSWAP) return(ENOMEM);
-  }
-
-  /* Yes.  Remove the swap hole and close the swap file descriptor. */
-  for (hp = hole_head; hp != NIL_HOLE; prev_ptr = hp, hp = hp->h_next) {
-	if (hp->h_base >= swap_base) {
-		del_slot(prev_ptr, hp);
-		hp = hole_head;
-	}
-  }
-  close(swap_fd);
-  swap_fd = -1;
-  return(OK);
-}
-
-/*===========================================================================*
- *				swap_inqueue				     *
- *===========================================================================*/
-PUBLIC void swap_inqueue(rmp)
-register struct mproc *rmp;		/* process to add to the queue */
-{
-/* Put a swapped out process on the queue of processes to be swapped in.  This
- * happens when such a process gets a signal, or if a reply message must be
- * sent, like when a process doing a wait() has a child that exits.
- */
-  struct mproc **pmp;
-
-  if (rmp->mp_flags & SWAPIN) return;	/* already queued */
-
-  
-  for (pmp = &in_queue; *pmp != NULL; pmp = &(*pmp)->mp_swapq) {}
-  *pmp = rmp;
-  rmp->mp_swapq = NULL;
-  rmp->mp_flags |= SWAPIN;
-}
-
-/*===========================================================================*
- *				swap_in					     *
- *===========================================================================*/
-PUBLIC void swap_in()
-{
-/* Try to swap in a process on the inswap queue.  We want to send it a message,
- * interrupt it, or something.
- */
-  struct mproc **pmp, *rmp;
-  phys_clicks old_base, new_base, size;
-  off_t off;
-  int proc_nr;
-
-  pmp = &in_queue;
-  while ((rmp = *pmp) != NULL) {
-	proc_nr = (rmp - mproc);
-	size = rmp->mp_seg[S].mem_vir + rmp->mp_seg[S].mem_len
-		- rmp->mp_seg[D].mem_vir;
-
-	if (!(rmp->mp_flags & SWAPIN)) {
-		/* Guess it got killed.  (Queue is cleaned here.) */
-		*pmp = rmp->mp_swapq;
-		continue;
-	} else
-	if ((new_base = alloc_mem(size)) == NO_MEM) {
-		/* No memory for this one, try the next. */
-		pmp = &rmp->mp_swapq;
-	} else {
-		/* We've found memory.  Update map and swap in. */
-		old_base = rmp->mp_seg[D].mem_phys;
-		rmp->mp_seg[D].mem_phys = new_base;
-		rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys + 
-			(rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
-		sys_newmap(rmp->mp_endpoint, rmp->mp_seg);
-		off = swap_offset + ((off_t) (old_base-swap_base)<<CLICK_SHIFT);
-		lseek(swap_fd, off, SEEK_SET);
-		rw_seg(0, swap_fd, rmp->mp_endpoint, D, (phys_bytes)size << CLICK_SHIFT);
-		free_mem(old_base, size);
-		rmp->mp_flags &= ~(ONSWAP|SWAPIN);
-		*pmp = rmp->mp_swapq;
-		check_pending(rmp);	/* a signal may have waked this one */
-	}
-  }
-}
-
-/*===========================================================================*
- *				swap_out				     *
- *===========================================================================*/
-PRIVATE int swap_out()
-{
-/* Try to find a process that can be swapped out.  Candidates are those blocked
- * on a system call that PM handles, like wait(), pause() or sigsuspend().
- */
-  struct mproc *rmp;
-  struct hole *hp, *prev_ptr;
-  phys_clicks old_base, new_base, size;
-  off_t off;
-  int proc_nr;
-
-  rmp = outswap;
-  do {
-	if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[0];
-
-	/* A candidate? */
-	if (!(rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED))) continue;
-
-	/* Already on swap or otherwise to be avoided? */
-	if (rmp->mp_flags & (DONT_SWAP | TRACED | REPLY | ONSWAP)) continue;
-
-	/* Got one, find a swap hole and swap it out. */
-	proc_nr = (rmp - mproc);
-	size = rmp->mp_seg[S].mem_vir + rmp->mp_seg[S].mem_len
-		- rmp->mp_seg[D].mem_vir;
-
-	prev_ptr = NIL_HOLE;
-	for (hp = hole_head; hp != NIL_HOLE; prev_ptr = hp, hp = hp->h_next) {
-		if (hp->h_base >= swap_base && hp->h_len >= size) break;
-	}
-	if (hp == NIL_HOLE) continue;	/* oops, not enough swapspace */
-	new_base = hp->h_base;
-	hp->h_base += size;
-	hp->h_len -= size;
-	if (hp->h_len == 0) del_slot(prev_ptr, hp);
-
-	off = swap_offset + ((off_t) (new_base - swap_base) << CLICK_SHIFT);
-	lseek(swap_fd, off, SEEK_SET);
-	rw_seg(1, swap_fd, rmp->mp_endpoint, D, (phys_bytes)size << CLICK_SHIFT);
-	old_base = rmp->mp_seg[D].mem_phys;
-	rmp->mp_seg[D].mem_phys = new_base;
-	rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys + 
-		(rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
-	sys_newmap(rmp->mp_endpoint, rmp->mp_seg);
-	free_mem(old_base, size);
-	rmp->mp_flags |= ONSWAP;
-
-	outswap = rmp;		/* next time start here */
-	return(TRUE);
-  } while (rmp != outswap);
-
-  return(FALSE);	/* no candidate found */
-}
-#endif /* SWAP */
Index: trunk/minix/servers/pm/break.c
===================================================================
--- trunk/minix/servers/pm/break.c	(revision 11)
+++ 	(revision )
@@ -1,177 +1,0 @@
-/* The MINIX model of memory allocation reserves a fixed amount of memory for
- * the combined text, data, and stack segments.  The amount used for a child
- * process created by FORK is the same as the parent had.  If the child does
- * an EXEC later, the new size is taken from the header of the file EXEC'ed.
- *
- * The layout in memory consists of the text segment, followed by the data
- * segment, followed by a gap (unused memory), followed by the stack segment.
- * The data segment grows upward and the stack grows downward, so each can
- * take memory from the gap.  If they meet, the process must be killed.  The
- * procedures in this file deal with the growth of the data and stack segments.
- *
- * The entry points into this file are:
- *   do_brk:	  BRK/SBRK system calls to grow or shrink the data segment
- *   adjust:	  see if a proposed segment adjustment is allowed
- *   size_ok:	  see if the segment sizes are feasible (i86 only)
- */
-
-#include "pm.h"
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-#define DATA_CHANGED       1	/* flag value when data segment size changed */
-#define STACK_CHANGED      2	/* flag value when stack size changed */
-
-/*===========================================================================*
- *				do_brk  				     *
- *===========================================================================*/
-PUBLIC int do_brk()
-{
-/* Perform the brk(addr) system call.
- *
- * The call is complicated by the fact that on some machines (e.g., 8088),
- * the stack pointer can grow beyond the base of the stack segment without
- * anybody noticing it.
- * The parameter, 'addr' is the new virtual address in D space.
- */
-
-  register struct mproc *rmp;
-  int r;
-  vir_bytes v, new_sp;
-  vir_clicks new_clicks;
-
-  rmp = mp;
-  v = (vir_bytes) m_in.addr;
-  new_clicks = (vir_clicks) ( ((long) v + CLICK_SIZE - 1) >> CLICK_SHIFT);
-  if (new_clicks < rmp->mp_seg[D].mem_vir) {
-	rmp->mp_reply.reply_ptr = (char *) -1;
-	return(ENOMEM);
-  }
-  new_clicks -= rmp->mp_seg[D].mem_vir;
-  if ((r=get_stack_ptr(who_e, &new_sp)) != OK) /* ask kernel for sp value */
-  	panic(__FILE__,"couldn't get stack pointer", r);
-  r = adjust(rmp, new_clicks, new_sp);
-  rmp->mp_reply.reply_ptr = (r == OK ? m_in.addr : (char *) -1);
-  return(r);			/* return new address or -1 */
-}
-
-/*===========================================================================*
- *				adjust  				     *
- *===========================================================================*/
-PUBLIC int adjust(rmp, data_clicks, sp)
-register struct mproc *rmp;	/* whose memory is being adjusted? */
-vir_clicks data_clicks;		/* how big is data segment to become? */
-vir_bytes sp;			/* new value of sp */
-{
-/* See if data and stack segments can coexist, adjusting them if need be.
- * Memory is never allocated or freed.  Instead it is added or removed from the
- * gap between data segment and stack segment.  If the gap size becomes
- * negative, the adjustment of data or stack fails and ENOMEM is returned.
- */
-
-  register struct mem_map *mem_sp, *mem_dp;
-  vir_clicks sp_click, gap_base, lower, old_clicks;
-  int changed, r, ft;
-  long base_of_stack, delta;	/* longs avoid certain problems */
-
-  mem_dp = &rmp->mp_seg[D];	/* pointer to data segment map */
-  mem_sp = &rmp->mp_seg[S];	/* pointer to stack segment map */
-  changed = 0;			/* set when either segment changed */
-
-  if (mem_sp->mem_len == 0) return(OK);	/* don't bother init */
-
-  /* See if stack size has gone negative (i.e., sp too close to 0xFFFF...) */
-  base_of_stack = (long) mem_sp->mem_vir + (long) mem_sp->mem_len;
-  sp_click = sp >> CLICK_SHIFT;	/* click containing sp */
-  if (sp_click >= base_of_stack) return(ENOMEM);	/* sp too high */
-
-  /* Compute size of gap between stack and data segments. */
-  delta = (long) mem_sp->mem_vir - (long) sp_click;
-  lower = (delta > 0 ? sp_click : mem_sp->mem_vir);
-
-  /* Add a safety margin for future stack growth. Impossible to do right. */
-#define SAFETY_BYTES  (384 * sizeof(char *))
-#define SAFETY_CLICKS ((SAFETY_BYTES + CLICK_SIZE - 1) / CLICK_SIZE)
-  gap_base = mem_dp->mem_vir + data_clicks + SAFETY_CLICKS;
-  if (lower < gap_base) return(ENOMEM);	/* data and stack collided */
-
-  /* Update data length (but not data orgin) on behalf of brk() system call. */
-  old_clicks = mem_dp->mem_len;
-  if (data_clicks != mem_dp->mem_len) {
-	mem_dp->mem_len = data_clicks;
-	changed |= DATA_CHANGED;
-  }
-
-  /* Update stack length and origin due to change in stack pointer. */
-  if (delta > 0) {
-	mem_sp->mem_vir -= delta;
-	mem_sp->mem_phys -= delta;
-	mem_sp->mem_len += delta;
-	changed |= STACK_CHANGED;
-  }
-
-  /* Do the new data and stack segment sizes fit in the address space? */
-  ft = (rmp->mp_flags & SEPARATE);
-#if (CHIP == INTEL && _WORD_SIZE == 2)
-  r = size_ok(ft, rmp->mp_seg[T].mem_len, rmp->mp_seg[D].mem_len, 
-       rmp->mp_seg[S].mem_len, rmp->mp_seg[D].mem_vir, rmp->mp_seg[S].mem_vir);
-#else
-  r = (rmp->mp_seg[D].mem_vir + rmp->mp_seg[D].mem_len > 
-          rmp->mp_seg[S].mem_vir) ? ENOMEM : OK;
-#endif
-  if (r == OK) {
-	int r2;
-	if (changed && (r2=sys_newmap(rmp->mp_endpoint, rmp->mp_seg)) != OK)
-  		panic(__FILE__,"couldn't sys_newmap in adjust", r2);
-	return(OK);
-  }
-
-  /* New sizes don't fit or require too many page/segment registers. Restore.*/
-  if (changed & DATA_CHANGED) mem_dp->mem_len = old_clicks;
-  if (changed & STACK_CHANGED) {
-	mem_sp->mem_vir += delta;
-	mem_sp->mem_phys += delta;
-	mem_sp->mem_len -= delta;
-  }
-  return(ENOMEM);
-}
-
-#if (CHIP == INTEL && _WORD_SIZE == 2)
-/*===========================================================================*
- *				size_ok  				     *
- *===========================================================================*/
-PUBLIC int size_ok(file_type, tc, dc, sc, dvir, s_vir)
-int file_type;			/* SEPARATE or 0 */
-vir_clicks tc;			/* text size in clicks */
-vir_clicks dc;			/* data size in clicks */
-vir_clicks sc;			/* stack size in clicks */
-vir_clicks dvir;		/* virtual address for start of data seg */
-vir_clicks s_vir;		/* virtual address for start of stack seg */
-{
-/* Check to see if the sizes are feasible and enough segmentation registers
- * exist.  On a machine with eight 8K pages, text, data, stack sizes of
- * (32K, 16K, 16K) will fit, but (33K, 17K, 13K) will not, even though the
- * former is bigger (64K) than the latter (63K).  Even on the 8088 this test
- * is needed, since the data and stack may not exceed 4096 clicks.
- * Note this is not used for 32-bit Intel Minix, the test is done in-line.
- */
-
-  int pt, pd, ps;		/* segment sizes in pages */
-
-  pt = ( (tc << CLICK_SHIFT) + PAGE_SIZE - 1)/PAGE_SIZE;
-  pd = ( (dc << CLICK_SHIFT) + PAGE_SIZE - 1)/PAGE_SIZE;
-  ps = ( (sc << CLICK_SHIFT) + PAGE_SIZE - 1)/PAGE_SIZE;
-
-  if (file_type == SEPARATE) {
-	if (pt > MAX_PAGES || pd + ps > MAX_PAGES) return(ENOMEM);
-  } else {
-	if (pt + pd + ps > MAX_PAGES) return(ENOMEM);
-  }
-
-  if (dvir + dc > s_vir) return(ENOMEM);
-
-  return(OK);
-}
-#endif
-
Index: trunk/minix/servers/pm/const.h
===================================================================
--- trunk/minix/servers/pm/const.h	(revision 11)
+++ 	(revision )
@@ -1,21 +1,0 @@
-/* Constants used by the Process Manager. */
-
-#define NO_MEM ((phys_clicks) 0)  /* returned by alloc_mem() with mem is up */
-
-#if (CHIP == INTEL && _WORD_SIZE == 2)
-/* These definitions are used in size_ok and are not needed for 386.
- * The 386 segment granularity is 1 for segments smaller than 1M and 4096
- * above that.  
- */
-#define PAGE_SIZE	  16	/* how many bytes in a page (s.b.HCLICK_SIZE)*/
-#define MAX_PAGES       4096	/* how many pages in the virtual addr space */
-#endif
-
-#define NR_PIDS	       30000	/* process ids range from 0 to NR_PIDS-1.
-				 * (magic constant: some old applications use
-				 * a 'short' instead of pid_t.)
-				 */
-
-#define PM_PID	           0	/* PM's process id number */
-#define INIT_PID	   1	/* INIT's process id number */
-
Index: trunk/minix/servers/pm/exec.c
===================================================================
--- trunk/minix/servers/pm/exec.c	(revision 11)
+++ 	(revision )
@@ -1,604 +1,0 @@
-/* This file handles the EXEC system call.  It performs the work as follows:
- *    - see if the permissions allow the file to be executed
- *    - read the header and extract the sizes
- *    - fetch the initial args and environment from the user space
- *    - allocate the memory for the new process
- *    - copy the initial stack from PM to the process
- *    - read in the text and data segments and copy to the process
- *    - take care of setuid and setgid bits
- *    - fix up 'mproc' table
- *    - tell kernel about EXEC
- *    - save offset to initial argc (for ps)
- *
- * The entry points into this file are:
- *   do_exec:	 perform the EXEC system call
- *   rw_seg:	 read or write a segment from or to a file
- *   find_share: find a process whose text segment can be shared
- */
-
-#include "pm.h"
-#include <sys/stat.h>
-#include <minix/callnr.h>
-#include <minix/endpoint.h>
-#include <minix/com.h>
-#include <a.out.h>
-#include <signal.h>
-#include <string.h>
-#include "mproc.h"
-#include "param.h"
-
-FORWARD _PROTOTYPE( int new_mem, (struct mproc *sh_mp, vir_bytes text_bytes,
-		vir_bytes data_bytes, vir_bytes bss_bytes,
-		vir_bytes stk_bytes, phys_bytes tot_bytes)		);
-FORWARD _PROTOTYPE( void patch_ptr, (char stack[ARG_MAX], vir_bytes base) );
-FORWARD _PROTOTYPE( int insert_arg, (char stack[ARG_MAX],
-		vir_bytes *stk_bytes, char *arg, int replace)		);
-FORWARD _PROTOTYPE( char *patch_stack, (int fd, char stack[ARG_MAX],
-		vir_bytes *stk_bytes, char *script)			);
-FORWARD _PROTOTYPE( int read_header, (int fd, int *ft, vir_bytes *text_bytes,
-		vir_bytes *data_bytes, vir_bytes *bss_bytes,
-		phys_bytes *tot_bytes, long *sym_bytes, vir_clicks sc,
-		vir_bytes *pc)						);
-
-#define ESCRIPT	(-2000)	/* Returned by read_header for a #! script. */
-#define PTRSIZE	sizeof(char *) /* Size of pointers in argv[] and envp[]. */
-
-/*===========================================================================*
- *				do_exec					     *
- *===========================================================================*/
-PUBLIC int do_exec()
-{
-/* Perform the execve(name, argv, envp) call.  The user library builds a
- * complete stack image, including pointers, args, environ, etc.  The stack
- * is copied to a buffer inside PM, and then to the new core image.
- */
-  register struct mproc *rmp;
-  struct mproc *sh_mp;
-  int m, r, r2, fd, ft, sn;
-  static char mbuf[ARG_MAX];	/* buffer for stack and zeroes */
-  static char name_buf[PATH_MAX]; /* the name of the file to exec */
-  char *new_sp, *name, *basename;
-  vir_bytes src, dst, text_bytes, data_bytes, bss_bytes, stk_bytes, vsp;
-  phys_bytes tot_bytes;		/* total space for program, including gap */
-  long sym_bytes;
-  vir_clicks sc;
-  struct stat s_buf[2], *s_p;
-  vir_bytes pc;
-
-  /* Do some validity checks. */
-  rmp = mp;
-  stk_bytes = (vir_bytes) m_in.stack_bytes;
-  if (stk_bytes > ARG_MAX) return(ENOMEM);	/* stack too big */
-  if (m_in.exec_len <= 0 || m_in.exec_len > PATH_MAX) return(EINVAL);
-
-  /* Get the exec file name and see if the file is executable. */
-  src = (vir_bytes) m_in.exec_name;
-  dst = (vir_bytes) name_buf;
-  r = sys_datacopy(who_e, (vir_bytes) src,
-		PM_PROC_NR, (vir_bytes) dst, (phys_bytes) m_in.exec_len);
-  if (r != OK) return(r);	/* file name not in user data segment */
-
-  /* Fetch the stack from the user before destroying the old core image. */
-  src = (vir_bytes) m_in.stack_ptr;
-  dst = (vir_bytes) mbuf;
-  r = sys_datacopy(who_e, (vir_bytes) src,
-  			PM_PROC_NR, (vir_bytes) dst, (phys_bytes)stk_bytes);
-  /* can't fetch stack (e.g. bad virtual addr) */
-  if (r != OK) return(EACCES);	
-
-  r = 0;	/* r = 0 (first attempt), or 1 (interpreted script) */
-  name = name_buf;	/* name of file to exec. */
-  do {
-	s_p = &s_buf[r];
-	tell_fs(CHDIR, who_e, FALSE, 0);  /* switch to the user's FS environ */
-	fd = allowed(name, s_p, X_BIT);	/* is file executable? */
-	if (fd < 0)  return(fd);		/* file was not executable */
-
-	/* Read the file header and extract the segment sizes. */
-	sc = (stk_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-
-	m = read_header(fd, &ft, &text_bytes, &data_bytes, &bss_bytes, 
-					&tot_bytes, &sym_bytes, sc, &pc);
-	if (m != ESCRIPT || ++r > 1) break;
-  } while ((name = patch_stack(fd, mbuf, &stk_bytes, name_buf)) != NULL);
-
-  if (m < 0) {
-	close(fd);		/* something wrong with header */
-	return(stk_bytes > ARG_MAX ? ENOMEM : ENOEXEC);
-  }
-
-  /* Can the process' text be shared with that of one already running? */
-  sh_mp = find_share(rmp, s_p->st_ino, s_p->st_dev, s_p->st_ctime);
-
-  /* Allocate new memory and release old memory.  Fix map and tell kernel. */
-  r = new_mem(sh_mp, text_bytes, data_bytes, bss_bytes, stk_bytes, tot_bytes);
-  if (r != OK) {
-	close(fd);		/* insufficient core or program too big */
-	return(r);
-  }
-
-  /* Save file identification to allow it to be shared. */
-  rmp->mp_ino = s_p->st_ino;
-  rmp->mp_dev = s_p->st_dev;
-  rmp->mp_ctime = s_p->st_ctime;
-
-  /* Patch up stack and copy it from PM to new core image. */
-  vsp = (vir_bytes) rmp->mp_seg[S].mem_vir << CLICK_SHIFT;
-  vsp += (vir_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT;
-  vsp -= stk_bytes;
-  patch_ptr(mbuf, vsp);
-  src = (vir_bytes) mbuf;
-  r = sys_datacopy(PM_PROC_NR, (vir_bytes) src,
-  			who_e, (vir_bytes) vsp, (phys_bytes)stk_bytes);
-  if (r != OK) panic(__FILE__,"do_exec stack copy err on", who_e);
-
-  /* Read in text and data segments. */
-  if (sh_mp != NULL) {
-	lseek(fd, (off_t) text_bytes, SEEK_CUR);  /* shared: skip text */
-  } else {
-	rw_seg(0, fd, who_e, T, text_bytes);
-  }
-  rw_seg(0, fd, who_e, D, data_bytes);
-
-  close(fd);			/* don't need exec file any more */
-
-  /* Take care of setuid/setgid bits. */
-  if ((rmp->mp_flags & TRACED) == 0) { /* suppress if tracing */
-	if (s_buf[0].st_mode & I_SET_UID_BIT) {
-		rmp->mp_effuid = s_buf[0].st_uid;
-		tell_fs(SETUID, who_e, (int)rmp->mp_realuid, (int)rmp->mp_effuid);
-	}
-	if (s_buf[0].st_mode & I_SET_GID_BIT) {
-		rmp->mp_effgid = s_buf[0].st_gid;
-		tell_fs(SETGID,who_e, (int)rmp->mp_realgid, (int)rmp->mp_effgid);
-	}
-  }
-
-  /* Save offset to initial argc (for ps) */
-  rmp->mp_procargs = vsp;
-
-  /* Fix 'mproc' fields, tell kernel that exec is done,  reset caught sigs. */
-  for (sn = 1; sn <= _NSIG; sn++) {
-	if (sigismember(&rmp->mp_catch, sn)) {
-		sigdelset(&rmp->mp_catch, sn);
-		rmp->mp_sigact[sn].sa_handler = SIG_DFL;
-		sigemptyset(&rmp->mp_sigact[sn].sa_mask);
-	}
-  }
-
-  rmp->mp_flags &= ~SEPARATE;	/* turn off SEPARATE bit */
-  rmp->mp_flags |= ft;		/* turn it on for separate I & D files */
-  new_sp = (char *) vsp;
-
-  tell_fs(EXEC, who_e, 0, 0);	/* allow FS to handle FD_CLOEXEC files */
-
-  /* System will save command line for debugging, ps(1) output, etc. */
-  basename = strrchr(name, '/');
-  if (basename == NULL) basename = name; else basename++;
-  strncpy(rmp->mp_name, basename, PROC_NAME_LEN-1);
-  rmp->mp_name[PROC_NAME_LEN] = '\0';
-  if((r2=sys_exec(who_e, new_sp, basename, pc)) != OK) {
-	panic(__FILE__,"sys_exec failed", r2);
-  }
-
-  /* Cause a signal if this process is traced. */
-  if (rmp->mp_flags & TRACED) check_sig(rmp->mp_pid, SIGTRAP);
-
-  return(SUSPEND);		/* no reply, new program just runs */
-}
-
-/*===========================================================================*
- *				read_header				     *
- *===========================================================================*/
-PRIVATE int read_header(fd, ft, text_bytes, data_bytes, bss_bytes, 
-						tot_bytes, sym_bytes, sc, pc)
-int fd;				/* file descriptor for reading exec file */
-int *ft;			/* place to return ft number */
-vir_bytes *text_bytes;		/* place to return text size */
-vir_bytes *data_bytes;		/* place to return initialized data size */
-vir_bytes *bss_bytes;		/* place to return bss size */
-phys_bytes *tot_bytes;		/* place to return total size */
-long *sym_bytes;		/* place to return symbol table size */
-vir_clicks sc;			/* stack size in clicks */
-vir_bytes *pc;			/* program entry point (initial PC) */
-{
-/* Read the header and extract the text, data, bss and total sizes from it. */
-
-  int m, ct;
-  vir_clicks tc, dc, s_vir, dvir;
-  phys_clicks totc;
-  struct exec hdr;		/* a.out header is read in here */
-
-  /* Read the header and check the magic number.  The standard MINIX header 
-   * is defined in <a.out.h>.  It consists of 8 chars followed by 6 longs.
-   * Then come 4 more longs that are not used here.
-   *	Byte 0: magic number 0x01
-   *	Byte 1: magic number 0x03
-   *	Byte 2: normal = 0x10 (not checked, 0 is OK), separate I/D = 0x20
-   *	Byte 3: CPU type, Intel 16 bit = 0x04, Intel 32 bit = 0x10, 
-   *            Motorola = 0x0B, Sun SPARC = 0x17
-   *	Byte 4: Header length = 0x20
-   *	Bytes 5-7 are not used.
-   *
-   *	Now come the 6 longs
-   *	Bytes  8-11: size of text segments in bytes
-   *	Bytes 12-15: size of initialized data segment in bytes
-   *	Bytes 16-19: size of bss in bytes
-   *	Bytes 20-23: program entry point
-   *	Bytes 24-27: total memory allocated to program (text, data + stack)
-   *	Bytes 28-31: size of symbol table in bytes
-   * The longs are represented in a machine dependent order,
-   * little-endian on the 8088, big-endian on the 68000.
-   * The header is followed directly by the text and data segments, and the 
-   * symbol table (if any). The sizes are given in the header. Only the 
-   * text and data segments are copied into memory by exec. The header is 
-   * used here only. The symbol table is for the benefit of a debugger and 
-   * is ignored here.
-   */
-
-  if ((m= read(fd, &hdr, A_MINHDR)) < 2) return(ENOEXEC);
-
-  /* Interpreted script? */
-  if (((char *) &hdr)[0] == '#' && ((char *) &hdr)[1] == '!') return(ESCRIPT);
-
-  if (m != A_MINHDR) return(ENOEXEC);
-
-  /* Check magic number, cpu type, and flags. */
-  if (BADMAG(hdr)) return(ENOEXEC);
-#if (CHIP == INTEL && _WORD_SIZE == 2)
-  if (hdr.a_cpu != A_I8086) return(ENOEXEC);
-#endif
-#if (CHIP == INTEL && _WORD_SIZE == 4)
-  if (hdr.a_cpu != A_I80386) return(ENOEXEC);
-#endif
-  if ((hdr.a_flags & ~(A_NSYM | A_EXEC | A_SEP)) != 0) return(ENOEXEC);
-
-  *ft = ( (hdr.a_flags & A_SEP) ? SEPARATE : 0);    /* separate I & D or not */
-
-  /* Get text and data sizes. */
-  *text_bytes = (vir_bytes) hdr.a_text;	/* text size in bytes */
-  *data_bytes = (vir_bytes) hdr.a_data;	/* data size in bytes */
-  *bss_bytes  = (vir_bytes) hdr.a_bss;	/* bss size in bytes */
-  *tot_bytes  = hdr.a_total;		/* total bytes to allocate for prog */
-  *sym_bytes  = hdr.a_syms;		/* symbol table size in bytes */
-  if (*tot_bytes == 0) return(ENOEXEC);
-
-  if (*ft != SEPARATE) {
-	/* If I & D space is not separated, it is all considered data. Text=0*/
-	*data_bytes += *text_bytes;
-	*text_bytes = 0;
-  }
-  *pc = hdr.a_entry;	/* initial address to start execution */
-
-  /* Check to see if segment sizes are feasible. */
-  tc = ((unsigned long) *text_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  dc = (*data_bytes + *bss_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  totc = (*tot_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  if (dc >= totc) return(ENOEXEC);	/* stack must be at least 1 click */
-  dvir = (*ft == SEPARATE ? 0 : tc);
-  s_vir = dvir + (totc - sc);
-#if (CHIP == INTEL && _WORD_SIZE == 2)
-  m = size_ok(*ft, tc, dc, sc, dvir, s_vir);
-#else
-  m = (dvir + dc > s_vir) ? ENOMEM : OK;
-#endif
-  ct = hdr.a_hdrlen & BYTE;		/* header length */
-  if (ct > A_MINHDR) lseek(fd, (off_t) ct, SEEK_SET); /* skip unused hdr */
-  return(m);
-}
-
-/*===========================================================================*
- *				new_mem					     *
- *===========================================================================*/
-PRIVATE int new_mem(sh_mp, text_bytes, data_bytes,
-	bss_bytes,stk_bytes,tot_bytes)
-struct mproc *sh_mp;		/* text can be shared with this process */
-vir_bytes text_bytes;		/* text segment size in bytes */
-vir_bytes data_bytes;		/* size of initialized data in bytes */
-vir_bytes bss_bytes;		/* size of bss in bytes */
-vir_bytes stk_bytes;		/* size of initial stack segment in bytes */
-phys_bytes tot_bytes;		/* total memory to allocate, including gap */
-{
-/* Allocate new memory and release the old memory.  Change the map and report
- * the new map to the kernel.  Zero the new core image's bss, gap and stack.
- */
-
-  register struct mproc *rmp = mp;
-  vir_clicks text_clicks, data_clicks, gap_clicks, stack_clicks, tot_clicks;
-  phys_clicks new_base;
-  phys_bytes bytes, base, bss_offset;
-  int s, r2;
-
-  /* No need to allocate text if it can be shared. */
-  if (sh_mp != NULL) text_bytes = 0;
-
-  /* Allow the old data to be swapped out to make room.  (Which is really a
-   * waste of time, because we are going to throw it away anyway.)
-   */
-  rmp->mp_flags |= WAITING;
-
-  /* Acquire the new memory.  Each of the 4 parts: text, (data+bss), gap,
-   * and stack occupies an integral number of clicks, starting at click
-   * boundary.  The data and bss parts are run together with no space.
-   */
-  text_clicks = ((unsigned long) text_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  data_clicks = (data_bytes + bss_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  stack_clicks = (stk_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  tot_clicks = (tot_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
-  gap_clicks = tot_clicks - data_clicks - stack_clicks;
-  if ( (int) gap_clicks < 0) return(ENOMEM);
-
-  /* Try to allocate memory for the new process. */
-  new_base = alloc_mem(text_clicks + tot_clicks);
-  if (new_base == NO_MEM) return(ENOMEM);
-
-  /* We've got memory for the new core image.  Release the old one. */
-  rmp = mp;
-
-  if (find_share(rmp, rmp->mp_ino, rmp->mp_dev, rmp->mp_ctime) == NULL) {
-	/* No other process shares the text segment, so free it. */
-	free_mem(rmp->mp_seg[T].mem_phys, rmp->mp_seg[T].mem_len);
-  }
-  /* Free the data and stack segments. */
-  free_mem(rmp->mp_seg[D].mem_phys,
-   rmp->mp_seg[S].mem_vir + rmp->mp_seg[S].mem_len - rmp->mp_seg[D].mem_vir);
-
-  /* We have now passed the point of no return.  The old core image has been
-   * forever lost, memory for a new core image has been allocated.  Set up
-   * and report new map.
-   */
-  if (sh_mp != NULL) {
-	/* Share the text segment. */
-	rmp->mp_seg[T] = sh_mp->mp_seg[T];
-  } else {
-	rmp->mp_seg[T].mem_phys = new_base;
-	rmp->mp_seg[T].mem_vir = 0;
-	rmp->mp_seg[T].mem_len = text_clicks;
-  }
-  rmp->mp_seg[D].mem_phys = new_base + text_clicks;
-  rmp->mp_seg[D].mem_vir = 0;
-  rmp->mp_seg[D].mem_len = data_clicks;
-  rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys + data_clicks + gap_clicks;
-  rmp->mp_seg[S].mem_vir = rmp->mp_seg[D].mem_vir + data_clicks + gap_clicks;
-  rmp->mp_seg[S].mem_len = stack_clicks;
-
-#if (CHIP == M68000)
-  rmp->mp_seg[T].mem_vir = 0;
-  rmp->mp_seg[D].mem_vir = rmp->mp_seg[T].mem_len;
-  rmp->mp_seg[S].mem_vir = rmp->mp_seg[D].mem_vir 
-  	+ rmp->mp_seg[D].mem_len + gap_clicks;
-#endif
-
-  if((r2=sys_newmap(who_e, rmp->mp_seg)) != OK) {
-	/* report new map to the kernel */
-	panic(__FILE__,"sys_newmap failed", r2);
-  }
-
-  /* The old memory may have been swapped out, but the new memory is real. */
-  rmp->mp_flags &= ~(WAITING|ONSWAP|SWAPIN);
-
-  /* Zero the bss, gap, and stack segment. */
-  bytes = (phys_bytes)(data_clicks + gap_clicks + stack_clicks) << CLICK_SHIFT;
-  base = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT;
-  bss_offset = (data_bytes >> CLICK_SHIFT) << CLICK_SHIFT;
-  base += bss_offset;
-  bytes -= bss_offset;
-
-  if ((s=sys_memset(0, base, bytes)) != OK) {
-	panic(__FILE__,"new_mem can't zero", s);
-  }
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				patch_ptr				     *
- *===========================================================================*/
-PRIVATE void patch_ptr(stack, base)
-char stack[ARG_MAX];		/* pointer to stack image within PM */
-vir_bytes base;			/* virtual address of stack base inside user */
-{
-/* When doing an exec(name, argv, envp) call, the user builds up a stack
- * image with arg and env pointers relative to the start of the stack.  Now
- * these pointers must be relocated, since the stack is not positioned at
- * address 0 in the user's address space.
- */
-
-  char **ap, flag;
-  vir_bytes v;
-
-  flag = 0;			/* counts number of 0-pointers seen */
-  ap = (char **) stack;		/* points initially to 'nargs' */
-  ap++;				/* now points to argv[0] */
-  while (flag < 2) {
-	if (ap >= (char **) &stack[ARG_MAX]) return;	/* too bad */
-	if (*ap != NULL) {
-		v = (vir_bytes) *ap;	/* v is relative pointer */
-		v += base;		/* relocate it */
-		*ap = (char *) v;	/* put it back */
-	} else {
-		flag++;
-	}
-	ap++;
-  }
-}
-
-/*===========================================================================*
- *				insert_arg				     *
- *===========================================================================*/
-PRIVATE int insert_arg(stack, stk_bytes, arg, replace)
-char stack[ARG_MAX];		/* pointer to stack image within PM */
-vir_bytes *stk_bytes;		/* size of initial stack */
-char *arg;			/* argument to prepend/replace as new argv[0] */
-int replace;
-{
-/* Patch the stack so that arg will become argv[0].  Be careful, the stack may
- * be filled with garbage, although it normally looks like this:
- *	nargs argv[0] ... argv[nargs-1] NULL envp[0] ... NULL
- * followed by the strings "pointed" to by the argv[i] and the envp[i].  The
- * pointers are really offsets from the start of stack.
- * Return true iff the operation succeeded.
- */
-  int offset, a0, a1, old_bytes = *stk_bytes;
-
-  /* Prepending arg adds at least one string and a zero byte. */
-  offset = strlen(arg) + 1;
-
-  a0 = (int) ((char **) stack)[1];	/* argv[0] */
-  if (a0 < 4 * PTRSIZE || a0 >= old_bytes) return(FALSE);
-
-  a1 = a0;			/* a1 will point to the strings to be moved */
-  if (replace) {
-	/* Move a1 to the end of argv[0][] (argv[1] if nargs > 1). */
-	do {
-		if (a1 == old_bytes) return(FALSE);
-		--offset;
-	} while (stack[a1++] != 0);
-  } else {
-	offset += PTRSIZE;	/* new argv[0] needs new pointer in argv[] */
-	a0 += PTRSIZE;		/* location of new argv[0][]. */
-  }
-
-  /* stack will grow by offset bytes (or shrink by -offset bytes) */
-  if ((*stk_bytes += offset) > ARG_MAX) return(FALSE);
-
-  /* Reposition the strings by offset bytes */
-  memmove(stack + a1 + offset, stack + a1, old_bytes - a1);
-
-  strcpy(stack + a0, arg);	/* Put arg in the new space. */
-
-  if (!replace) {
-	/* Make space for a new argv[0]. */
-	memmove(stack + 2 * PTRSIZE, stack + 1 * PTRSIZE, a0 - 2 * PTRSIZE);
-
-	((char **) stack)[0]++;	/* nargs++; */
-  }
-  /* Now patch up argv[] and envp[] by offset. */
-  patch_ptr(stack, (vir_bytes) offset);
-  ((char **) stack)[1] = (char *) a0;	/* set argv[0] correctly */
-  return(TRUE);
-}
-
-/*===========================================================================*
- *				patch_stack				     *
- *===========================================================================*/
-PRIVATE char *patch_stack(fd, stack, stk_bytes, script)
-int fd;				/* file descriptor to open script file */
-char stack[ARG_MAX];		/* pointer to stack image within PM */
-vir_bytes *stk_bytes;		/* size of initial stack */
-char *script;			/* name of script to interpret */
-{
-/* Patch the argument vector to include the path name of the script to be
- * interpreted, and all strings on the #! line.  Returns the path name of
- * the interpreter.
- */
-  char *sp, *interp = NULL;
-  int n;
-  enum { INSERT=FALSE, REPLACE=TRUE };
-
-  /* Make script[] the new argv[0]. */
-  if (!insert_arg(stack, stk_bytes, script, REPLACE)) return(NULL);
-
-  if (lseek(fd, 2L, 0) == -1			/* just behind the #! */
-    || (n= read(fd, script, PATH_MAX)) < 0	/* read line one */
-    || (sp= memchr(script, '\n', n)) == NULL)	/* must be a proper line */
-	return(NULL);
-
-  /* Move sp backwards through script[], prepending each string to stack. */
-  for (;;) {
-	/* skip spaces behind argument. */
-	while (sp > script && (*--sp == ' ' || *sp == '\t')) {}
-	if (sp == script) break;
-
-	sp[1] = 0;
-	/* Move to the start of the argument. */
-	while (sp > script && sp[-1] != ' ' && sp[-1] != '\t') --sp;
-
-	interp = sp;
-	if (!insert_arg(stack, stk_bytes, sp, INSERT)) return(NULL);
-  }
-
-  /* Round *stk_bytes up to the size of a pointer for alignment contraints. */
-  *stk_bytes= ((*stk_bytes + PTRSIZE - 1) / PTRSIZE) * PTRSIZE;
-
-  close(fd);
-  return(interp);
-}
-
-/*===========================================================================*
- *				rw_seg					     *
- *===========================================================================*/
-PUBLIC void rw_seg(rw, fd, proc_e, seg, seg_bytes0)
-int rw;				/* 0 = read, 1 = write */
-int fd;				/* file descriptor to read from / write to */
-int proc_e;			/* process number (endpoint) */
-int seg;			/* T, D, or S */
-phys_bytes seg_bytes0;		/* how much is to be transferred? */
-{
-/* Transfer text or data from/to a file and copy to/from a process segment.
- * This procedure is a little bit tricky.  The logical way to transfer a
- * segment would be block by block and copying each block to/from the user
- * space one at a time.  This is too slow, so we do something dirty here,
- * namely send the user space and virtual address to the file system in the
- * upper 10 bits of the file descriptor, and pass it the user virtual address
- * instead of a PM address.  The file system extracts these parameters when 
- * gets a read or write call from the process manager, which is the only 
- * process that is permitted to use this trick.  The file system then copies 
- * the whole segment directly to/from user space, bypassing PM completely.
- *
- * The byte count on read is usually smaller than the segment count, because
- * a segment is padded out to a click multiple, and the data segment is only
- * partially initialized.
- */
-
-  int bytes, r, proc_n;
-  char *ubuf_ptr;
-  struct mem_map *sp;
-  phys_bytes seg_bytes = seg_bytes0;
-
-  if(pm_isokendpt(proc_e, &proc_n) != OK || proc_n < 0)
-	return;
-
-  sp = &mproc[proc_n].mp_seg[seg];
-
-  ubuf_ptr = (char *) ((vir_bytes) sp->mem_vir << CLICK_SHIFT);
-
-  while (seg_bytes != 0) {
-#define PM_CHUNK_SIZE 8192
-	bytes = MIN((INT_MAX / PM_CHUNK_SIZE) * PM_CHUNK_SIZE, seg_bytes);
-	if(!rw) {
-		r = _read_pm(fd, ubuf_ptr, bytes, seg, proc_e);
-	} else {
-		r = _write_pm(fd, ubuf_ptr, bytes, seg, proc_e);
-	}
-	if (r != bytes) break;
-	ubuf_ptr += bytes;
-	seg_bytes -= bytes;
-  }
-}
-
-/*===========================================================================*
- *				find_share				     *
- *===========================================================================*/
-PUBLIC struct mproc *find_share(mp_ign, ino, dev, ctime)
-struct mproc *mp_ign;		/* process that should not be looked at */
-ino_t ino;			/* parameters that uniquely identify a file */
-dev_t dev;
-time_t ctime;
-{
-/* Look for a process that is the file <ino, dev, ctime> in execution.  Don't
- * accidentally "find" mp_ign, because it is the process on whose behalf this
- * call is made.
- */
-  struct mproc *sh_mp;
-  for (sh_mp = &mproc[0]; sh_mp < &mproc[NR_PROCS]; sh_mp++) {
-
-	if (!(sh_mp->mp_flags & SEPARATE)) continue;
-	if (sh_mp == mp_ign) continue;
-	if (sh_mp->mp_ino != ino) continue;
-	if (sh_mp->mp_dev != dev) continue;
-	if (sh_mp->mp_ctime != ctime) continue;
-	return sh_mp;
-  }
-  return(NULL);
-}
Index: trunk/minix/servers/pm/forkexit.c
===================================================================
--- trunk/minix/servers/pm/forkexit.c	(revision 11)
+++ 	(revision )
@@ -1,312 +1,0 @@
-/* This file deals with creating processes (via FORK) and deleting them (via
- * EXIT/WAIT).  When a process forks, a new slot in the 'mproc' table is
- * allocated for it, and a copy of the parent's core image is made for the
- * child.  Then the kernel and file system are informed.  A process is removed
- * from the 'mproc' table when two events have occurred: (1) it has exited or
- * been killed by a signal, and (2) the parent has done a WAIT.  If the process
- * exits first, it continues to occupy a slot until the parent does a WAIT.
- *
- * The entry points into this file are:
- *   do_fork:	 perform the FORK system call
- *   do_pm_exit: perform the EXIT system call (by calling pm_exit())
- *   pm_exit:	 actually do the exiting
- *   do_wait:	 perform the WAITPID or WAIT system call
- */
-
-#include "pm.h"
-#include <sys/wait.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <sys/resource.h>
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-#define LAST_FEW            2	/* last few slots reserved for superuser */
-
-FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) );
-
-/*===========================================================================*
- *				do_fork					     *
- *===========================================================================*/
-PUBLIC int do_fork()
-{
-/* The process pointed to by 'mp' has forked.  Create a child process. */
-  register struct mproc *rmp;	/* pointer to parent */
-  register struct mproc *rmc;	/* pointer to child */
-  int child_nr, s;
-  phys_clicks prog_clicks, child_base;
-  phys_bytes prog_bytes, parent_abs, child_abs;	/* Intel only */
-  pid_t new_pid;
-  static int next_child;
-  int n = 0, r;
-
- /* If tables might fill up during FORK, don't even start since recovery half
-  * way through is such a nuisance.
-  */
-  rmp = mp;
-  if ((procs_in_use == NR_PROCS) || 
-  		(procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0))
-  {
-  	printf("PM: warning, process table is full!\n");
-  	return(EAGAIN);
-  }
-
-  /* Determine how much memory to allocate.  Only the data and stack need to
-   * be copied, because the text segment is either shared or of zero length.
-   */
-  prog_clicks = (phys_clicks) rmp->mp_seg[S].mem_len;
-  prog_clicks += (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
-  prog_bytes = (phys_bytes) prog_clicks << CLICK_SHIFT;
-  if ( (child_base = alloc_mem(prog_clicks)) == NO_MEM) return(ENOMEM);
-
-  /* Create a copy of the parent's core image for the child. */
-  child_abs = (phys_bytes) child_base << CLICK_SHIFT;
-  parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT;
-  s = sys_abscopy(parent_abs, child_abs, prog_bytes);
-  if (s < 0) panic(__FILE__,"do_fork can't copy", s);
-
-  /* Find a slot in 'mproc' for the child process.  A slot must exist. */
-  do {
-        next_child = (next_child+1) % NR_PROCS;
-	n++;
-  } while((mproc[next_child].mp_flags & IN_USE) && n <= NR_PROCS);
-  if(n > NR_PROCS)
-	panic(__FILE__,"do_fork can't find child slot", NO_NUM);
-  if(next_child < 0 || next_child >= NR_PROCS
- || (mproc[next_child].mp_flags & IN_USE))
-	panic(__FILE__,"do_fork finds wrong child slot", next_child);
-
-  rmc = &mproc[next_child];
-  /* Set up the child and its memory map; copy its 'mproc' slot from parent. */
-  child_nr = (int)(rmc - mproc);	/* slot number of the child */
-  procs_in_use++;
-  *rmc = *rmp;			/* copy parent's process slot to child's */
-  rmc->mp_parent = who_p;			/* record child's parent */
-  /* inherit only these flags */
-  rmc->mp_flags &= (IN_USE|SEPARATE|PRIV_PROC|DONT_SWAP);
-  rmc->mp_child_utime = 0;		/* reset administration */
-  rmc->mp_child_stime = 0;		/* reset administration */
-
-  /* A separate I&D child keeps the parents text segment.  The data and stack
-   * segments must refer to the new copy.
-   */
-  if (!(rmc->mp_flags & SEPARATE)) rmc->mp_seg[T].mem_phys = child_base;
-  rmc->mp_seg[D].mem_phys = child_base;
-  rmc->mp_seg[S].mem_phys = rmc->mp_seg[D].mem_phys + 
-			(rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
-  rmc->mp_exitstatus = 0;
-  rmc->mp_sigstatus = 0;
-
-  /* Find a free pid for the child and put it in the table. */
-  new_pid = get_free_pid();
-  rmc->mp_pid = new_pid;	/* assign pid to child */
-
-  /* Tell kernel and file system about the (now successful) FORK. */
-  if((r=sys_fork(who_e, child_nr, &rmc->mp_endpoint)) != OK) {
-  	panic(__FILE__,"do_fork can't sys_fork", r);
-  }
-  tell_fs(FORK, who_e, rmc->mp_endpoint, rmc->mp_pid);
-
-  /* Report child's memory map to kernel. */
-  if((r=sys_newmap(rmc->mp_endpoint, rmc->mp_seg)) != OK) {
-  	panic(__FILE__,"do_fork can't sys_newmap", r);
-  }
-
-  /* Reply to child to wake it up. */
-  setreply(child_nr, 0);		/* only parent gets details */
-  rmp->mp_reply.endpt = rmc->mp_endpoint;	/* child's process number */
-
-  return(new_pid);		 	/* child's pid */
-}
-
-/*===========================================================================*
- *				do_pm_exit				     *
- *===========================================================================*/
-PUBLIC int do_pm_exit()
-{
-/* Perform the exit(status) system call. The real work is done by pm_exit(),
- * which is also called when a process is killed by a signal.
- */
-  pm_exit(mp, m_in.status);
-  return(SUSPEND);		/* can't communicate from beyond the grave */
-}
-
-/*===========================================================================*
- *				pm_exit					     *
- *===========================================================================*/
-PUBLIC void pm_exit(rmp, exit_status)
-register struct mproc *rmp;	/* pointer to the process to be terminated */
-int exit_status;		/* the process' exit status (for parent) */
-{
-/* A process is done.  Release most of the process' possessions.  If its
- * parent is waiting, release the rest, else keep the process slot and
- * become a zombie.
- */
-  register int proc_nr, proc_nr_e;
-  int parent_waiting, right_child, r;
-  pid_t pidarg, procgrp;
-  struct mproc *p_mp;
-  clock_t t[5];
-
-  proc_nr = (int) (rmp - mproc);	/* get process slot number */
-  proc_nr_e = rmp->mp_endpoint;
-
-  /* Remember a session leader's process group. */
-  procgrp = (rmp->mp_pid == mp->mp_procgrp) ? mp->mp_procgrp : 0;
-
-  /* If the exited process has a timer pending, kill it. */
-  if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr_e, (unsigned) 0);
-
-  /* Do accounting: fetch usage times and accumulate at parent. */
-  if((r=sys_times(proc_nr_e, t)) != OK)
-  	panic(__FILE__,"pm_exit: sys_times failed", r);
-
-  p_mp = &mproc[rmp->mp_parent];			/* process' parent */
-  p_mp->mp_child_utime += t[0] + rmp->mp_child_utime;	/* add user time */
-  p_mp->mp_child_stime += t[1] + rmp->mp_child_stime;	/* add system time */
-
-  /* Tell the kernel the process is no longer runnable to prevent it from 
-   * being scheduled in between the following steps. Then tell FS that it 
-   * the process has exited and finally, clean up the process at the kernel.
-   * This order is important so that FS can tell drivers to cancel requests
-   * such as copying to/ from the exiting process, before it is gone.
-   */
-  sys_nice(proc_nr_e, PRIO_STOP);	/* stop the process */
-  if(proc_nr_e != FS_PROC_NR)		/* if it is not FS that is exiting.. */
-	tell_fs(EXIT, proc_nr_e, 0, 0);  	/* tell FS to free the slot */
-  else
-	printf("PM: FS died\n");
-  if((r=sys_exit(proc_nr_e)) != OK)	/* destroy the process */
-  	panic(__FILE__,"pm_exit: sys_exit failed", r);
-
-  /* Pending reply messages for the dead process cannot be delivered. */
-  rmp->mp_flags &= ~REPLY;
-  
-  /* Release the memory occupied by the child. */
-  if (find_share(rmp, rmp->mp_ino, rmp->mp_dev, rmp->mp_ctime) == NULL) {
-	/* No other process shares the text segment, so free it. */
-	free_mem(rmp->mp_seg[T].mem_phys, rmp->mp_seg[T].mem_len);
-  }
-  /* Free the data and stack segments. */
-  free_mem(rmp->mp_seg[D].mem_phys,
-      rmp->mp_seg[S].mem_vir 
-        + rmp->mp_seg[S].mem_len - rmp->mp_seg[D].mem_vir);
-
-  /* The process slot can only be freed if the parent has done a WAIT. */
-  rmp->mp_exitstatus = (char) exit_status;
-
-  pidarg = p_mp->mp_wpid;		/* who's being waited for? */
-  parent_waiting = p_mp->mp_flags & WAITING;
-  right_child =				/* child meets one of the 3 tests? */
-	(pidarg == -1 || pidarg == rmp->mp_pid || -pidarg == rmp->mp_procgrp);
-
-  if (parent_waiting && right_child) {
-	cleanup(rmp);			/* tell parent and release child slot */
-  } else {
-	rmp->mp_flags = IN_USE|ZOMBIE;	/* parent not waiting, zombify child */
-	sig_proc(p_mp, SIGCHLD);	/* send parent a "child died" signal */
-  }
-
-  /* If the process has children, disinherit them.  INIT is the new parent. */
-  for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-	if (rmp->mp_flags & IN_USE && rmp->mp_parent == proc_nr) {
-		/* 'rmp' now points to a child to be disinherited. */
-		rmp->mp_parent = INIT_PROC_NR;
-		parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
-		if (parent_waiting && (rmp->mp_flags & ZOMBIE)) cleanup(rmp);
-	}
-  }
-
-  /* Send a hangup to the process' process group if it was a session leader. */
-  if (procgrp != 0) check_sig(-procgrp, SIGHUP);
-}
-
-/*===========================================================================*
- *				do_waitpid				     *
- *===========================================================================*/
-PUBLIC int do_waitpid()
-{
-/* A process wants to wait for a child to terminate. If a child is already 
- * waiting, go clean it up and let this WAIT call terminate.  Otherwise, 
- * really wait. 
- * A process calling WAIT never gets a reply in the usual way at the end
- * of the main loop (unless WNOHANG is set or no qualifying child exists).
- * If a child has already exited, the routine cleanup() sends the reply
- * to awaken the caller.
- * Both WAIT and WAITPID are handled by this code.
- */
-  register struct mproc *rp;
-  int pidarg, options, children;
-
-  /* Set internal variables, depending on whether this is WAIT or WAITPID. */
-  pidarg  = (call_nr == WAIT ? -1 : m_in.pid);	   /* 1st param of waitpid */
-  options = (call_nr == WAIT ?  0 : m_in.sig_nr);  /* 3rd param of waitpid */
-  if (pidarg == 0) pidarg = -mp->mp_procgrp;	/* pidarg < 0 ==> proc grp */
-
-  /* Is there a child waiting to be collected? At this point, pidarg != 0:
-   *	pidarg  >  0 means pidarg is pid of a specific process to wait for
-   *	pidarg == -1 means wait for any child
-   *	pidarg  < -1 means wait for any child whose process group = -pidarg
-   */
-  children = 0;
-  for (rp = &mproc[0]; rp < &mproc[NR_PROCS]; rp++) {
-	if ( (rp->mp_flags & IN_USE) && rp->mp_parent == who_p) {
-		/* The value of pidarg determines which children qualify. */
-		if (pidarg  > 0 && pidarg != rp->mp_pid) continue;
-		if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue;
-
-		children++;		/* this child is acceptable */
-		if (rp->mp_flags & ZOMBIE) {
-			/* This child meets the pid test and has exited. */
-			cleanup(rp);	/* this child has already exited */
-			return(SUSPEND);
-		}
-		if ((rp->mp_flags & STOPPED) && rp->mp_sigstatus) {
-			/* This child meets the pid test and is being traced.*/
-			mp->mp_reply.reply_res2 = 0177|(rp->mp_sigstatus << 8);
-			rp->mp_sigstatus = 0;
-			return(rp->mp_pid);
-		}
-	}
-  }
-
-  /* No qualifying child has exited.  Wait for one, unless none exists. */
-  if (children > 0) {
-	/* At least 1 child meets the pid test exists, but has not exited. */
-	if (options & WNOHANG) return(0);    /* parent does not want to wait */
-	mp->mp_flags |= WAITING;	     /* parent wants to wait */
-	mp->mp_wpid = (pid_t) pidarg;	     /* save pid for later */
-	return(SUSPEND);		     /* do not reply, let it wait */
-  } else {
-	/* No child even meets the pid test.  Return error immediately. */
-	return(ECHILD);			     /* no - parent has no children */
-  }
-}
-
-/*===========================================================================*
- *				cleanup					     *
- *===========================================================================*/
-PRIVATE void cleanup(child)
-register struct mproc *child;	/* tells which process is exiting */
-{
-/* Finish off the exit of a process.  The process has exited or been killed
- * by a signal, and its parent is waiting.
- */
-  struct mproc *parent = &mproc[child->mp_parent];
-  int exitstatus;
-
-  /* Wake up the parent by sending the reply message. */
-  exitstatus = (child->mp_exitstatus << 8) | (child->mp_sigstatus & 0377);
-  parent->mp_reply.reply_res2 = exitstatus;
-  setreply(child->mp_parent, child->mp_pid);
-  parent->mp_flags &= ~WAITING;		/* parent no longer waiting */
-
-  /* Release the process table entry and reinitialize some field. */
-  child->mp_pid = 0;
-  child->mp_flags = 0;
-  child->mp_child_utime = 0;
-  child->mp_child_stime = 0;
-  procs_in_use--;
-}
-
Index: trunk/minix/servers/pm/getset.c
===================================================================
--- trunk/minix/servers/pm/getset.c	(revision 11)
+++ 	(revision )
@@ -1,83 +1,0 @@
-/* This file handles the 4 system calls that get and set uids and gids.
- * It also handles getpid(), setsid(), and getpgrp().  The code for each
- * one is so tiny that it hardly seemed worthwhile to make each a separate
- * function.
- */
-
-#include "pm.h"
-#include <minix/callnr.h>
-#include <minix/endpoint.h>
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-/*===========================================================================*
- *				do_getset				     *
- *===========================================================================*/
-PUBLIC int do_getset()
-{
-/* Handle GETUID, GETGID, GETPID, GETPGRP, SETUID, SETGID, SETSID.  The four
- * GETs and SETSID return their primary results in 'r'.  GETUID, GETGID, and
- * GETPID also return secondary results (the effective IDs, or the parent
- * process ID) in 'reply_res2', which is returned to the user.
- */
-
-  register struct mproc *rmp = mp;
-  int r, proc;
-
-  switch(call_nr) {
-	case GETUID:
-		r = rmp->mp_realuid;
-		rmp->mp_reply.reply_res2 = rmp->mp_effuid;
-		break;
-
-	case GETGID:
-		r = rmp->mp_realgid;
-		rmp->mp_reply.reply_res2 = rmp->mp_effgid;
-		break;
-
-	case GETPID:
-		r = mproc[who_p].mp_pid;
-		rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid;
-		if(pm_isokendpt(m_in.endpt, &proc) == OK && proc >= 0)
-			rmp->mp_reply.reply_res3 = mproc[proc].mp_pid;
-		break;
-
-	case SETEUID:
-	case SETUID:
-		if (rmp->mp_realuid != (uid_t) m_in.usr_id && 
-				rmp->mp_effuid != SUPER_USER)
-			return(EPERM);
-		if(call_nr == SETUID) rmp->mp_realuid = (uid_t) m_in.usr_id;
-		rmp->mp_effuid = (uid_t) m_in.usr_id;
-		tell_fs(SETUID, who_e, rmp->mp_realuid, rmp->mp_effuid);
-		r = OK;
-		break;
-
-	case SETEGID:
-	case SETGID:
-		if (rmp->mp_realgid != (gid_t) m_in.grp_id && 
-				rmp->mp_effuid != SUPER_USER)
-			return(EPERM);
-		if(call_nr == SETGID) rmp->mp_realgid = (gid_t) m_in.grp_id;
-		rmp->mp_effgid = (gid_t) m_in.grp_id;
-		tell_fs(SETGID, who_e, rmp->mp_realgid, rmp->mp_effgid);
-		r = OK;
-		break;
-
-	case SETSID:
-		if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM);
-		rmp->mp_procgrp = rmp->mp_pid;
-		tell_fs(SETSID, who_e, 0, 0);
-		/* fall through */
-
-	case GETPGRP:
-		r = rmp->mp_procgrp;
-		break;
-
-	default:
-		r = EINVAL;
-		break;	
-  }
-  return(r);
-}
Index: trunk/minix/servers/pm/glo.h
===================================================================
--- trunk/minix/servers/pm/glo.h	(revision 11)
+++ 	(revision )
@@ -1,22 +1,0 @@
-/* EXTERN should be extern except in table.c */
-#ifdef _TABLE
-#undef EXTERN
-#define EXTERN
-#endif
-
-/* Global variables. */
-EXTERN struct mproc *mp;	/* ptr to 'mproc' slot of current process */
-EXTERN int procs_in_use;	/* how many processes are marked as IN_USE */
-EXTERN char monitor_params[128*sizeof(char *)];	/* boot monitor parameters */
-EXTERN struct kinfo kinfo;	/* kernel information */
-
-/* The parameters of the call are kept here. */
-EXTERN message m_in;		/* the incoming message itself is kept here. */
-EXTERN int who_p, who_e;	/* caller's proc number, endpoint */
-EXTERN int call_nr;		/* system call number */
-
-extern _PROTOTYPE (int (*call_vec[]), (void) );	/* system call handlers */
-extern char core_name[];	/* file name where core images are produced */
-EXTERN sigset_t core_sset;	/* which signals cause core images */
-EXTERN sigset_t ign_sset;	/* which signals are by default ignored */
-
Index: trunk/minix/servers/pm/main.c
===================================================================
--- trunk/minix/servers/pm/main.c	(revision 11)
+++ 	(revision )
@@ -1,472 +1,0 @@
-/* This file contains the main program of the process manager and some related
- * procedures.  When MINIX starts up, the kernel runs for a little while,
- * initializing itself and its tasks, and then it runs PM and FS.  Both PM
- * and FS initialize themselves as far as they can. PM asks the kernel for
- * all free memory and starts serving requests.
- *
- * The entry points into this file are:
- *   main:	starts PM running
- *   setreply:	set the reply to be sent to process making an PM system call
- */
-
-#include "pm.h"
-#include <minix/keymap.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/resource.h>
-#include <string.h>
-#include "mproc.h"
-#include "param.h"
-
-#include "../../kernel/const.h"
-#include "../../kernel/config.h"
-#include "../../kernel/type.h"
-#include "../../kernel/proc.h"
-
-FORWARD _PROTOTYPE( void get_work, (void)				);
-FORWARD _PROTOTYPE( void pm_init, (void)				);
-FORWARD _PROTOTYPE( int get_nice_value, (int queue)			);
-FORWARD _PROTOTYPE( void get_mem_chunks, (struct memory *mem_chunks) 	);
-FORWARD _PROTOTYPE( void patch_mem_chunks, (struct memory *mem_chunks, 
-	struct mem_map *map_ptr) 	);
-FORWARD _PROTOTYPE( void do_x86_vm, (struct memory mem_chunks[NR_MEMS])	);
-
-#define click_to_round_k(n) \
-	((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
-
-/*===========================================================================*
- *				main					     *
- *===========================================================================*/
-PUBLIC int main()
-{
-/* Main routine of the process manager. */
-  int result, s, proc_nr;
-  struct mproc *rmp;
-  sigset_t sigset;
-
-  pm_init();			/* initialize process manager tables */
-
-  /* This is PM's main loop-  get work and do it, forever and forever. */
-  while (TRUE) {
-	get_work();		/* wait for an PM system call */
-
-	/* Check for system notifications first. Special cases. */
-	if (call_nr == SYN_ALARM) {
-		pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
-		result = SUSPEND;		/* don't reply */
-	} else if (call_nr == SYS_SIG) {	/* signals pending */
-		sigset = m_in.NOTIFY_ARG;
-		if (sigismember(&sigset, SIGKSIG))  {
-			(void) ksig_pending();
-		} 
-		result = SUSPEND;		/* don't reply */
-	}
-	/* Else, if the system call number is valid, perform the call. */
-	else if ((unsigned) call_nr >= NCALLS) {
-		result = ENOSYS;
-	} else {
-		result = (*call_vec[call_nr])();
-	}
-
-	/* Send the results back to the user to indicate completion. */
-	if (result != SUSPEND) setreply(who_p, result);
-
-	swap_in();		/* maybe a process can be swapped in? */
-
-	/* Send out all pending reply messages, including the answer to
-	 * the call just made above.  The processes must not be swapped out.
-	 */
-	for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
-		/* In the meantime, the process may have been killed by a
-		 * signal (e.g. if a lethal pending signal was unblocked)
-		 * without the PM realizing it. If the slot is no longer in
-		 * use or just a zombie, don't try to reply.
-		 */
-		if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) ==
-		   (REPLY | IN_USE)) {
-			if ((s=send(rmp->mp_endpoint, &rmp->mp_reply)) != OK) {
-				printf("PM can't reply to %d (%s)\n",
-					rmp->mp_endpoint, rmp->mp_name);
-				panic(__FILE__, "PM can't reply", NO_NUM);
-			}
-			rmp->mp_flags &= ~REPLY;
-		}
-	}
-  }
-  return(OK);
-}
-
-/*===========================================================================*
- *				get_work				     *
- *===========================================================================*/
-PRIVATE void get_work()
-{
-/* Wait for the next message and extract useful information from it. */
-  if (receive(ANY, &m_in) != OK)
-	panic(__FILE__,"PM receive error", NO_NUM);
-  who_e = m_in.m_source;	/* who sent the message */
-  if(pm_isokendpt(who_e, &who_p) != OK)
-	panic(__FILE__, "PM got message from invalid endpoint", who_e);
-  call_nr = m_in.m_type;	/* system call number */
-
-  /* Process slot of caller. Misuse PM's own process slot if the kernel is
-   * calling. This can happen in case of synchronous alarms (CLOCK) or or 
-   * event like pending kernel signals (SYSTEM).
-   */
-  mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
-  if(who_p >= 0 && mp->mp_endpoint != who_e) {
-	panic(__FILE__, "PM endpoint number out of sync with source",
-		mp->mp_endpoint);
-  }
-}
-
-/*===========================================================================*
- *				setreply				     *
- *===========================================================================*/
-PUBLIC void setreply(proc_nr, result)
-int proc_nr;			/* process to reply to */
-int result;			/* result of call (usually OK or error #) */
-{
-/* Fill in a reply message to be sent later to a user process.  System calls
- * may occasionally fill in other fields, this is only for the main return
- * value, and for setting the "must send reply" flag.
- */
-  register struct mproc *rmp = &mproc[proc_nr];
-
-  if(proc_nr < 0 || proc_nr >= NR_PROCS)
-      panic(__FILE__,"setreply arg out of range", proc_nr);
-
-  rmp->mp_reply.reply_res = result;
-  rmp->mp_flags |= REPLY;	/* reply pending */
-
-  if (rmp->mp_flags & ONSWAP)
-	swap_inqueue(rmp);	/* must swap this process back in */
-}
-
-/*===========================================================================*
- *				pm_init					     *
- *===========================================================================*/
-PRIVATE void pm_init()
-{
-/* Initialize the process manager. 
- * Memory use info is collected from the boot monitor, the kernel, and
- * all processes compiled into the system image. Initially this information
- * is put into an array mem_chunks. Elements of mem_chunks are struct memory,
- * and hold base, size pairs in units of clicks. This array is small, there
- * should be no more than 8 chunks. After the array of chunks has been built
- * the contents are used to initialize the hole list. Space for the hole list
- * is reserved as an array with twice as many elements as the maximum number
- * of processes allowed. It is managed as a linked list, and elements of the
- * array are struct hole, which, in addition to storage for a base and size in 
- * click units also contain space for a link, a pointer to another element.
-*/
-  int s;
-  static struct boot_image image[NR_BOOT_PROCS];
-  register struct boot_image *ip;
-  static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
-			SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };
-  static char ign_sigs[] = { SIGCHLD, SIGWINCH, SIGCONT };
-  static char mess_sigs[] = { SIGTERM, SIGHUP, SIGABRT, SIGQUIT };
-  register struct mproc *rmp;
-  register int i;
-  register char *sig_ptr;
-  phys_clicks total_clicks, minix_clicks, free_clicks;
-  message mess;
-  struct mem_map mem_map[NR_LOCAL_SEGS];
-  struct memory mem_chunks[NR_MEMS];
-
-  /* Initialize process table, including timers. */
-  for (rmp=&mproc[0]; rmp<&mproc[NR_PROCS]; rmp++) {
-	tmr_inittimer(&rmp->mp_timer);
-  }
-
-  /* Build the set of signals which cause core dumps, and the set of signals
-   * that are by default ignored.
-   */
-  sigemptyset(&core_sset);
-  for (sig_ptr = core_sigs; sig_ptr < core_sigs+sizeof(core_sigs); sig_ptr++)
-	sigaddset(&core_sset, *sig_ptr);
-  sigemptyset(&ign_sset);
-  for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++)
-	sigaddset(&ign_sset, *sig_ptr);
-
-  /* Obtain a copy of the boot monitor parameters and the kernel info struct.  
-   * Parse the list of free memory chunks. This list is what the boot monitor 
-   * reported, but it must be corrected for the kernel and system processes.
-   */
-  if ((s=sys_getmonparams(monitor_params, sizeof(monitor_params))) != OK)
-      panic(__FILE__,"get monitor params failed",s);
-  get_mem_chunks(mem_chunks);
-  if ((s=sys_getkinfo(&kinfo)) != OK)
-      panic(__FILE__,"get kernel info failed",s);
-
-  /* Get the memory map of the kernel to see how much memory it uses. */
-  if ((s=get_mem_map(SYSTASK, mem_map)) != OK)
-  	panic(__FILE__,"couldn't get memory map of SYSTASK",s);
-  minix_clicks = (mem_map[S].mem_phys+mem_map[S].mem_len)-mem_map[T].mem_phys;
-  patch_mem_chunks(mem_chunks, mem_map);
-
-  /* Initialize PM's process table. Request a copy of the system image table 
-   * that is defined at the kernel level to see which slots to fill in.
-   */
-  if (OK != (s=sys_getimage(image))) 
-  	panic(__FILE__,"couldn't get image table: %d\n", s);
-  procs_in_use = 0;				/* start populating table */
-  printf("Building process table:");		/* show what's happening */
-  for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) {		
-  	if (ip->proc_nr >= 0) {			/* task have negative nrs */
-  		procs_in_use += 1;		/* found user process */
-
-		/* Set process details found in the image table. */
-		rmp = &mproc[ip->proc_nr];	
-  		strncpy(rmp->mp_name, ip->proc_name, PROC_NAME_LEN); 
-		rmp->mp_parent = RS_PROC_NR;
-		rmp->mp_nice = get_nice_value(ip->priority);
-  		sigemptyset(&rmp->mp_sig2mess);
-  		sigemptyset(&rmp->mp_ignore);	
-  		sigemptyset(&rmp->mp_sigmask);
-  		sigemptyset(&rmp->mp_catch);
-		if (ip->proc_nr == INIT_PROC_NR) {	/* user process */
-  			rmp->mp_procgrp = rmp->mp_pid = INIT_PID;
-			rmp->mp_flags |= IN_USE; 
-		}
-		else {					/* system process */
-  			rmp->mp_pid = get_free_pid();
-			rmp->mp_flags |= IN_USE | DONT_SWAP | PRIV_PROC; 
-  			for (sig_ptr = mess_sigs; 
-				sig_ptr < mess_sigs+sizeof(mess_sigs); 
-				sig_ptr++)
-			sigaddset(&rmp->mp_sig2mess, *sig_ptr);
-		}
-
-		/* Get kernel endpoint identifier. */
-		rmp->mp_endpoint = ip->endpoint;
-
-  		/* Get memory map for this process from the kernel. */
-		if ((s=get_mem_map(ip->proc_nr, rmp->mp_seg)) != OK)
-  			panic(__FILE__,"couldn't get process entry",s);
-		if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
-		minix_clicks += rmp->mp_seg[S].mem_phys + 
-			rmp->mp_seg[S].mem_len - rmp->mp_seg[T].mem_phys;
-  		patch_mem_chunks(mem_chunks, rmp->mp_seg);
-
-		/* Tell FS about this system process. */
-		mess.PR_SLOT = ip->proc_nr;
-		mess.PR_PID = rmp->mp_pid;
-		mess.PR_ENDPT = rmp->mp_endpoint;
-  		if (OK != (s=send(FS_PROC_NR, &mess)))
-			panic(__FILE__,"can't sync up with FS", s);
-  		printf(" %s", ip->proc_name);	/* display process name */
-  	}
-  }
-  printf(".\n");				/* last process done */
-
-  /* Override some details. INIT, PM, FS and RS are somewhat special. */
-  mproc[PM_PROC_NR].mp_pid = PM_PID;		/* PM has magic pid */
-  mproc[RS_PROC_NR].mp_parent = INIT_PROC_NR;	/* INIT is root */
-  sigfillset(&mproc[PM_PROC_NR].mp_ignore); 	/* guard against signals */
-
-  /* Tell FS that no more system processes follow and synchronize. */
-  mess.PR_ENDPT = NONE;
-  if (sendrec(FS_PROC_NR, &mess) != OK || mess.m_type != OK)
-	panic(__FILE__,"can't sync up with FS", NO_NUM);
-
-#if ENABLE_BOOTDEV
-  /* Possibly we must correct the memory chunks for the boot device. */
-  if (kinfo.bootdev_size > 0) {
-      mem_map[T].mem_phys = kinfo.bootdev_base >> CLICK_SHIFT;
-      mem_map[T].mem_len = 0;
-      mem_map[D].mem_len = (kinfo.bootdev_size+CLICK_SIZE-1) >> CLICK_SHIFT;
-      patch_mem_chunks(mem_chunks, mem_map);
-  }
-#endif /* ENABLE_BOOTDEV */
-
-  /* Withhold some memory from x86 VM */
-  do_x86_vm(mem_chunks);
-
-  /* Initialize tables to all physical memory and print memory information. */
-  printf("Physical memory:");
-  mem_init(mem_chunks, &free_clicks);
-  total_clicks = minix_clicks + free_clicks;
-  printf(" total %u KB,", click_to_round_k(total_clicks));
-  printf(" system %u KB,", click_to_round_k(minix_clicks));
-  printf(" free %u KB.\n", click_to_round_k(free_clicks));
-}
-
-/*===========================================================================*
- *				get_nice_value				     *
- *===========================================================================*/
-PRIVATE int get_nice_value(queue)
-int queue;				/* store mem chunks here */
-{
-/* Processes in the boot image have a priority assigned. The PM doesn't know
- * about priorities, but uses 'nice' values instead. The priority is between 
- * MIN_USER_Q and MAX_USER_Q. We have to scale between PRIO_MIN and PRIO_MAX.
- */ 
-  int nice_val = (queue - USER_Q) * (PRIO_MAX-PRIO_MIN+1) / 
-      (MIN_USER_Q-MAX_USER_Q+1);
-  if (nice_val > PRIO_MAX) nice_val = PRIO_MAX;	/* shouldn't happen */
-  if (nice_val < PRIO_MIN) nice_val = PRIO_MIN;	/* shouldn't happen */
-  return nice_val;
-}
-
-#if _WORD_SIZE == 2
-/* In real mode only 1M can be addressed, and in 16-bit protected we can go
- * no further than we can count in clicks.  (The 286 is further limited by
- * its 24 bit address bus, but we can assume in that case that no more than
- * 16M memory is reported by the BIOS.)
- */
-#define MAX_REAL	0x00100000L
-#define MAX_16BIT	(0xFFF0L << CLICK_SHIFT)
-#endif
-
-/*===========================================================================*
- *				get_mem_chunks				     *
- *===========================================================================*/
-PRIVATE void get_mem_chunks(mem_chunks)
-struct memory *mem_chunks;			/* store mem chunks here */
-{
-/* Initialize the free memory list from the 'memory' boot variable.  Translate
- * the byte offsets and sizes in this list to clicks, properly truncated. Also
- * make sure that we don't exceed the maximum address space of the 286 or the
- * 8086, i.e. when running in 16-bit protected mode or real mode.
- */
-  long base, size, limit;
-  char *s, *end;			/* use to parse boot variable */ 
-  int i, done = 0;
-  struct memory *memp;
-#if _WORD_SIZE == 2
-  unsigned long max_address;
-  struct machine machine;
-  if (OK != (i=sys_getmachine(&machine)))
-	panic(__FILE__, "sys_getmachine failed", i);
-#endif
-
-  /* Initialize everything to zero. */
-  for (i = 0; i < NR_MEMS; i++) {
-	memp = &mem_chunks[i];		/* next mem chunk is stored here */
-	memp->base = memp->size = 0;
-  }
-  
-  /* The available memory is determined by MINIX' boot loader as a list of 
-   * (base:size)-pairs in boothead.s. The 'memory' boot variable is set in
-   * in boot.s.  The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem,
-   * b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1 
-   * and b2:s2 are combined if the memory is adjacent. 
-   */
-  s = find_param("memory");		/* get memory boot variable */
-  for (i = 0; i < NR_MEMS && !done; i++) {
-	memp = &mem_chunks[i];		/* next mem chunk is stored here */
-	base = size = 0;		/* initialize next base:size pair */
-	if (*s != 0) {			/* get fresh data, unless at end */	
-
-	    /* Read fresh base and expect colon as next char. */ 
-	    base = strtoul(s, &end, 0x10);		/* get number */
-	    if (end != s && *end == ':') s = ++end;	/* skip ':' */ 
-	    else *s=0;			/* terminate, should not happen */
-
-	    /* Read fresh size and expect comma or assume end. */ 
-	    size = strtoul(s, &end, 0x10);		/* get number */
-	    if (end != s && *end == ',') s = ++end;	/* skip ',' */
-	    else done = 1;
-	}
-	limit = base + size;	
-#if _WORD_SIZE == 2
-	max_address = machine.protected ? MAX_16BIT : MAX_REAL;
-	if (limit > max_address) limit = max_address;
-#endif
-	base = (base + CLICK_SIZE-1) & ~(long)(CLICK_SIZE-1);
-	limit &= ~(long)(CLICK_SIZE-1);
-	if (limit <= base) continue;
-	memp->base = base >> CLICK_SHIFT;
-	memp->size = (limit - base) >> CLICK_SHIFT;
-  }
-}
-
-/*===========================================================================*
- *				patch_mem_chunks			     *
- *===========================================================================*/
-PRIVATE void patch_mem_chunks(mem_chunks, map_ptr)
-struct memory *mem_chunks;			/* store mem chunks here */
-struct mem_map *map_ptr;			/* memory to remove */
-{
-/* Remove server memory from the free memory list. The boot monitor
- * promises to put processes at the start of memory chunks. The 
- * tasks all use same base address, so only the first task changes
- * the memory lists. The servers and init have their own memory
- * spaces and their memory will be removed from the list. 
- */
-  struct memory *memp;
-  for (memp = mem_chunks; memp < &mem_chunks[NR_MEMS]; memp++) {
-	if (memp->base == map_ptr[T].mem_phys) {
-		memp->base += map_ptr[T].mem_len + map_ptr[D].mem_len;
-		memp->size -= map_ptr[T].mem_len + map_ptr[D].mem_len;
-	}
-  }
-}
-
-#define PAGE_SIZE	4096
-#define PAGE_TABLE_COVER (1024*PAGE_SIZE)
-/*=========================================================================*
- *				do_x86_vm				   *
- *=========================================================================*/
-PRIVATE void do_x86_vm(mem_chunks)
-struct memory mem_chunks[NR_MEMS];
-{
-	phys_bytes high, bytes;
-	phys_clicks clicks, base_click;
-	unsigned pages;
-	int i, r;
-
-	/* Compute the highest memory location */
-	high= 0;
-	for (i= 0; i<NR_MEMS; i++)
-	{
-		if (mem_chunks[i].size == 0)
-			continue;
-		if (mem_chunks[i].base + mem_chunks[i].size > high)
-			high= mem_chunks[i].base + mem_chunks[i].size;
-	}
-
-	high <<= CLICK_SHIFT;
-#if VERBOSE_VM
-	printf("do_x86_vm: found high 0x%x\n", high);
-#endif
-
-	/* The number of pages we need is one for the page directory, enough
-	 * page tables to cover the memory, and one page for alignement.
-	 */
-	pages= 1 + (high + PAGE_TABLE_COVER-1)/PAGE_TABLE_COVER + 1;
-	bytes= pages*PAGE_SIZE;
-	clicks= (bytes + CLICK_SIZE-1) >> CLICK_SHIFT;
-
-#if VERBOSE_VM
-	printf("do_x86_vm: need %d pages\n", pages);
-	printf("do_x86_vm: need %d bytes\n", bytes);
-	printf("do_x86_vm: need %d clicks\n", clicks);
-#endif
-
-	for (i= 0; i<NR_MEMS; i++)
-	{
-		if (mem_chunks[i].size <= clicks)
-			continue;
-		break;
-	}
-	if (i >= NR_MEMS)
-		panic("PM", "not enough memory for VM page tables?", NO_NUM);
-	base_click= mem_chunks[i].base;
-	mem_chunks[i].base += clicks;
-	mem_chunks[i].size -= clicks;
-
-#if VERBOSE_VM
-	printf("do_x86_vm: using 0x%x clicks @ 0x%x\n", clicks, base_click);
-#endif
-	r= sys_vm_setbuf(base_click << CLICK_SHIFT, clicks << CLICK_SHIFT,
-		high);
-	if (r != 0)
-		printf("do_x86_vm: sys_vm_setbuf failed: %d\n", r);
-}
Index: trunk/minix/servers/pm/misc.c
===================================================================
--- trunk/minix/servers/pm/misc.c	(revision 11)
+++ 	(revision )
@@ -1,434 +1,0 @@
-/* Miscellaneous system calls.				Author: Kees J. Bot
- *								31 Mar 2000
- * The entry points into this file are:
- *   do_reboot: kill all processes, then reboot system
- *   do_procstat: request process status  (Jorrit N. Herder)
- *   do_getsysinfo: request copy of PM data structure  (Jorrit N. Herder)
- *   do_getprocnr: lookup process slot number  (Jorrit N. Herder)
- *   do_allocmem: allocate a chunk of memory  (Jorrit N. Herder)
- *   do_freemem: deallocate a chunk of memory  (Jorrit N. Herder)
- *   do_getsetpriority: get/set process priority
- *   do_svrctl: process manager control
- */
-
-#include "pm.h"
-#include <minix/callnr.h>
-#include <signal.h>
-#include <sys/svrctl.h>
-#include <sys/resource.h>
-#include <minix/com.h>
-#include <minix/config.h>
-#include <minix/type.h>
-#include <string.h>
-#include <lib.h>
-#include "mproc.h"
-#include "param.h"
-#include "../../kernel/proc.h"
-
-/*===========================================================================*
- *				do_allocmem				     *
- *===========================================================================*/
-PUBLIC int do_allocmem()
-{
-  vir_clicks mem_clicks;
-  phys_clicks mem_base;
-
-  mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT;
-  mem_base = alloc_mem(mem_clicks);
-  if (mem_base == NO_MEM) return(ENOMEM);
-  mp->mp_reply.membase =  (phys_bytes) (mem_base << CLICK_SHIFT);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_freemem				     *
- *===========================================================================*/
-PUBLIC int do_freemem()
-{
-  vir_clicks mem_clicks;
-  phys_clicks mem_base;
-
-  mem_clicks = (m_in.memsize + CLICK_SIZE -1 ) >> CLICK_SHIFT;
-  mem_base = (m_in.membase + CLICK_SIZE -1 ) >> CLICK_SHIFT;
-  free_mem(mem_base, mem_clicks);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_procstat				     *
- *===========================================================================*/
-PUBLIC int do_procstat()
-{ 
-  /* For the moment, this is only used to return pending signals to 
-   * system processes that request the PM for their own status. 
-   *
-   * Future use might include the FS requesting for process status of
-   * any user process. 
-   */
-  if (m_in.stat_nr == SELF) {
-      mp->mp_reply.sig_set = mp->mp_sigpending;
-      sigemptyset(&mp->mp_sigpending);
-  } 
-  else {
-      return(ENOSYS);
-  }
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_getsysinfo			       	     *
- *===========================================================================*/
-PUBLIC int do_getsysinfo()
-{
-  struct mproc *proc_addr;
-  vir_bytes src_addr, dst_addr;
-  struct kinfo kinfo;
-  struct loadinfo loadinfo;
-  static struct proc proctab[NR_PROCS+NR_TASKS];
-  size_t len;
-  static struct pm_mem_info pmi;
-  int s, r;
-  size_t holesize;
-
-  switch(m_in.info_what) {
-  case SI_KINFO:			/* kernel info is obtained via PM */
-        sys_getkinfo(&kinfo);
-        src_addr = (vir_bytes) &kinfo;
-        len = sizeof(struct kinfo);
-        break;
-  case SI_PROC_ADDR:			/* get address of PM process table */
-  	proc_addr = &mproc[0];
-  	src_addr = (vir_bytes) &proc_addr;
-  	len = sizeof(struct mproc *);
-  	break; 
-  case SI_PROC_TAB:			/* copy entire process table */
-        src_addr = (vir_bytes) mproc;
-        len = sizeof(struct mproc) * NR_PROCS;
-        break;
-  case SI_KPROC_TAB:			/* copy entire process table */
-	if((r=sys_getproctab(proctab)) != OK)
-		return r;
-	src_addr = (vir_bytes) proctab;
-	len = sizeof(proctab);
-        break;
-  case SI_MEM_ALLOC:
-  	holesize = sizeof(pmi.pmi_holes);
-	if((r=mem_holes_copy(pmi.pmi_holes, &holesize,
-	   &pmi.pmi_hi_watermark)) != OK)
-		return r;
-	src_addr = (vir_bytes) &pmi;
-	len = sizeof(pmi);
-	break;
-  case SI_LOADINFO:			/* loadinfo is obtained via PM */
-        sys_getloadinfo(&loadinfo);
-        src_addr = (vir_bytes) &loadinfo;
-        len = sizeof(struct loadinfo);
-        break;
-  default:
-  	return(EINVAL);
-  }
-
-  dst_addr = (vir_bytes) m_in.info_where;
-  if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len)))
-  	return(s);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_getprocnr			             *
- *===========================================================================*/
-PUBLIC int do_getprocnr()
-{
-  register struct mproc *rmp;
-  static char search_key[PROC_NAME_LEN+1];
-  int key_len;
-  int s;
-
-  if (m_in.pid >= 0) {			/* lookup process by pid */
-  	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-		if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) {
-  			mp->mp_reply.endpt = rmp->mp_endpoint;
-  			return(OK);
-		} 
-	}
-  	return(ESRCH);			
-  } else if (m_in.namelen > 0) {	/* lookup process by name */
-  	key_len = MIN(m_in.namelen, PROC_NAME_LEN);
- 	if (OK != (s=sys_datacopy(who_e, (vir_bytes) m_in.addr, 
- 			SELF, (vir_bytes) search_key, key_len))) 
- 		return(s);
- 	search_key[key_len] = '\0';	/* terminate for safety */
-  	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-		if (((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE) && 
-			strncmp(rmp->mp_name, search_key, key_len)==0) {
-  			mp->mp_reply.endpt = rmp->mp_endpoint;
-  			return(OK);
-		} 
-	}
-  	return(ESRCH);			
-  } else {			/* return own/parent process number */
-  	mp->mp_reply.endpt = who_e;
-	mp->mp_reply.pendpt = mproc[mp->mp_parent].mp_endpoint;
-  }
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_reboot				     *
- *===========================================================================*/
-PUBLIC int do_reboot()
-{
-  char monitor_code[256];		
-  vir_bytes code_addr;
-  int code_size;
-  int abort_flag;
-
-  /* Check permission to abort the system. */
-  if (mp->mp_effuid != SUPER_USER) return(EPERM);
-
-  /* See how the system should be aborted. */
-  abort_flag = (unsigned) m_in.reboot_flag;
-  if (abort_flag >= RBT_INVALID) return(EINVAL); 
-  if (RBT_MONITOR == abort_flag) {
-	int r;
-	if(m_in.reboot_strlen >= sizeof(monitor_code))
-		return EINVAL;
-	if((r = sys_datacopy(who_e, (vir_bytes) m_in.reboot_code,
-		SELF, (vir_bytes) monitor_code, m_in.reboot_strlen)) != OK)
-		return r;
-	code_addr = (vir_bytes) monitor_code;
-	monitor_code[m_in.reboot_strlen] = '\0';
-	code_size = m_in.reboot_strlen + 1;
-  }
-
-  /* Order matters here. When FS is told to reboot, it exits all its
-   * processes, and then would be confused if they're exited again by
-   * SIGKILL. So first kill, then reboot. 
-   */
-
-  check_sig(-1, SIGKILL); 		/* kill all users except init */
-  sys_nice(INIT_PROC_NR, PRIO_STOP);	/* stop init, but keep it around */
-  tell_fs(REBOOT, 0, 0, 0);		/* tell FS to synchronize */
-
-  /* Ask the kernel to abort. All system services, including the PM, will 
-   * get a HARD_STOP notification. Await the notification in the main loop.
-   */
-  sys_abort(abort_flag, PM_PROC_NR, code_addr, code_size);
-  return(SUSPEND);			/* don't reply to caller */
-}
-
-/*===========================================================================*
- *				do_getsetpriority			     *
- *===========================================================================*/
-PUBLIC int do_getsetpriority()
-{
-	int arg_which, arg_who, arg_pri;
-	int rmp_nr;
-	struct mproc *rmp;
-
-	arg_which = m_in.m1_i1;
-	arg_who = m_in.m1_i2;
-	arg_pri = m_in.m1_i3;	/* for SETPRIORITY */
-
-	/* Code common to GETPRIORITY and SETPRIORITY. */
-
-	/* Only support PRIO_PROCESS for now. */
-	if (arg_which != PRIO_PROCESS)
-		return(EINVAL);
-
-	if (arg_who == 0)
-		rmp_nr = who_p;
-	else
-		if ((rmp_nr = proc_from_pid(arg_who)) < 0)
-			return(ESRCH);
-
-	rmp = &mproc[rmp_nr];
-
-	if (mp->mp_effuid != SUPER_USER &&
-	   mp->mp_effuid != rmp->mp_effuid && mp->mp_effuid != rmp->mp_realuid)
-		return EPERM;
-
-	/* If GET, that's it. */
-	if (call_nr == GETPRIORITY) {
-		return(rmp->mp_nice - PRIO_MIN);
-	}
-
-	/* Only root is allowed to reduce the nice level. */
-	if (rmp->mp_nice > arg_pri && mp->mp_effuid != SUPER_USER)
-		return(EACCES);
-	
-	/* We're SET, and it's allowed. Do it and tell kernel. */
-	rmp->mp_nice = arg_pri;
-	return sys_nice(rmp->mp_endpoint, arg_pri);
-}
-
-/*===========================================================================*
- *				do_svrctl				     *
- *===========================================================================*/
-PUBLIC int do_svrctl()
-{
-  int s, req;
-  vir_bytes ptr;
-#define MAX_LOCAL_PARAMS 2
-  static struct {
-  	char name[30];
-  	char value[30];
-  } local_param_overrides[MAX_LOCAL_PARAMS];
-  static int local_params = 0;
-
-  req = m_in.svrctl_req;
-  ptr = (vir_bytes) m_in.svrctl_argp;
-
-  /* Is the request indeed for the MM? */
-  if (((req >> 8) & 0xFF) != 'M') return(EINVAL);
-
-  /* Control operations local to the PM. */
-  switch(req) {
-  case MMSETPARAM:
-  case MMGETPARAM: {
-      struct sysgetenv sysgetenv;
-      char search_key[64];
-      char *val_start;
-      size_t val_len;
-      size_t copy_len;
-
-      /* Copy sysgetenv structure to PM. */
-      if (sys_datacopy(who_e, ptr, SELF, (vir_bytes) &sysgetenv, 
-              sizeof(sysgetenv)) != OK) return(EFAULT);  
-
-      /* Set a param override? */
-      if (req == MMSETPARAM) {
-  	if (local_params >= MAX_LOCAL_PARAMS) return ENOSPC;
-  	if (sysgetenv.keylen <= 0
-  	 || sysgetenv.keylen >=
-  	 	 sizeof(local_param_overrides[local_params].name)
-  	 || sysgetenv.vallen <= 0
-  	 || sysgetenv.vallen >=
-  	 	 sizeof(local_param_overrides[local_params].value))
-  		return EINVAL;
-  		
-          if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.key,
-            SELF, (vir_bytes) local_param_overrides[local_params].name,
-               sysgetenv.keylen)) != OK)
-               	return s;
-          if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.val,
-            SELF, (vir_bytes) local_param_overrides[local_params].value,
-              sysgetenv.keylen)) != OK)
-               	return s;
-            local_param_overrides[local_params].name[sysgetenv.keylen] = '\0';
-            local_param_overrides[local_params].value[sysgetenv.vallen] = '\0';
-
-  	local_params++;
-
-  	return OK;
-      }
-
-      if (sysgetenv.keylen == 0) {	/* copy all parameters */
-          val_start = monitor_params;
-          val_len = sizeof(monitor_params);
-      } 
-      else {				/* lookup value for key */
-      	  int p;
-          /* Try to get a copy of the requested key. */
-          if (sysgetenv.keylen > sizeof(search_key)) return(EINVAL);
-          if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.key,
-                  SELF, (vir_bytes) search_key, sysgetenv.keylen)) != OK)
-              return(s);
-
-          /* Make sure key is null-terminated and lookup value.
-           * First check local overrides.
-           */
-          search_key[sysgetenv.keylen-1]= '\0';
-          for(p = 0; p < local_params; p++) {
-          	if (!strcmp(search_key, local_param_overrides[p].name)) {
-          		val_start = local_param_overrides[p].value;
-          		break;
-          	}
-          }
-          if (p >= local_params && (val_start = find_param(search_key)) == NULL)
-               return(ESRCH);
-          val_len = strlen(val_start) + 1;
-      }
-
-      /* See if it fits in the client's buffer. */
-      if (val_len > sysgetenv.vallen)
-      	return E2BIG;
-
-      /* Value found, make the actual copy (as far as possible). */
-      copy_len = MIN(val_len, sysgetenv.vallen); 
-      if ((s=sys_datacopy(SELF, (vir_bytes) val_start, 
-              who_e, (vir_bytes) sysgetenv.val, copy_len)) != OK)
-          return(s);
-
-      return OK;
-  }
-
-#if ENABLE_SWAP
-  case MMSWAPON: {
-	struct mmswapon swapon;
-
-	if (mp->mp_effuid != SUPER_USER) return(EPERM);
-
-	if (sys_datacopy(who_e, (phys_bytes) ptr,
-		PM_PROC_NR, (phys_bytes) &swapon,
-		(phys_bytes) sizeof(swapon)) != OK) return(EFAULT);
-
-	return(swap_on(swapon.file, swapon.offset, swapon.size)); }
-
-  case MMSWAPOFF: {
-	if (mp->mp_effuid != SUPER_USER) return(EPERM);
-
-	return(swap_off()); }
-#endif /* SWAP */
-
-  default:
-	return(EINVAL);
-  }
-}
-
-/*===========================================================================*
- *				_read_pm				     *
- *===========================================================================*/
-PUBLIC ssize_t _read_pm(fd, buffer, nbytes, seg, ep)
-int fd;
-void *buffer;
-size_t nbytes;
-int seg;
-int ep;
-{
-  message m;
-
-  m.m1_i1 = _PM_SEG_FLAG | fd;
-  m.m1_i2 = nbytes;
-  m.m1_p1 = (char *) buffer;
-  m.m1_p2 = (char *) seg;
-  m.m1_p3 = (char *) ep;
-  return(_syscall(FS_PROC_NR, READ, &m));
-}
-
-/*===========================================================================*
- *				_write_pm				     *
- *===========================================================================*/
-PUBLIC ssize_t _write_pm(fd, buffer, nbytes, seg, ep)
-int fd;
-void *buffer;
-size_t nbytes;
-int seg;
-int ep;
-{
-  message m;
-
-  m.m1_i1 = _PM_SEG_FLAG | fd;
-  m.m1_i2 = nbytes;
-  m.m1_p1 = (char *) buffer;
-  m.m1_p2 = (char *) seg;
-  m.m1_p3 = (char *) ep;
-  return(_syscall(FS_PROC_NR, WRITE, &m));
-}
-
-PUBLIC int do_foo()
-{
-	printf("Foo syscall called!\n");
-	return OK;
-}
Index: trunk/minix/servers/pm/mproc.h
===================================================================
--- trunk/minix/servers/pm/mproc.h	(revision 11)
+++ 	(revision )
@@ -1,76 +1,0 @@
-/* This table has one slot per process.  It contains all the process management
- * information for each process.  Among other things, it defines the text, data
- * and stack segments, uids and gids, and various flags.  The kernel and file
- * systems have tables that are also indexed by process, with the contents
- * of corresponding slots referring to the same process in all three.
- */
-#include <timers.h>
-
-EXTERN struct mproc {
-  struct mem_map mp_seg[NR_LOCAL_SEGS]; /* points to text, data, stack */
-  char mp_exitstatus;		/* storage for status when process exits */
-  char mp_sigstatus;		/* storage for signal # for killed procs */
-  pid_t mp_pid;			/* process id */
-  int mp_endpoint;		/* kernel endpoint id */
-  pid_t mp_procgrp;		/* pid of process group (used for signals) */
-  pid_t mp_wpid;		/* pid this process is waiting for */
-  int mp_parent;		/* index of parent process */
-
-  /* Child user and system times. Accounting done on child exit. */
-  clock_t mp_child_utime;	/* cumulative user time of children */
-  clock_t mp_child_stime;	/* cumulative sys time of children */
-
-  /* Real and effective uids and gids. */
-  uid_t mp_realuid;		/* process' real uid */
-  uid_t mp_effuid;		/* process' effective uid */
-  gid_t mp_realgid;		/* process' real gid */
-  gid_t mp_effgid;		/* process' effective gid */
-
-  /* File identification for sharing. */
-  ino_t mp_ino;			/* inode number of file */
-  dev_t mp_dev;			/* device number of file system */
-  time_t mp_ctime;		/* inode changed time */
-
-  /* Signal handling information. */
-  sigset_t mp_ignore;		/* 1 means ignore the signal, 0 means don't */
-  sigset_t mp_catch;		/* 1 means catch the signal, 0 means don't */
-  sigset_t mp_sig2mess;		/* 1 means transform into notify message */
-  sigset_t mp_sigmask;		/* signals to be blocked */
-  sigset_t mp_sigmask2;		/* saved copy of mp_sigmask */
-  sigset_t mp_sigpending;	/* pending signals to be handled */
-  struct sigaction mp_sigact[_NSIG + 1]; /* as in sigaction(2) */
-  vir_bytes mp_sigreturn; 	/* address of C library __sigreturn function */
-  struct timer mp_timer;	/* watchdog timer for alarm(2) */
-
-  /* Backwards compatibility for signals. */
-  sighandler_t mp_func;		/* all sigs vectored to a single user fcn */
-
-  unsigned mp_flags;		/* flag bits */
-  vir_bytes mp_procargs;        /* ptr to proc's initial stack arguments */
-  struct mproc *mp_swapq;	/* queue of procs waiting to be swapped in */
-  message mp_reply;		/* reply message to be sent to one */
-
-  /* Scheduling priority. */
-  signed int mp_nice;		/* nice is PRIO_MIN..PRIO_MAX, standard 0. */
-
-  char mp_name[PROC_NAME_LEN];	/* process name */
-} mproc[NR_PROCS];
-
-/* Flag values */
-#define IN_USE          0x001	/* set when 'mproc' slot in use */
-#define WAITING         0x002	/* set by WAIT system call */
-#define ZOMBIE          0x004	/* set by EXIT, cleared by WAIT */
-#define PAUSED          0x008	/* set by PAUSE system call */
-#define ALARM_ON        0x010	/* set when SIGALRM timer started */
-#define SEPARATE	0x020	/* set if file is separate I & D space */
-#define	TRACED		0x040	/* set if process is to be traced */
-#define STOPPED		0x080	/* set if process stopped for tracing */
-#define SIGSUSPENDED 	0x100	/* set by SIGSUSPEND system call */
-#define REPLY	 	0x200	/* set if a reply message is pending */
-#define ONSWAP	 	0x400	/* set if data segment is swapped out */
-#define SWAPIN	 	0x800	/* set if on the "swap this in" queue */
-#define DONT_SWAP      0x1000   /* never swap out this process */
-#define PRIV_PROC      0x2000   /* system process, special privileges */
-
-#define NIL_MPROC ((struct mproc *) 0)
-
Index: trunk/minix/servers/pm/param.h
===================================================================
--- trunk/minix/servers/pm/param.h	(revision 11)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/* The following names are synonyms for the variables in the input message. */
-#define addr            m1_p1
-#define exec_name	m1_p1
-#define exec_len	m1_i1
-#define func		m6_f1
-#define grp_id		m1_i1
-#define namelen		m1_i2
-#define pid		m1_i1
-#define endpt		m1_i1
-#define pendpt		m1_i2
-#define seconds		m1_i1
-#define sig		m6_i1
-#define stack_bytes	m1_i2
-#define stack_ptr	m1_p2
-#define status		m1_i1
-#define usr_id		m1_i1
-#define request		m2_i2
-#define taddr		m2_l1
-#define data		m2_l2
-#define sig_nr		m1_i2
-#define sig_nsa		m1_p1
-#define sig_osa		m1_p2
-#define sig_ret		m1_p3
-#define stat_nr		m2_i1
-#define sig_set		m2_l1
-#define sig_how		m2_i1
-#define sig_flags	m2_i2
-#define sig_context	m2_p1
-#ifdef _SIGMESSAGE
-#define sig_msg		m1_i1
-#endif
-#define info_what	m1_i1
-#define info_where	m1_p1
-#define reboot_flag	m1_i1
-#define reboot_code	m1_p1
-#define reboot_strlen	m1_i2
-#define svrctl_req	m2_i1
-#define svrctl_argp	m2_p1
-#define stime      	m2_l1
-#define memsize      	m4_l1
-#define membase      	m4_l2
-
-/* The following names are synonyms for the variables in a reply message. */
-#define reply_res	m_type
-#define reply_res2	m2_i1
-#define reply_res3	m2_i2
-#define reply_ptr	m2_p1
-#define reply_mask	m2_l1 	
-#define reply_trace	m2_l2 	
-#define reply_time      m2_l1
-#define reply_utime     m2_l2
-#define reply_t1 	m4_l1
-#define reply_t2 	m4_l2
-#define reply_t3 	m4_l3
-#define reply_t4 	m4_l4
-#define reply_t5 	m4_l5
-
-/* The following names are used to inform the FS about certain events. */
-#define tell_fs_arg1    m1_i1
-#define tell_fs_arg2    m1_i2
-#define tell_fs_arg3    m1_i3
-
Index: trunk/minix/servers/pm/pm.h
===================================================================
--- trunk/minix/servers/pm/pm.h	(revision 11)
+++ 	(revision )
@@ -1,26 +1,0 @@
-/* This is the master header for PM.  It includes some other files
- * and defines the principal constants.
- */
-#define _POSIX_SOURCE      1	/* tell headers to include POSIX stuff */
-#define _MINIX             1	/* tell headers to include MINIX stuff */
-#define _SYSTEM            1	/* tell headers that this is the kernel */
-
-/* The following are so basic, all the *.c files get them automatically. */
-#include <minix/config.h>	/* MUST be first */
-#include <ansi.h>		/* MUST be second */
-#include <sys/types.h>
-#include <minix/const.h>
-#include <minix/type.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <minix/syslib.h>
-#include <minix/sysutil.h>
-
-#include <limits.h>
-#include <errno.h>
-
-#include "const.h"
-#include "type.h"
-#include "proto.h"
-#include "glo.h"
Index: trunk/minix/servers/pm/proto.h
===================================================================
--- trunk/minix/servers/pm/proto.h	(revision 11)
+++ 	(revision )
@@ -1,120 +1,0 @@
-/* Function prototypes. */
-
-struct mproc;
-struct stat;
-struct mem_map;
-struct memory;
-
-#include <timers.h>
-
-/* alloc.c */
-_PROTOTYPE( phys_clicks alloc_mem, (phys_clicks clicks)			);
-_PROTOTYPE( void free_mem, (phys_clicks base, phys_clicks clicks)	);
-_PROTOTYPE( void mem_init, (struct memory *chunks, phys_clicks *free)	);
-#if ENABLE_SWAP
-_PROTOTYPE( int swap_on, (char *file, u32_t offset, u32_t size)	);
-_PROTOTYPE( int swap_off, (void)					);
-_PROTOTYPE( void swap_in, (void)					);
-_PROTOTYPE( void swap_inqueue, (struct mproc *rmp)			);
-#else /* !SWAP */
-#define swap_in()			((void)0)
-#define swap_inqueue(rmp)		((void)0)
-#endif /* !SWAP */
-_PROTOTYPE(int mem_holes_copy, (struct hole *, size_t *, u32_t *)	);
-
-/* break.c */
-_PROTOTYPE( int adjust, (struct mproc *rmp,
-			vir_clicks data_clicks, vir_bytes sp)		);
-_PROTOTYPE( int do_brk, (void)						);
-_PROTOTYPE( int size_ok, (int file_type, vir_clicks tc, vir_clicks dc,
-			vir_clicks sc, vir_clicks dvir, vir_clicks s_vir) );
-
-/* devio.c */
-_PROTOTYPE( int do_dev_io, (void) );
-_PROTOTYPE( int do_dev_io, (void) );
-
-/* dmp.c */
-_PROTOTYPE( int do_fkey_pressed, (void)						);
-
-/* exec.c */
-_PROTOTYPE( int do_exec, (void)						);
-_PROTOTYPE( void rw_seg, (int rw, int fd, int proc, int seg,
-						phys_bytes seg_bytes)	);
-_PROTOTYPE( struct mproc *find_share, (struct mproc *mp_ign, Ino_t ino,
-			Dev_t dev, time_t ctime)			);
-
-/* forkexit.c */
-_PROTOTYPE( int do_fork, (void)						);
-_PROTOTYPE( int do_pm_exit, (void)					);
-_PROTOTYPE( int do_waitpid, (void)					);
-_PROTOTYPE( void pm_exit, (struct mproc *rmp, int exit_status)		);
-
-/* getset.c */
-_PROTOTYPE( int do_getset, (void)					);
-
-/* main.c */
-_PROTOTYPE( int main, (void)						);
-
-/* misc.c */
-_PROTOTYPE( int do_foo, (void)					);
-_PROTOTYPE( int do_reboot, (void)					);
-_PROTOTYPE( int do_procstat, (void)					);
-_PROTOTYPE( int do_getsysinfo, (void)					);
-_PROTOTYPE( int do_getprocnr, (void)					);
-_PROTOTYPE( int do_svrctl, (void)					);
-_PROTOTYPE( int do_allocmem, (void)					);
-_PROTOTYPE( int do_freemem, (void)					);
-_PROTOTYPE( int do_getsetpriority, (void)					);
-_PROTOTYPE( ssize_t _read_pm, (int _fd, void *_buf, size_t _n, int s, int e));
-_PROTOTYPE( ssize_t _write_pm, (int _fd, void *_buf, size_t _n, int s, int e));
-
-
-#if (MACHINE == MACINTOSH)
-_PROTOTYPE( phys_clicks start_click, (void)				);
-#endif
-
-_PROTOTYPE( void setreply, (int proc_nr, int result)			);
-
-/* signal.c */
-_PROTOTYPE( int do_alarm, (void)					);
-_PROTOTYPE( int do_kill, (void)						);
-_PROTOTYPE( int ksig_pending, (void)					);
-_PROTOTYPE( int do_pause, (void)					);
-_PROTOTYPE( int set_alarm, (int proc_nr, int sec)			);
-_PROTOTYPE( int check_sig, (pid_t proc_id, int signo)			);
-_PROTOTYPE( void sig_proc, (struct mproc *rmp, int sig_nr)		);
-_PROTOTYPE( int do_sigaction, (void)					);
-_PROTOTYPE( int do_sigpending, (void)					);
-_PROTOTYPE( int do_sigprocmask, (void)					);
-_PROTOTYPE( int do_sigreturn, (void)					);
-_PROTOTYPE( int do_sigsuspend, (void)					);
-_PROTOTYPE( void check_pending, (struct mproc *rmp)			);
-
-/* time.c */
-_PROTOTYPE( int do_stime, (void)					);
-_PROTOTYPE( int do_time, (void)						);
-_PROTOTYPE( int do_times, (void)					);
-_PROTOTYPE( int do_gettimeofday, (void)					);
-
-/* timers.c */
-_PROTOTYPE( void pm_set_timer, (timer_t *tp, int delta, 
-	tmr_func_t watchdog, int arg));
-_PROTOTYPE( void pm_expire_timers, (clock_t now));
-_PROTOTYPE( void pm_cancel_timer, (timer_t *tp));
-
-/* trace.c */
-_PROTOTYPE( int do_trace, (void)					);
-_PROTOTYPE( void stop_proc, (struct mproc *rmp, int sig_nr)		);
-
-/* utility.c */
-_PROTOTYPE( pid_t get_free_pid, (void)					);
-_PROTOTYPE( int allowed, (char *name_buf, struct stat *s_buf, int mask)	);
-_PROTOTYPE( int no_sys, (void)						);
-_PROTOTYPE( void panic, (char *who, char *mess, int num)		);
-_PROTOTYPE( void tell_fs, (int what, int p1, int p2, int p3)		);
-_PROTOTYPE( int get_stack_ptr, (int proc_nr, vir_bytes *sp)		);
-_PROTOTYPE( int get_mem_map, (int proc_nr, struct mem_map *mem_map)	);
-_PROTOTYPE( char *find_param, (const char *key));
-_PROTOTYPE( int proc_from_pid, (pid_t p));
-_PROTOTYPE( int pm_isokendpt, (int ep, int *proc));
-
Index: trunk/minix/servers/pm/signal.c
===================================================================
--- trunk/minix/servers/pm/signal.c	(revision 11)
+++ 	(revision )
@@ -1,703 +1,0 @@
-/* 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_alarm:	perform the ALARM system call by calling set_alarm()
- *   set_alarm:	tell the clock task to start or stop a timer
- *   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
- */
-
-#include "pm.h"
-#include <sys/stat.h>
-#include <sys/ptrace.h>
-#include <minix/callnr.h>
-#include <minix/endpoint.h>
-#include <minix/com.h>
-#include <signal.h>
-#include <sys/sigcontext.h>
-#include <string.h>
-#include "mproc.h"
-#include "param.h"
-
-#define CORE_MODE	0777	/* mode to use on core image files */
-#define DUMPED          0200	/* bit set in status when core dumped */
-
-FORWARD _PROTOTYPE( void dump_core, (struct mproc *rmp)			);
-FORWARD _PROTOTYPE( void unpause, (int pro)				);
-FORWARD _PROTOTYPE( void handle_ksig, (int proc_nr, sigset_t sig_map)	);
-FORWARD _PROTOTYPE( void cause_sigalrm, (struct timer *tp)		);
-
-/*===========================================================================*
- *				do_sigaction				     *
- *===========================================================================*/
-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,
-		who_e, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec));
-	if (r != OK) return(r);
-  }
-
-  if ((struct sigaction *) m_in.sig_nsa == (struct sigaction *) NULL) 
-  	return(OK);
-
-  /* Read in the sigaction structure. */
-  r = sys_datacopy(who_e, (vir_bytes) m_in.sig_nsa,
-		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);
-	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);
-  } else {
-	sigdelset(&mp->mp_ignore, m_in.sig_nr);
-	sigaddset(&mp->mp_catch, m_in.sig_nr);
-	sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
-  }
-  mp->mp_sigact[m_in.sig_nr].sa_handler = svec.sa_handler;
-  sigdelset(&svec.sa_mask, SIGKILL);
-  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);
-}
-
-/*===========================================================================*
- *				do_sigpending                                *
- *===========================================================================*/
-PUBLIC int do_sigpending()
-{
-  mp->mp_reply.reply_mask = (long) mp->mp_sigpending;
-  return OK;
-}
-
-/*===========================================================================*
- *				do_sigprocmask                               *
- *===========================================================================*/
-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.
- *
- * KILL and STOP can't be masked.
- */
-
-  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);
-	sigdelset((sigset_t *)&m_in.sig_set, SIGSTOP);
-	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);
-	sigdelset((sigset_t *) &m_in.sig_set, SIGSTOP);
-	mp->mp_sigmask = (sigset_t) m_in.sig_set;
-	check_pending(mp);
-	break;
-
-      case SIG_INQUIRE:
-	break;
-
-      default:
-	return(EINVAL);
-	break;
-  }
-  return OK;
-}
-
-/*===========================================================================*
- *				do_sigsuspend                                *
- *===========================================================================*/
-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);
-  mp->mp_flags |= SIGSUSPENDED;
-  check_pending(mp);
-  return(SUSPEND);
-}
-
-/*===========================================================================*
- *				do_sigreturn				     *
- *===========================================================================*/
-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);
-
-  r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context);
-  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);
-}
-
-/*===========================================================================*
- *				ksig_pending				     *
- *===========================================================================*/
-PUBLIC int ksig_pending()
-{
-/* 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). 
- *
- * The kernel has notified the PM about pending signals. Request pending
- * signals until all signals are handled. If there are no more signals,
- * NONE is returned in the process number field.
- */ 
- int proc_nr_e;
- sigset_t sig_map;
-
- while (TRUE) {
-   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 */
- 	break;
-   } else {
- 	int proc_nr_p;
- 	if(pm_isokendpt(proc_nr_e, &proc_nr_p) != OK)
-  		panic(__FILE__,"sys_getksig strange process", proc_nr_e);
-   	handle_ksig(proc_nr_e, sig_map);	/* handle the received signal */
-	/* If the process still exists to the kernel after the signal
-	 * has been handled ...
-	 */
-        if ((mproc[proc_nr_p].mp_flags & (IN_USE | ZOMBIE)) == IN_USE)
-	   if((r=sys_endksig(proc_nr_e)) != OK)	/* ... tell kernel it's done */
-  		panic(__FILE__,"sys_endksig failed", r);
-   }
- } 
- return(SUSPEND);			/* prevents sending reply */
-}
-
-/*===========================================================================*
- *				handle_ksig				     *
- *===========================================================================*/
-PRIVATE void handle_ksig(proc_nr_e, sig_map)
-int proc_nr_e;
-sigset_t sig_map;
-{
-  register struct mproc *rmp;
-  int i, proc_nr;
-  pid_t proc_id, id;
-
-  if(pm_isokendpt(proc_nr_e, &proc_nr) != OK || proc_nr < 0)
-	return;
-  rmp = &mproc[proc_nr];
-  if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE)
-	return;
-  proc_id = rmp->mp_pid;
-  mp = &mproc[0];			/* pretend signals are from PM */
-  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
-   * process and pass them to PM in one blow.  Thus loop on the bit
-   * map. 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.
-   */
-  for (i = 1; i <= _NSIG; i++) {
-	if (!sigismember(&sig_map, i)) continue;
-	switch (i) {
-	    case SIGINT:
-	    case SIGQUIT:
-	    case SIGWINCH:
-		id = 0; break;	/* broadcast to process group */
-#if 0
-	    case SIGKILL:
-		id = -1; break;	/* broadcast to all except INIT */
-#endif
-	    default:
-		id = proc_id;
-		break;
-	}
-	check_sig(id, i);
-  }
-}
-
-/*===========================================================================*
- *				do_alarm				     *
- *===========================================================================*/
-PUBLIC int do_alarm()
-{
-/* Perform the alarm(seconds) system call. */
-  return(set_alarm(who_e, m_in.seconds));
-}
-
-/*===========================================================================*
- *				set_alarm				     *
- *===========================================================================*/
-PUBLIC int set_alarm(proc_nr_e, sec)
-int proc_nr_e;			/* process that wants the alarm */
-int sec;			/* how many seconds delay before the signal */
-{
-/* This routine is used by do_alarm() to set the alarm timer.  It is also used
- * to turn the timer off when a process exits with the timer still on.
- */
-  clock_t ticks;	/* number of ticks for alarm */
-  clock_t exptime;	/* needed for remaining time on previous alarm */
-  clock_t uptime;	/* current system time */
-  int remaining;	/* previous time left in seconds */
-  int s;
-  int proc_nr_n;
-
-  if(pm_isokendpt(proc_nr_e, &proc_nr_n) != OK)
-	return EINVAL;
-
-  /* First determine remaining time of previous alarm, if set. */
-  if (mproc[proc_nr_n].mp_flags & ALARM_ON) {
-  	if ( (s=getuptime(&uptime)) != OK) 
-  		panic(__FILE__,"set_alarm couldn't get uptime", s);
-  	exptime = *tmr_exp_time(&mproc[proc_nr_n].mp_timer);
-  	remaining = (int) ((exptime - uptime + (HZ-1))/HZ);
-  	if (remaining < 0) remaining = 0;	
-  } else {
-  	remaining = 0; 
-  }
-
-  /* Tell the clock task to provide a signal message when the time comes.
-   *
-   * Large delays cause a lot of problems.  First, the alarm system call
-   * takes an unsigned seconds count and the library has cast it to an int.
-   * That probably works, but on return the library will convert "negative"
-   * unsigneds to errors.  Presumably no one checks for these errors, so
-   * force this call through.  Second, If unsigned and long have the same
-   * size, converting from seconds to ticks can easily overflow.  Finally,
-   * the kernel has similar overflow bugs adding ticks.
-   *
-   * Fixing this requires a lot of ugly casts to fit the wrong interface
-   * types and to avoid overflow traps.  ALRM_EXP_TIME has the right type
-   * (clock_t) although it is declared as long.  How can variables like
-   * this be declared properly without combinatorial explosion of message
-   * types?
-   */
-  ticks = (clock_t) (HZ * (unsigned long) (unsigned) sec);
-  if ( (unsigned long) ticks / HZ != (unsigned) sec)
-	ticks = LONG_MAX;	/* eternity (really TMR_NEVER) */
-
-  if (ticks != 0) {
-  	pm_set_timer(&mproc[proc_nr_n].mp_timer, ticks,
-		cause_sigalrm, proc_nr_e);
-  	mproc[proc_nr_n].mp_flags |=  ALARM_ON;
-  } else if (mproc[proc_nr_n].mp_flags & ALARM_ON) {
-  	pm_cancel_timer(&mproc[proc_nr_n].mp_timer);
-  	mproc[proc_nr_n].mp_flags &= ~ALARM_ON;
-  }
-  return(remaining);
-}
-
-/*===========================================================================*
- *				cause_sigalrm				     *
- *===========================================================================*/
-PRIVATE void cause_sigalrm(tp)
-struct timer *tp;
-{
-  int proc_nr_e, proc_nr_n;
-  register struct mproc *rmp;
-
-  /* get process from timer */
-  if(pm_isokendpt(tmr_arg(tp)->ta_int, &proc_nr_n) != OK) {
-	printf("PM: ignoring timer for invalid endpoint %d\n",
-		tmr_arg(tp)->ta_int);
-	return;
-  }
-
-  rmp = &mproc[proc_nr_n];
-
-  if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return;
-  if ((rmp->mp_flags & ALARM_ON) == 0) return;
-  rmp->mp_flags &= ~ALARM_ON;
-  check_sig(rmp->mp_pid, SIGALRM);
-}
-
-/*===========================================================================*
- *				do_pause				     *
- *===========================================================================*/
-PUBLIC int do_pause()
-{
-/* Perform the pause() system call. */
-
-  mp->mp_flags |= PAUSED;
-  return(SUSPEND);
-}
-
-/*===========================================================================*
- *				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,
- * 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.
- * If there is insufficient stack space, kill the process.
- */
-
-  vir_bytes new_sp;
-  int s;
-  int slot;
-  int sigflags;
-  struct sigmsg sm;
-
-  slot = (int) (rmp - mproc);
-  if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
-	printf("PM: signal %d sent to %s process %d\n",
-		signo, (rmp->mp_flags & ZOMBIE) ? "zombie" : "dead", slot);
-	panic(__FILE__,"", NO_NUM);
-  }
-  if ((rmp->mp_flags & TRACED) && signo != SIGKILL) {
-	/* A traced process has special handling. */
-	unpause(slot);
-	stop_proc(rmp, signo);	/* a signal causes it to stop */
-	return;
-  }
-  /* Some signals are ignored by default. */
-  if (sigismember(&rmp->mp_ignore, signo)) { 
-  	return;
-  }
-  if (sigismember(&rmp->mp_sigmask, signo)) {
-	/* Signal should be blocked. */
-	sigaddset(&rmp->mp_sigpending, signo);
-	return;
-  }
-#if ENABLE_SWAP
-  if (rmp->mp_flags & ONSWAP) {
-	/* Process is swapped out, leave signal pending. */
-	sigaddset(&rmp->mp_sigpending, signo);
-	swap_inqueue(rmp);
-	return;
-  }
-#endif
-  sigflags = rmp->mp_sigact[signo].sa_flags;
-  if (sigismember(&rmp->mp_catch, signo)) {
-	if (rmp->mp_flags & SIGSUSPENDED)
-		sm.sm_mask = rmp->mp_sigmask2;
-	else
-		sm.sm_mask = rmp->mp_sigmask;
-	sm.sm_signo = signo;
-	sm.sm_sighandler = (vir_bytes) rmp->mp_sigact[signo].sa_handler;
-	sm.sm_sigreturn = rmp->mp_sigreturn;
-	if ((s=get_stack_ptr(rmp->mp_endpoint, &new_sp)) != OK)
-		panic(__FILE__,"couldn't get new stack pointer (for sig)",s);
-	sm.sm_stkptr = new_sp;
-
-	/* Make room for the sigcontext and sigframe struct. */
-	new_sp -= sizeof(struct sigcontext)
-				 + 3 * sizeof(char *) + 2 * sizeof(int);
-
-	if (adjust(rmp, rmp->mp_seg[D].mem_len, new_sp) != OK)
-		goto doterminate;
-
-	rmp->mp_sigmask |= rmp->mp_sigact[signo].sa_mask;
-	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;
-	}
-
-	if (OK == (s=sys_sigsend(rmp->mp_endpoint, &sm))) {
-
-		sigdelset(&rmp->mp_sigpending, signo);
-		/* If process is hanging on PAUSE, WAIT, SIGSUSPEND, tty, 
-		 * pipe, etc., release it.
-		 */
-		unpause(slot);
-		return;
-	}
-  	panic(__FILE__, "sys_sigsend failed", s);
-  }
-  else if (sigismember(&rmp->mp_sig2mess, signo)) {
-
-	/* Mark event pending in process slot and send notification. */
-	sigaddset(&rmp->mp_sigpending, signo);
-	notify(rmp->mp_endpoint);
-  	return;
-  }
-
-doterminate:
-  /* Signal should not or cannot be caught.  Take default action. */
-  if (sigismember(&ign_sset, signo)) return;
-
-  rmp->mp_sigstatus = (char) signo;
-  if (sigismember(&core_sset, signo) && slot != FS_PROC_NR) {
-#if ENABLE_SWAP
-	if (rmp->mp_flags & ONSWAP) {
-		/* Process is swapped out, leave signal pending. */
-		sigaddset(&rmp->mp_sigpending, signo);
-		swap_inqueue(rmp);
-		return;
-	}
-#endif
-	/* Switch to the user's FS environment and dump core. */
-	tell_fs(CHDIR, rmp->mp_endpoint, FALSE, 0);
-	dump_core(rmp);
-  }
-  pm_exit(rmp, 0);		/* terminate process */
-}
-
-/*===========================================================================*
- *				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);
-
-  /* Search the proc table for processes to signal.  
-   * (See forkexit.c aboutpid magic.)
-   */
-  count = 0;
-  error_code = ESRCH;
-  for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
-	if (!(rmp->mp_flags & IN_USE)) continue;
-	if ((rmp->mp_flags & ZOMBIE) && signo != 0) 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;
-
-	/* Do not kill servers and drivers when broadcasting SIGKILL. */
-	if (proc_id == -1 && signo == SIGKILL &&
-		(rmp->mp_flags & PRIV_PROC)) continue;
-
-	/* 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++;
-	if (signo == 0) continue;
-
-	/* '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. */
-  if ((mp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return(SUSPEND);
-  return(count > 0 ? OK : error_code);
-}
-
-/*===========================================================================*
- *				check_pending				     *
- *===========================================================================*/
-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					     *
- *===========================================================================*/
-PRIVATE void unpause(pro)
-int pro;			/* which process number */
-{
-/* 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.
- * First check if the process is hanging on an PM call.  If not, tell FS,
- * so it can check for READs and WRITEs from pipes, ttys and the like.
- */
-
-  register struct mproc *rmp;
-
-  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;
-  }
-
-  /* Process is not hanging on an PM call.  Ask FS to take a look. */
-  tell_fs(UNPAUSE, rmp->mp_endpoint, 0, 0);
-}
-
-/*===========================================================================*
- *				dump_core				     *
- *===========================================================================*/
-PRIVATE void dump_core(rmp)
-register struct mproc *rmp;	/* whose core is to be dumped */
-{
-/* Make a core dump on the file "core", if possible. */
-
-  int s, fd, seg, slot;
-  vir_bytes current_sp;
-  long trace_data, trace_off;
-
-  slot = (int) (rmp - mproc);
-
-  /* Can core file be written?  We are operating in the user's FS environment,
-   * so no special permission checks are needed.
-   */
-  if (rmp->mp_realuid != rmp->mp_effuid) return;
-  if ( (fd = open(core_name, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK,
-						CORE_MODE)) < 0) return;
-  rmp->mp_sigstatus |= DUMPED;
-
-  /* Make sure the stack segment is up to date.
-   * We don't want adjust() to fail unless current_sp is preposterous,
-   * but it might fail due to safety checking.  Also, we don't really want 
-   * the adjust() for sending a signal to fail due to safety checking.  
-   * Maybe make SAFETY_BYTES a parameter.
-   */
-  if ((s=get_stack_ptr(rmp->mp_endpoint, &current_sp)) != OK)
-	panic(__FILE__,"couldn't get new stack pointer (for core)",s);
-  adjust(rmp, rmp->mp_seg[D].mem_len, current_sp);
-
-  /* Write the memory map of all segments to begin the core file. */
-  if (write(fd, (char *) rmp->mp_seg, (unsigned) sizeof rmp->mp_seg)
-      != (unsigned) sizeof rmp->mp_seg) {
-	close(fd);
-	return;
-  }
-
-  /* Write out the whole kernel process table entry to get the regs. */
-  trace_off = 0;
-  while (sys_trace(T_GETUSER, rmp->mp_endpoint, trace_off, &trace_data) == OK) {
-	if (write(fd, (char *) &trace_data, (unsigned) sizeof (long))
-	    != (unsigned) sizeof (long)) {
-		close(fd);
-		return;
-	}
-	trace_off += sizeof (long);
-  }
-
-  /* Loop through segments and write the segments themselves out. */
-  for (seg = 0; seg < NR_LOCAL_SEGS; seg++) {
-	rw_seg(1, fd, rmp->mp_endpoint, seg,
-		(phys_bytes) rmp->mp_seg[seg].mem_len << CLICK_SHIFT);
-  }
-  close(fd);
-}
-
Index: trunk/minix/servers/pm/table.c
===================================================================
--- trunk/minix/servers/pm/table.c	(revision 11)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/* This file contains the table used to map system call numbers onto the
- * routines that perform them.
- */
-
-#define _TABLE
-
-#include "pm.h"
-#include <minix/callnr.h>
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-/* Miscellaneous */
-char core_name[] = "core";	/* file name where core images are produced */
-
-_PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
-	no_sys,		/*  0 = unused	*/
-	do_pm_exit,	/*  1 = exit	*/
-	do_fork,	/*  2 = fork	*/
-	no_sys,		/*  3 = read	*/
-	no_sys,		/*  4 = write	*/
-	no_sys,		/*  5 = open	*/
-	no_sys,		/*  6 = close	*/
-	do_waitpid,	/*  7 = wait	*/
-	no_sys,		/*  8 = creat	*/
-	no_sys,		/*  9 = link	*/
-	no_sys,		/* 10 = unlink	*/
-	do_waitpid,	/* 11 = waitpid	*/
-	no_sys,		/* 12 = chdir	*/
-	do_time,	/* 13 = time	*/
-	no_sys,		/* 14 = mknod	*/
-	no_sys,		/* 15 = chmod	*/
-	no_sys,		/* 16 = chown	*/
-	do_brk,		/* 17 = break	*/
-	no_sys,		/* 18 = stat	*/
-	no_sys,		/* 19 = lseek	*/
-	do_getset,	/* 20 = getpid	*/
-	no_sys,		/* 21 = mount	*/
-	no_sys,		/* 22 = umount	*/
-	do_getset,	/* 23 = setuid	*/
-	do_getset,	/* 24 = getuid	*/
-	do_stime,	/* 25 = stime	*/
-	do_trace,	/* 26 = ptrace	*/
-	do_alarm,	/* 27 = alarm	*/
-	no_sys,		/* 28 = fstat	*/
-	do_pause,	/* 29 = pause	*/
-	no_sys,		/* 30 = utime	*/
-	no_sys,		/* 31 = (stty)	*/
-	no_sys,		/* 32 = (gtty)	*/
-	no_sys,		/* 33 = access	*/
-	no_sys,		/* 34 = (nice)	*/
-	no_sys,		/* 35 = (ftime)	*/
-	no_sys,		/* 36 = sync	*/
-	do_kill,	/* 37 = kill	*/
-	no_sys,		/* 38 = rename	*/
-	no_sys,		/* 39 = mkdir	*/
-	no_sys,		/* 40 = rmdir	*/
-	no_sys,		/* 41 = dup	*/
-	no_sys,		/* 42 = pipe	*/
-	do_times,	/* 43 = times	*/
-	no_sys,		/* 44 = (prof)	*/
-	no_sys,		/* 45 = unused	*/
-	do_getset,	/* 46 = setgid	*/
-	do_getset,	/* 47 = getgid	*/
-	no_sys,		/* 48 = (signal)*/
-	no_sys,		/* 49 = unused	*/
-	no_sys,		/* 50 = unused	*/
-	no_sys,		/* 51 = (acct)	*/
-	no_sys,		/* 52 = (phys)	*/
-	no_sys,		/* 53 = (lock)	*/
-	no_sys,		/* 54 = ioctl	*/
-	no_sys,		/* 55 = fcntl	*/
-	no_sys,		/* 56 = (mpx)	*/
-	no_sys,		/* 57 = unused	*/
-	no_sys,		/* 58 = unused	*/
-	do_exec,	/* 59 = execve	*/
-	no_sys,		/* 60 = umask	*/
-	no_sys,		/* 61 = chroot	*/
-	do_getset,	/* 62 = setsid	*/
-	do_getset,	/* 63 = getpgrp	*/
-
-	no_sys,		/* 64 = unused */
-	no_sys,		/* 65 = UNPAUSE	*/
-	no_sys, 	/* 66 = unused  */
-	no_sys,		/* 67 = REVIVE	*/
-	no_sys,		/* 68 = TASK_REPLY  */
-	no_sys,		/* 69 = unused	*/
-	no_sys,		/* 70 = unused	*/
-	do_sigaction,	/* 71 = sigaction   */
-	do_sigsuspend,	/* 72 = sigsuspend  */
-	do_sigpending,	/* 73 = sigpending  */
-	do_sigprocmask,	/* 74 = sigprocmask */
-	do_sigreturn,	/* 75 = sigreturn   */
-	do_reboot,	/* 76 = reboot	*/
-	do_svrctl,	/* 77 = svrctl	*/
-	do_procstat,	/* 78 = procstat */
-	do_getsysinfo,	/* 79 = getsysinfo */
-	do_getprocnr,	/* 80 = getprocnr */
-	no_sys, 	/* 81 = unused */
-	no_sys, 	/* 82 = fstatfs */
-	do_allocmem, 	/* 83 = memalloc */
-	do_freemem, 	/* 84 = memfree */
-	no_sys,		/* 85 = select */
-	no_sys,		/* 86 = fchdir */
-	no_sys,		/* 87 = fsync */
-	do_getsetpriority,	/* 88 = getpriority */
-	do_getsetpriority,	/* 89 = setpriority */
-	do_time,	/* 90 = gettimeofday */
-	do_getset,	/* 91 = seteuid	*/
-	do_getset,	/* 92 = setegid	*/
-	no_sys,		/* 93 = truncate */
-	no_sys,		/* 94 = ftruncate */
-	do_foo,		/* 95 = foo */
-};
-/* This should not fail with "array size is negative": */
-extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
Index: trunk/minix/servers/pm/time.c
===================================================================
--- trunk/minix/servers/pm/time.c	(revision 11)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/* This file takes care of those system calls that deal with time.
- *
- * The entry points into this file are
- *   do_time:		perform the TIME system call
- *   do_stime:		perform the STIME system call
- *   do_times:		perform the TIMES system call
- */
-
-#include "pm.h"
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-PRIVATE time_t boottime;
-
-/*===========================================================================*
- *				do_time					     *
- *===========================================================================*/
-PUBLIC int do_time()
-{
-/* Perform the time(tp) system call. This returns the time in seconds since 
- * 1.1.1970.  MINIX is an astrophysically naive system that assumes the earth 
- * rotates at a constant rate and that such things as leap seconds do not 
- * exist.
- */
-  clock_t uptime;
-  int s;
-
-  if ( (s=getuptime(&uptime)) != OK) 
-  	panic(__FILE__,"do_time couldn't get uptime", s);
-
-  mp->mp_reply.reply_time = (time_t) (boottime + (uptime/HZ));
-  mp->mp_reply.reply_utime = (uptime%HZ)*1000000/HZ;
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_stime				     *
- *===========================================================================*/
-PUBLIC int do_stime()
-{
-/* Perform the stime(tp) system call. Retrieve the system's uptime (ticks 
- * since boot) and store the time in seconds at system boot in the global
- * variable 'boottime'.
- */
-  clock_t uptime;
-  int s;
-
-  if (mp->mp_effuid != SUPER_USER) { 
-      return(EPERM);
-  }
-  if ( (s=getuptime(&uptime)) != OK) 
-      panic(__FILE__,"do_stime couldn't get uptime", s);
-  boottime = (long) m_in.stime - (uptime/HZ);
-
-  /* Also inform FS about the new system time. */
-  tell_fs(STIME, boottime, 0, 0);
-
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_times				     *
- *===========================================================================*/
-PUBLIC int do_times()
-{
-/* Perform the times(buffer) system call. */
-  register struct mproc *rmp = mp;
-  clock_t t[5];
-  int s;
-
-  if (OK != (s=sys_times(who_e, t)))
-      panic(__FILE__,"do_times couldn't get times", s);
-  rmp->mp_reply.reply_t1 = t[0];		/* user time */
-  rmp->mp_reply.reply_t2 = t[1];		/* system time */
-  rmp->mp_reply.reply_t3 = rmp->mp_child_utime;	/* child user time */
-  rmp->mp_reply.reply_t4 = rmp->mp_child_stime;	/* child system time */
-  rmp->mp_reply.reply_t5 = t[4];		/* uptime since boot */
-
-  return(OK);
-}
-
Index: trunk/minix/servers/pm/timers.c
===================================================================
--- trunk/minix/servers/pm/timers.c	(revision 11)
+++ 	(revision )
@@ -1,79 +1,0 @@
-/* PM watchdog timer management. These functions in this file provide
- * a convenient interface to the timers library that manages a list of
- * watchdog timers. All details of scheduling an alarm at the CLOCK task 
- * are hidden behind this interface.
- * Only system processes are allowed to set an alarm timer at the kernel. 
- * Therefore, the PM maintains a local list of timers for user processes
- * that requested an alarm signal. 
- * 
- * The entry points into this file are:
- *   pm_set_timer:      reset and existing or set a new watchdog timer
- *   pm_expire_timers:  check for expired timers and run watchdog functions
- *   pm_cancel_timer:   remove a time from the list of timers
- *
- */
-
-#include "pm.h"
-
-#include <timers.h>
-#include <minix/syslib.h>
-#include <minix/com.h>
-
-PRIVATE timer_t *pm_timers = NULL;
-
-/*===========================================================================*
- *				pm_set_timer				     *
- *===========================================================================*/
-PUBLIC void pm_set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
-{
-	int r;
-	clock_t now, prev_time = 0, next_time;
-
-	if ((r = getuptime(&now)) != OK)
-		panic(__FILE__, "PM couldn't get uptime", NO_NUM);
-
-	/* Set timer argument and add timer to the list. */
-	tmr_arg(tp)->ta_int = arg;
-	prev_time = tmrs_settimer(&pm_timers,tp,now+ticks,watchdog,&next_time);
-
-	/* Reschedule our synchronous alarm if necessary. */
-	if (! prev_time || prev_time > next_time) {
-		if (sys_setalarm(next_time, 1) != OK)
-			panic(__FILE__, "PM set timer couldn't set alarm.", NO_NUM);
-	}
-
-	return;
-}
-
-/*===========================================================================*
- *				pm_expire_timers			     *
- *===========================================================================*/
-PUBLIC void pm_expire_timers(clock_t now)
-{
-	clock_t next_time;
-
-	/* Check for expired timers and possibly reschedule an alarm. */
-	tmrs_exptimers(&pm_timers, now, &next_time);
-	if (next_time > 0) {
-		if (sys_setalarm(next_time, 1) != OK)
-			panic(__FILE__, "PM expire timer couldn't set alarm.", NO_NUM);
-	}
-}
-
-/*===========================================================================*
- *				pm_cancel_timer				     *
- *===========================================================================*/
-PUBLIC void pm_cancel_timer(timer_t *tp)
-{
-	clock_t next_time, prev_time;
-	prev_time = tmrs_clrtimer(&pm_timers, tp, &next_time);
-
-	/* If the earliest timer has been removed, we have to set the alarm to  
-     * the next timer, or cancel the alarm altogether if the last timer has 
-     * been cancelled (next_time will be 0 then).
-	 */
-	if (prev_time < next_time || ! next_time) {
-		if (sys_setalarm(next_time, 1) != OK)
-			panic(__FILE__, "PM expire timer couldn't set alarm.", NO_NUM);
-	}
-}
Index: trunk/minix/servers/pm/trace.c
===================================================================
--- trunk/minix/servers/pm/trace.c	(revision 11)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/* This file handles the process manager's part of debugging, using the 
- * ptrace system call. Most of the commands are passed on to the system
- * task for completion.
- *
- * The debugging commands available are:
- * T_STOP	stop the process 
- * T_OK		enable tracing by parent for this process
- * T_GETINS	return value from instruction space 
- * T_GETDATA	return value from data space 
- * T_GETUSER	return value from user process table
- * T_SETINS	set value in instruction space
- * T_SETDATA	set value in data space
- * T_SETUSER	set value in user process table 
- * T_RESUME	resume execution 
- * T_EXIT	exit
- * T_STEP	set trace bit 
- * 
- * The T_OK and T_EXIT commands are handled here, and the T_RESUME and
- * T_STEP commands are partially handled here and completed by the system
- * task. The rest are handled entirely by the system task. 
- */
-
-#include "pm.h"
-#include <minix/com.h>
-#include <sys/ptrace.h>
-#include <signal.h>
-#include "mproc.h"
-#include "param.h"
-
-#define NIL_MPROC	((struct mproc *) 0)
-
-FORWARD _PROTOTYPE( struct mproc *find_proc, (pid_t lpid) );
-
-/*===========================================================================*
- *				do_trace  				     *
- *===========================================================================*/
-PUBLIC int do_trace()
-{
-  register struct mproc *child;
-  int r;
-
-  /* the T_OK call is made by the child fork of the debugger before it execs  
-   * the process to be traced
-   */
-  if (m_in.request == T_OK) {	/* enable tracing by parent for this proc */
-	mp->mp_flags |= TRACED;
-	mp->mp_reply.reply_trace = 0;
-	return(OK);
-  }
-  if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) {
-	return(ESRCH);
-  }
-  /* all the other calls are made by the parent fork of the debugger to 
-   * control execution of the child
-   */
-  switch (m_in.request) {
-  case T_EXIT:		/* exit */
-	pm_exit(child, (int) m_in.data);
-	mp->mp_reply.reply_trace = 0;
-	return(OK);
-  case T_RESUME: 
-  case T_STEP: 		/* resume execution */
-	if (m_in.data < 0 || m_in.data > _NSIG) return(EIO);
-	if (m_in.data > 0) {		/* issue signal */
-		child->mp_flags &= ~TRACED;  /* so signal is not diverted */
-		sig_proc(child, (int) m_in.data);
-		child->mp_flags |= TRACED;
-	}
-	child->mp_flags &= ~STOPPED;
-  	break;
-  }
-  r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data);
-  if (r != OK) return(r);
-
-  mp->mp_reply.reply_trace = m_in.data;
-  return(OK);
-}
-
-/*===========================================================================*
- *				find_proc  				     *
- *===========================================================================*/
-PRIVATE struct mproc *find_proc(lpid)
-pid_t lpid;
-{
-  register struct mproc *rmp;
-
-  for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
-	if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
-  return(NIL_MPROC);
-}
-
-/*===========================================================================*
- *				stop_proc				     *
- *===========================================================================*/
-PUBLIC void stop_proc(rmp, signo)
-register struct mproc *rmp;
-int signo;
-{
-/* A traced process got a signal so stop it. */
-
-  register struct mproc *rpmp = mproc + rmp->mp_parent;
-  int r;
-
-  r= sys_trace(-1, rmp->mp_endpoint, 0L, (long *) 0);
-  if (r != OK) panic("pm", "sys_trace failed", r);
- 
-  rmp->mp_flags |= STOPPED;
-  if (rpmp->mp_flags & WAITING) {
-	rpmp->mp_flags &= ~WAITING;	/* parent is no longer waiting */
-	rpmp->mp_reply.reply_res2 = 0177 | (signo << 8);
-	setreply(rmp->mp_parent, rmp->mp_pid);
-  } else {
-	rmp->mp_sigstatus = signo;
-  }
-  return;
-}
Index: trunk/minix/servers/pm/type.h
===================================================================
--- trunk/minix/servers/pm/type.h	(revision 11)
+++ 	(revision )
@@ -1,5 +1,0 @@
-/* If there were any type definitions local to the Process Manager, they would
- * be here.  This file is included only for symmetry with the kernel and File
- * System, which do have some local type definitions.
- */
-
Index: trunk/minix/servers/pm/utility.c
===================================================================
--- trunk/minix/servers/pm/utility.c	(revision 11)
+++ 	(revision )
@@ -1,239 +1,0 @@
-/* This file contains some utility routines for PM.
- *
- * The entry points are:
- *   find_param:	look up a boot monitor parameter
- *   get_free_pid:	get a free process or group id
- *   allowed:		see if an access is permitted
- *   no_sys:		called for invalid system call numbers
- *   panic:		PM has run aground of a fatal error 
- *   tell_fs:		interface to FS
- *   get_mem_map:	get memory map of given process
- *   get_stack_ptr:	get stack pointer of given process	
- *   proc_from_pid:	return process pointer from pid number
- */
-
-#include "pm.h"
-#include <sys/stat.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include <fcntl.h>
-#include <signal.h>		/* needed only because mproc.h needs it */
-#include "mproc.h"
-#include "param.h"
-
-#include <minix/config.h>
-#include <timers.h>
-#include <string.h>
-#include "../../kernel/const.h"
-#include "../../kernel/config.h"
-#include "../../kernel/type.h"
-#include "../../kernel/proc.h"
-
-/*===========================================================================*
- *				get_free_pid				     *
- *===========================================================================*/
-PUBLIC pid_t get_free_pid()
-{
-  static pid_t next_pid = INIT_PID + 1;		/* next pid to be assigned */
-  register struct mproc *rmp;			/* check process table */
-  int t;					/* zero if pid still free */
-
-  /* Find a free pid for the child and put it in the table. */
-  do {
-	t = 0;			
-	next_pid = (next_pid < NR_PIDS ? next_pid + 1 : INIT_PID + 1);
-	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
-		if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
-			t = 1;
-			break;
-		}
-  } while (t);					/* 't' = 0 means pid free */
-  return(next_pid);
-}
-
-/*===========================================================================*
- *				allowed					     *
- *===========================================================================*/
-PUBLIC int allowed(name_buf, s_buf, mask)
-char *name_buf;			/* pointer to file name to be EXECed */
-struct stat *s_buf;		/* buffer for doing and returning stat struct*/
-int mask;			/* R_BIT, W_BIT, or X_BIT */
-{
-/* Check to see if file can be accessed.  Return EACCES or ENOENT if the access
- * is prohibited.  If it is legal open the file and return a file descriptor.
- */
-  int fd;
-  int save_errno;
-
-  /* Use the fact that mask for access() is the same as the permissions mask.
-   * E.g., X_BIT in <minix/const.h> is the same as X_OK in <unistd.h> and
-   * S_IXOTH in <sys/stat.h>.  tell_fs(DO_CHDIR, ...) has set PM's real ids
-   * to the user's effective ids, so access() works right for setuid programs.
-   */
-  if (access(name_buf, mask) < 0) return(-errno);
-
-  /* The file is accessible but might not be readable.  Make it readable. */
-  tell_fs(SETUID, PM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER);
-
-  /* Open the file and fstat it.  Restore the ids early to handle errors. */
-  fd = open(name_buf, O_RDONLY | O_NONBLOCK);
-  save_errno = errno;		/* open might fail, e.g. from ENFILE */
-  tell_fs(SETUID, PM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid);
-  if (fd < 0) return(-save_errno);
-  if (fstat(fd, s_buf) < 0) panic(__FILE__,"allowed: fstat failed", NO_NUM);
-
-  /* Only regular files can be executed. */
-  if (mask == X_BIT && (s_buf->st_mode & I_TYPE) != I_REGULAR) {
-	close(fd);
-	return(EACCES);
-  }
-  return(fd);
-}
-
-/*===========================================================================*
- *				no_sys					     *
- *===========================================================================*/
-PUBLIC int no_sys()
-{
-/* A system call number not implemented by PM has been requested. */
-
-  return(ENOSYS);
-}
-
-/*===========================================================================*
- *				panic					     *
- *===========================================================================*/
-PUBLIC void panic(who, mess, num)
-char *who;			/* who caused the panic */
-char *mess;			/* panic message string */
-int num;			/* number to go with it */
-{
-/* An unrecoverable error has occurred.  Panics are caused when an internal
- * inconsistency is detected, e.g., a programming error or illegal value of a
- * defined constant. The process manager decides to exit.
- */
-  message m;
-  int s;
-
-  /* Switch to primary console and print panic message. */
-  check_sig(mproc[TTY_PROC_NR].mp_pid, SIGTERM);
-  printf("PM panic (%s): %s", who, mess);
-  if (num != NO_NUM) printf(": %d",num);
-  printf("\n");
-   
-  /* Exit PM. */
-  sys_exit(SELF);
-}
-
-/*===========================================================================*
- *				tell_fs					     *
- *===========================================================================*/
-PUBLIC void tell_fs(what, p1, p2, p3)
-int what, p1, p2, p3;
-{
-/* This routine is only used by PM to inform FS of certain events:
- *      tell_fs(CHDIR, slot, dir, 0)
- *      tell_fs(EXEC, proc, 0, 0)
- *      tell_fs(EXIT, proc, 0, 0)
- *      tell_fs(FORK, parent, child, pid)
- *      tell_fs(SETGID, proc, realgid, effgid)
- *      tell_fs(SETSID, proc, 0, 0)
- *      tell_fs(SETUID, proc, realuid, effuid)
- *      tell_fs(UNPAUSE, proc, signr, 0)
- *      tell_fs(STIME, time, 0, 0)
- * Ignore this call if the FS is already dead, e.g. on shutdown.
- */
-  message m;
-
-  if ((mproc[FS_PROC_NR].mp_flags & (IN_USE|ZOMBIE)) != IN_USE)
-      return;
-
-  m.tell_fs_arg1 = p1;
-  m.tell_fs_arg2 = p2;
-  m.tell_fs_arg3 = p3;
-  _taskcall(FS_PROC_NR, what, &m);
-}
-
-/*===========================================================================*
- *				find_param				     *
- *===========================================================================*/
-PUBLIC char *find_param(name)
-const char *name;
-{
-  register const char *namep;
-  register char *envp;
-
-  for (envp = (char *) monitor_params; *envp != 0;) {
-	for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
-		;
-	if (*namep == '\0' && *envp == '=') 
-		return(envp + 1);
-	while (*envp++ != 0)
-		;
-  }
-  return(NULL);
-}
-
-/*===========================================================================*
- *				get_mem_map				     *
- *===========================================================================*/
-PUBLIC int get_mem_map(proc_nr, mem_map)
-int proc_nr;					/* process to get map of */
-struct mem_map *mem_map;			/* put memory map here */
-{
-  struct proc p;
-  int s;
-
-  if ((s=sys_getproc(&p, proc_nr)) != OK)
-  	return(s);
-  memcpy(mem_map, p.p_memmap, sizeof(p.p_memmap));
-  return(OK);
-}
-
-/*===========================================================================*
- *				get_stack_ptr				     *
- *===========================================================================*/
-PUBLIC int get_stack_ptr(proc_nr_e, sp)
-int proc_nr_e;					/* process to get sp of */
-vir_bytes *sp;					/* put stack pointer here */
-{
-  struct proc p;
-  int s;
-
-  if ((s=sys_getproc(&p, proc_nr_e)) != OK)
-  	return(s);
-  *sp = p.p_reg.sp;
-  return(OK);
-}
-
-/*===========================================================================*
- *				proc_from_pid				     *
- *===========================================================================*/
-PUBLIC int proc_from_pid(mp_pid)
-pid_t mp_pid;
-{
-	int rmp;
-
-	for (rmp = 0; rmp < NR_PROCS; rmp++)
-		if (mproc[rmp].mp_pid == mp_pid)
-			return rmp;
-
-	return -1;
-}
-
-/*===========================================================================*
- *				pm_isokendpt			 	     *
- *===========================================================================*/
-PUBLIC int pm_isokendpt(int endpoint, int *proc)
-{
-	*proc = _ENDPOINT_P(endpoint);
-	if(*proc < -NR_TASKS || *proc >= NR_PROCS)
-		return EINVAL;
-	if(*proc >= 0 && endpoint != mproc[*proc].mp_endpoint)
-		return EDEADSRCDST;
-	if(*proc >= 0 && !(mproc[*proc].mp_flags & IN_USE))
-		return EDEADSRCDST;
-	return OK;
-}
-
