# install -S 256w $@
# install with other servers
-install: /sbin/$(SERVER)
-/sbin/$(SERVER): $(SERVER)
- install -o root -c $? $@
+install: $(SERVER)
+ install -o root -c $? /sbin/$(SERVER)
# install -o root -cs $? $@
# clean up local files
#include "inc.h" /* include master header file */
/* Allocate space for the global variables. */
-int who; /* caller's proc number */
+int who_e; /* caller's proc number */
int callnr; /* system call number */
int sys_panic; /* flag to indicate system-wide panic */
/* Finally send reply message, unless disabled. */
if (result != EDONTREPLY) {
m.m_type = result; /* build reply message */
- reply(who, &m); /* send it away */
+ reply(who_e, &m); /* send it away */
}
}
return(OK); /* shouldn't come here */
status = receive(ANY, m_ptr); /* this blocks until message arrives */
if (OK != status)
panic("DS","failed to receive message!", status);
- who = m_ptr->m_source; /* message arrived! set sender */
+ who_e = m_ptr->m_source; /* message arrived! set sender */
callnr = m_ptr->m_type; /* set function call number */
}
/*===========================================================================*
* reply *
*===========================================================================*/
-PRIVATE void reply(who, m_ptr)
-int who; /* destination */
+PRIVATE void reply(who_e, m_ptr)
+int who_e; /* destination */
message *m_ptr; /* message buffer */
{
int s;
- s = send(who, m_ptr); /* send the message */
+ s = send(who_e, m_ptr); /* send the message */
if (OK != s)
panic("DS", "unable to send reply!", s);
}
#include <fcntl.h>
#include <minix/callnr.h>
#include <minix/com.h>
+#include <minix/endpoint.h>
#include "file.h"
#include "fproc.h"
#include "inode.h"
#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
extern int dmap_size;
+PRIVATE int dummyproc;
/*===========================================================================*
* dev_open *
major = (dev >> MAJOR) & BYTE;
if (major >= NR_DEVICES) major = 0;
dp = &dmap[major];
- if (dp->dmap_driver == NONE) {
+ if (dp->dmap_driver == NONE)
return ENXIO;
- }
r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags);
if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver);
return(r);
switch(st.m_type) {
case DEV_REVIVE:
- revive(st.REP_PROC_NR, st.REP_STATUS);
+ revive(st.REP_ENDPT, st.REP_STATUS);
break;
case DEV_IO_READY:
select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);
/*===========================================================================*
* dev_io *
*===========================================================================*/
-PUBLIC int dev_io(op, dev, proc, buf, pos, bytes, flags)
+PUBLIC int dev_io(op, dev, proc_e, buf, pos, bytes, flags)
int op; /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */
dev_t dev; /* major-minor device number */
-int proc; /* in whose address space is buf? */
+int proc_e; /* in whose address space is buf? */
void *buf; /* virtual address of the buffer */
off_t pos; /* byte position */
int bytes; /* how many bytes to transfer */
/* See if driver is roughly valid. */
if (dp->dmap_driver == NONE) {
printf("FS: dev_io: no driver for dev %x\n", dev);
- return EIO;
+ return ENXIO;
+ }
+
+ if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
+ printf("FS: dev_io: old driver for dev %x (%d)\n",
+ dev, dp->dmap_driver);
+ return ENXIO;
}
/* Set up the message passed to task. */
dev_mess.m_type = op;
dev_mess.DEVICE = (dev >> MINOR) & BYTE;
dev_mess.POSITION = pos;
- dev_mess.PROC_NR = proc;
+ dev_mess.IO_ENDPT = proc_e;
dev_mess.ADDRESS = buf;
dev_mess.COUNT = bytes;
dev_mess.TTY_FLAGS = flags;
/* Call the task. */
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+ if(dp->dmap_driver == NONE)
+ panic(__FILE__,"dev_io: driver changed to NONE", NO_NUM);
+
/* Task has completed. See if call completed. */
if (dev_mess.REP_STATUS == SUSPEND) {
if (flags & O_NONBLOCK) {
/* Not supposed to block. */
dev_mess.m_type = CANCEL;
- dev_mess.PROC_NR = proc;
+ dev_mess.IO_ENDPT = proc_e;
dev_mess.DEVICE = (dev >> MINOR) & BYTE;
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
if (dev_mess.REP_STATUS == EINTR) dev_mess.REP_STATUS = EAGAIN;
/*===========================================================================*
* gen_opcl *
*===========================================================================*/
-PUBLIC int gen_opcl(op, dev, proc, flags)
+PUBLIC int gen_opcl(op, dev, proc_e, flags)
int op; /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev; /* device to open or close */
-int proc; /* process to open/close for */
+int proc_e; /* process to open/close for */
int flags; /* mode bits and flags */
{
/* Called from the dmap struct in table.c on opens & closes of special files.*/
dev_mess.m_type = op;
dev_mess.DEVICE = (dev >> MINOR) & BYTE;
- dev_mess.PROC_NR = proc;
+ dev_mess.IO_ENDPT = proc_e;
dev_mess.COUNT = flags;
+ if (dp->dmap_driver == NONE) {
+ printf("FS: gen_opcl: no driver for dev %x\n", dev);
+ return ENXIO;
+ }
+ if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
+ printf("FS: gen_opcl: old driver for dev %x (%d)\n",
+ dev, dp->dmap_driver);
+ return ENXIO;
+ }
+
/* Call the task. */
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
/*===========================================================================*
* tty_opcl *
*===========================================================================*/
-PUBLIC int tty_opcl(op, dev, proc, flags)
+PUBLIC int tty_opcl(op, dev, proc_e, flags)
int op; /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev; /* device to open or close */
-int proc; /* process to open/close for */
+int proc_e; /* process to open/close for */
int flags; /* mode bits and flags */
{
/* This procedure is called from the dmap struct on tty open/close. */
}
}
- r = gen_opcl(op, dev, proc, flags);
+ r = gen_opcl(op, dev, proc_e, flags);
/* Did this call make the tty the controlling tty? */
if (r == 1) {
/*===========================================================================*
* ctty_opcl *
*===========================================================================*/
-PUBLIC int ctty_opcl(op, dev, proc, flags)
+PUBLIC int ctty_opcl(op, dev, proc_e, flags)
int op; /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev; /* device to open or close */
-int proc; /* process to open/close for */
+int proc_e; /* process to open/close for */
int flags; /* mode bits and flags */
{
/* This procedure is called from the dmap struct in table.c on opening/closing
* terminal of a process, and make the process a session leader.
*/
register struct fproc *rfp;
+ int slot;
/* Only MM may do the SETSID call directly. */
- if (who != PM_PROC_NR) return(ENOSYS);
+ if (who_e != PM_PROC_NR) return(ENOSYS);
/* Make the process a session leader with no controlling tty. */
- rfp = &fproc[m_in.slot1];
+ okendpt(m_in.endpt1, &slot);
+ rfp = &fproc[slot];
rfp->fp_sesldr = TRUE;
rfp->fp_tty = 0;
return(OK);
dev_mess = m; /* Copy full message with all the weird bits. */
dev_mess.m_type = DEV_IOCTL;
- dev_mess.PROC_NR = who;
+ dev_mess.PROC_NR = who_e;
dev_mess.TTY_LINE = (dev >> MINOR) & BYTE;
/* Call the task. */
+
+ if (dp->dmap_driver == NONE) {
+ printf("FS: do_ioctl: no driver for dev %x\n", dev);
+ return ENXIO;
+ }
+
+ if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
+ printf("FS: do_ioctl: old driver for dev %x (%d)\n",
+ dev, dp->dmap_driver);
+ return ENXIO;
+ }
+
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
m_out.TTY_SPEK = dev_mess.TTY_SPEK; /* erase and kill */
}
#endif
- return(dev_io(DEV_IOCTL, dev, who, m_in.ADDRESS, 0L,
+ return(dev_io(DEV_IOCTL, dev, who_e, m_in.ADDRESS, 0L,
m_in.REQUEST, f->filp_flags));
}
* pairs. These lead to calls on the following routines via the dmap table.
*/
- int r, proc_nr;
+ int r, proc_e, dummy_proc;
message local_m;
- proc_nr = mess_ptr->PROC_NR;
- if (! isokprocnr(proc_nr)) {
- printf("FS: warning, got illegal process number (%d) from %d\n",
- mess_ptr->PROC_NR, mess_ptr->m_source);
- return;
- }
+ proc_e = mess_ptr->IO_ENDPT;
+#if DEAD_CODE
while ((r = sendrec(task_nr, mess_ptr)) == ELOCKED) {
/* sendrec() failed to avoid deadlock. The task 'task_nr' is
* trying to send a REVIVE message for an earlier request.
* sent a completion reply, ignore the reply and abort the cancel
* request. The caller will do the revive for the process.
*/
- if (mess_ptr->m_type == CANCEL && local_m.REP_PROC_NR == proc_nr) {
+ if (mess_ptr->m_type == CANCEL && local_m.REP_ENDPT == proc_e) {
return;
}
printf(
"fs: strange device reply from %d, type = %d, proc = %d (1)\n",
local_m.m_source,
- local_m.m_type, local_m.REP_PROC_NR);
+ local_m.m_type, local_m.REP_ENDPT);
continue;
}
- revive(local_m.REP_PROC_NR, local_m.REP_STATUS);
+ revive(local_m.REP_ENDPT, local_m.REP_STATUS);
}
+#endif
/* The message received may be a reply to this call, or a REVIVE for some
* other process.
*/
- for (;;) {
+ r = sendrec(task_nr, mess_ptr);
+ for(;;) {
if (r != OK) {
- if (r == EDEADSRCDST) return; /* give up */
- if (r == EDSTDIED) return;
- if (r == ESRCDIED) return;
- if (r == ELOCKED) return;
- else panic(__FILE__,"call_task: can't send/receive", r);
+ if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
+ printf("fs: dead driver %d\n", task_nr);
+ return;
+ }
+ if (r == ELOCKED) {
+ printf("fs: ELOCKED talking to %d\n", task_nr);
+ return;
+ }
+ panic(__FILE__,"call_task: can't send/receive", r);
}
/* Did the process we did the sendrec() for get a result? */
- if (mess_ptr->REP_PROC_NR == proc_nr) {
+ if (mess_ptr->REP_ENDPT == proc_e) {
break;
} else if (mess_ptr->m_type == REVIVE) {
/* Otherwise it should be a REVIVE. */
- revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS);
+ revive(mess_ptr->REP_ENDPT, mess_ptr->REP_STATUS);
} else {
printf(
- "fs: strange device reply from %d, type = %d, proc = %d (2)\n",
+ "fs: strange device reply from %d, type = %d, proc = %d (2) ignored\n",
mess_ptr->m_source,
- mess_ptr->m_type, mess_ptr->REP_PROC_NR);
- return;
+ mess_ptr->m_type, mess_ptr->REP_ENDPT);
}
-
r = receive(task_nr, mess_ptr);
}
}
/* Substitute the controlling terminal device. */
dp = &dmap[(fp->fp_tty >> MAJOR) & BYTE];
mess_ptr->DEVICE = (fp->fp_tty >> MINOR) & BYTE;
+
+ if (dp->dmap_driver == NONE) {
+ printf("FS: ctty_io: no driver for dev\n");
+ return;
+ }
+
+ if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
+ printf("FS: ctty_io: old driver %d\n",
+ dp->dmap_driver);
+ return;
+ }
+
(*dp->dmap_io)(dp->dmap_driver, mess_ptr);
}
}
/*===========================================================================*
* clone_opcl *
*===========================================================================*/
-PUBLIC int clone_opcl(op, dev, proc, flags)
+PUBLIC int clone_opcl(op, dev, proc_e, flags)
int op; /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev; /* device to open or close */
-int proc; /* process to open/close for */
+int proc_e; /* process to open/close for */
int flags; /* mode bits and flags */
{
/* Some devices need special processing upon open. Such a device is "cloned",
dev_mess.m_type = op;
dev_mess.DEVICE = minor;
- dev_mess.PROC_NR = proc;
+ dev_mess.IO_ENDPT = proc_e;
dev_mess.COUNT = flags;
+
+ if (dp->dmap_driver == NONE) {
+ printf("FS: clone_opcl: no driver for dev %x\n", dev);
+ return ENXIO;
+ }
+
+ if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
+ printf("FS: clone_opcl: old driver for dev %x (%d)\n",
+ dev, dp->dmap_driver);
+ return ENXIO;
+ }
+
/* Call the task. */
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
ip = alloc_inode(root_dev, ALL_MODES | I_CHAR_SPECIAL);
if (ip == NIL_INODE) {
/* Oops, that didn't work. Undo open. */
- (void) clone_opcl(DEV_CLOSE, dev, proc, 0);
+ (void) clone_opcl(DEV_CLOSE, dev, proc_e, 0);
return(err_code);
}
ip->i_zone[0] = dev;
/*===========================================================================*
* map_driver *
*===========================================================================*/
-PUBLIC int map_driver(major, proc_nr, style)
+PUBLIC int map_driver(major, proc_nr_e, style)
int major; /* major number of the device */
-int proc_nr; /* process number of the driver */
+int proc_nr_e; /* process number of the driver */
int style; /* style of the device */
{
/* Set a new device driver mapping in the dmap table. Given that correct
* a system call that tries to dynamically install a new driver.
*/
struct dmap *dp;
+ int proc_nr_n;
/* Get pointer to device entry in the dmap table. */
if (major < 0 || major >= NR_DEVICES) return(ENODEV);
* if busy or unmutable, as unmap is called when driver has
* exited.
*/
- if(proc_nr == NONE) {
+ if(proc_nr_e == NONE) {
dp->dmap_opcl = no_dev;
dp->dmap_io = no_dev_io;
dp->dmap_driver = NONE;
if (dp->dmap_flags & DMAP_BUSY) return(EBUSY);
/* Check process number of new driver. */
- if (! isokprocnr(proc_nr)) return(EINVAL);
+ if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
+ return(EINVAL);
/* Try to update the entry. */
switch (style) {
default: return(EINVAL);
}
dp->dmap_io = gen_io;
- dp->dmap_driver = proc_nr;
+ dp->dmap_driver = proc_nr_e;
/* If a driver has completed its exec(), it can be announced to be up. */
- if(fproc[proc_nr].fp_execced) {
+ if(fproc[proc_nr_n].fp_execced) {
dev_up(major);
} else {
dp->dmap_flags |= DMAP_BABY;
}
/*===========================================================================*
- * dmap_unmap_by_proc *
+ * dmap_unmap_by_endpt *
*===========================================================================*/
-PUBLIC void dmap_unmap_by_proc(int proc_nr)
+PUBLIC void dmap_unmap_by_endpt(int proc_nr_e)
{
int i, r;
for (i=0; i<NR_DEVICES; i++)
- if(dmap[i].dmap_driver && dmap[i].dmap_driver == proc_nr)
+ if(dmap[i].dmap_driver && dmap[i].dmap_driver == proc_nr_e)
if((r=map_driver(i, NONE, 0)) != OK)
- printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr, i, r);
+ printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr_e,i,r);
return;
}
/*===========================================================================*
- * dmap_proc_up *
+ * dmap_endpt_up *
*===========================================================================*/
-PUBLIC void dmap_proc_up(int proc)
+PUBLIC void dmap_endpt_up(int proc_e)
{
int i;
for (i=0; i<NR_DEVICES; i++) {
if(dmap[i].dmap_driver != NONE
- && dmap[i].dmap_driver == proc
+ && dmap[i].dmap_driver == proc_e
&& (dmap[i].dmap_flags & DMAP_BABY)) {
dmap[i].dmap_flags &= ~DMAP_BABY;
dev_up(i);
int fp_cum_io_partial; /* partial byte count if rd/wr can't finish */
char fp_suspended; /* set to indicate process hanging */
char fp_revived; /* set to indicate process being revived */
- char fp_task; /* which task is proc suspended on */
+ int fp_task; /* which task is proc suspended on */
char fp_sesldr; /* true if proc is a session leader */
char fp_execced; /* true if proc has exec()ced after fork */
pid_t fp_pid; /* process id */
long fp_cloexec; /* bit map for POSIX Table 6-2 FD_CLOEXEC */
+ int fp_endpoint; /* kernel endpoint number of this process */
} fproc[NR_PROCS];
/* Field values. */
/* The parameters of the call are kept here. */
EXTERN message m_in; /* the input message itself */
EXTERN message m_out; /* the output message used for reply */
-EXTERN int who; /* caller's proc number */
+EXTERN int who_p, who_e; /* caller's proc number, endpoint */
EXTERN int call_nr; /* system call number */
EXTERN char user_path[PATH_MAX];/* storage for user path name */
/* Fetch the flock structure from user space. */
user_flock = (vir_bytes) m_in.name1;
- r = sys_datacopy(who, (vir_bytes) user_flock,
+ r = sys_datacopy(who_e, (vir_bytes) user_flock,
FS_PROC_NR, (vir_bytes) &flock, (phys_bytes) sizeof(flock));
if (r != OK) return(EINVAL);
/* Copy the flock structure back to the caller. */
r = sys_datacopy(FS_PROC_NR, (vir_bytes) &flock,
- who, (vir_bytes) user_flock, (phys_bytes) sizeof(flock));
+ who_e, (vir_bytes) user_flock, (phys_bytes) sizeof(flock));
return(r);
}
for (fptr = &fproc[INIT_PROC_NR + 1]; fptr < &fproc[NR_PROCS]; fptr++){
task = -fptr->fp_task;
if (fptr->fp_suspended == SUSPENDED && task == XLOCK) {
- revive( (int) (fptr - fproc), 0);
+ revive(fptr->fp_endpoint, 0);
}
}
}
#include <minix/com.h>
#include <minix/keymap.h>
#include <minix/const.h>
+#include <minix/endpoint.h>
#include "buf.h"
#include "file.h"
#include "fproc.h"
fs_init();
+
/* This is the main loop that gets work, processes it, and sends replies. */
while (TRUE) {
get_work(); /* sets who and call_nr */
- fp = &fproc[who]; /* pointer to proc table struct */
+ fp = &fproc[who_p]; /* pointer to proc table struct */
super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */
/* Check for special control messages first. */
/* Call the internal function that does the work. */
if (call_nr < 0 || call_nr >= NCALLS) {
error = ENOSYS;
- printf("FS, warning illegal %d system call by %d\n", call_nr, who);
+ printf("FS, warning illegal %d system call by %d\n", call_nr, who_e);
} else if (fp->fp_pid == PID_FREE) {
error = ENOSYS;
- printf("FS, bad process, who = %d, call_nr = %d, slot1 = %d\n",
- who, call_nr, m_in.slot1);
+ printf("FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n",
+ who_e, call_nr, m_in.endpt1);
} else {
error = (*call_vec[call_nr])();
}
/* Copy the results back to the user and send reply. */
- if (error != SUSPEND) { reply(who, error); }
+ if (error != SUSPEND) { reply(who_e, error); }
if (rdahed_inode != NIL_INODE) {
read_ahead(); /* do block read ahead */
}
* nonzero, a suspended process must be awakened.
*/
register struct fproc *rp;
+ int l = 0;
if (reviving != 0) {
/* Revive a suspended process. */
for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++)
if (rp->fp_revived == REVIVING) {
- who = (int)(rp - fproc);
+ who_p = (int)(rp - fproc);
+ who_e = rp->fp_endpoint;
call_nr = rp->fp_fd & BYTE;
m_in.fd = (rp->fp_fd >>8) & BYTE;
m_in.buffer = rp->fp_buffer;
panic(__FILE__,"get_work couldn't revive anyone", NO_NUM);
}
- /* Normal case. No one to revive. */
- if (receive(ANY, &m_in) != OK) panic(__FILE__,"fs receive error", NO_NUM);
- who = m_in.m_source;
- call_nr = m_in.m_type;
+ for(;;) {
+ /* Normal case. No one to revive. */
+ if (receive(ANY, &m_in) != OK)
+ panic(__FILE__,"fs receive error", NO_NUM);
+ who_e = m_in.m_source;
+ who_p = _ENDPOINT_P(who_e);
+ if(who_p < -NR_TASKS || who_p >= NR_PROCS)
+ panic(__FILE__,"receive process out of range", who_p);
+ if(who_p >= 0 && fproc[who_p].fp_endpoint == NONE) {
+ printf("FS: ignoring request from %d, endpointless slot %d (%d)",
+ m_in.m_source, who_p, m_in.m_type);
+ continue;
+ }
+ if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) {
+ printf("FS: receive endpoint inconsistent (%d, %d), ignoring %d",
+ fproc[who_p].fp_endpoint, who_e, m_in.m_type);
+ continue;
+ }
+ call_nr = m_in.m_type;
+ return;
+ }
}
/*===========================================================================*
int s;
m_out.reply_type = result;
s = send(whom, &m_out);
- if (s != OK) printf("FS: couldn't send reply %d: %d\n", result, s);
+ if (s != OK) printf("FS: couldn't send reply %d to %d: %d\n",
+ result, whom, s);
}
/*===========================================================================*
* Then, stop and synchronize with the PM.
*/
do {
+ int slot;
if (OK != (s=receive(PM_PROC_NR, &mess)))
panic(__FILE__,"FS couldn't receive from PM", s);
- if (NONE == mess.PR_PROC_NR) break;
+ if (NONE == mess.PR_ENDPT) break;
- rfp = &fproc[mess.PR_PROC_NR];
+ rfp = &fproc[mess.PR_SLOT];
rfp->fp_pid = mess.PR_PID;
+ rfp->fp_endpoint = mess.PR_ENDPT;
rfp->fp_realuid = (uid_t) SYS_UID;
rfp->fp_effuid = (uid_t) SYS_UID;
rfp->fp_realgid = (gid_t) SYS_GID;
/* The following initializations are needed to let dev_opcl succeed .*/
fp = (struct fproc *) NULL;
- who = FS_PROC_NR;
+ who_e = who_p = FS_PROC_NR;
buf_pool(); /* initialize buffer pool */
build_dmap(); /* build device table and map boot driver */
dup_inode(rip);
rfp->fp_rootdir = rip;
rfp->fp_workdir = rip;
- }
+ } else rfp->fp_endpoint = NONE;
}
}
/* Tell RAM driver how big the RAM disk must be. */
m_out.m_type = DEV_IOCTL;
- m_out.PROC_NR = FS_PROC_NR;
+ m_out.PR_ENDPT = FS_PROC_NR;
m_out.DEVICE = RAM_DEV;
m_out.REQUEST = MIOCRAMSIZE; /* I/O control to use */
m_out.POSITION = (ram_size_kb * 1024); /* request in bytes */
#include <fcntl.h>
#include <unistd.h> /* cc runs out of memory with unistd.h :-( */
#include <minix/callnr.h>
+#include <minix/endpoint.h>
#include <minix/com.h>
#include <sys/svrctl.h>
#include "buf.h"
}
dst_addr = (vir_bytes) m_in.info_where;
- if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
+ if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len)))
return(s);
return(OK);
}
/* Copy flock data from userspace. */
- if((r = sys_datacopy(who, (vir_bytes) m_in.name1,
+ if((r = sys_datacopy(who_e, (vir_bytes) m_in.name1,
SELF, (vir_bytes) &flock_arg,
(phys_bytes) sizeof(flock_arg))) != OK)
return r;
struct inode dummy;
/* Only PM may make this call directly. */
- if (who != PM_PROC_NR) return(EGENERIC);
+ if (who_e != PM_PROC_NR) return(EGENERIC);
/* Do exit processing for all leftover processes and servers. */
- for (i = 0; i < NR_PROCS; i++) { m_in.slot1 = i; do_exit(); }
+ for (i = 0; i < NR_PROCS; i++) {
+ if((m_in.endpt1 = fproc[i].fp_endpoint) != NONE)
+ do_exit();
+ }
/* The root file system is mounted onto itself, which keeps it from being
* unmounted. Pull an inode out of thin air and put the root on it.
*/
register struct fproc *cp;
- int i;
+ int i, parentno, childno;
/* Only PM may make this call directly. */
- if (who != PM_PROC_NR) return(EGENERIC);
+ if (who_e != PM_PROC_NR) return(EGENERIC);
+
+ /* Check up-to-dateness of fproc. */
+ okendpt(m_in.parent_endpt, &parentno);
+
+ /* PM gives child endpoint, which implies process slot information.
+ * Don't call isokendpt, because that will verify if the endpoint
+ * number is correct in fproc, which it won't be.
+ */
+ childno = _ENDPOINT_P(m_in.child_endpt);
+ if(childno < 0 || childno >= NR_PROCS)
+ panic(__FILE__, "FS: bogus child for forking", m_in.child_endpt);
+ if(fproc[childno].fp_pid != PID_FREE)
+ panic(__FILE__, "FS: forking on top of in-use child", childno);
/* Copy the parent's fproc struct to the child. */
- fproc[m_in.child] = fproc[m_in.parent];
+ fproc[childno] = fproc[parentno];
/* Increase the counters in the 'filp' table. */
- cp = &fproc[m_in.child];
+ cp = &fproc[childno];
for (i = 0; i < OPEN_MAX; i++)
if (cp->fp_filp[i] != NIL_FILP) cp->fp_filp[i]->filp_count++;
- /* Fill in new process id. */
+ /* Fill in new process and endpoint id. */
cp->fp_pid = m_in.pid;
+ cp->fp_endpoint = m_in.child_endpt;
/* A child is not a process leader. */
cp->fp_sesldr = 0;
* MM does an EXEC, it calls FS to allow FS to find these files and close them.
*/
- register int i;
+ int i, proc;
long bitmap;
/* Only PM may make this call directly. */
- if (who != PM_PROC_NR) return(EGENERIC);
+ if (who_e != PM_PROC_NR) return(EGENERIC);
/* The array of FD_CLOEXEC bits is in the fp_cloexec bit map. */
- fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */
+ okendpt(m_in.endpt1, &proc);
+ fp = &fproc[proc]; /* get_filp() needs 'fp' */
bitmap = fp->fp_cloexec;
if (bitmap) {
/* Check the file desriptors one by one for presence of FD_CLOEXEC. */
fp->fp_execced = 1;
/* Reply to caller (PM) directly. */
- reply(who, OK);
+ reply(who_e, OK);
/* Check if this is a driver that can now be useful. */
- dmap_proc_up(fp - fproc);
+ dmap_endpt_up(fp->fp_endpoint);
/* Suppress reply to caller (caller already replied to). */
return SUSPEND;
{
/* Perform the file system portion of the exit(status) system call. */
- register int i, exitee, task;
+ int i, exitee_p, exitee_e, task;
register struct fproc *rfp;
register struct filp *rfilp;
register struct inode *rip;
dev_t dev;
/* Only PM may do the EXIT call directly. */
- if (who != PM_PROC_NR) return(EGENERIC);
+ if (who_e != PM_PROC_NR) return(EGENERIC);
/* Nevertheless, pretend that the call came from the user. */
- fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */
- exitee = m_in.slot1;
+ exitee_e = m_in.endpt1;
+ okendpt(exitee_e, &exitee_p);
+ fp = &fproc[exitee_p]; /* get_filp() needs 'fp' */
if (fp->fp_suspended == SUSPENDED) {
task = -fp->fp_task;
if (task == XPIPE || task == XPOPEN) susp_count--;
- m_in.pro = exitee;
+ m_in.ENDPT = exitee_e;
(void) do_unpause(); /* this always succeeds for MM */
fp->fp_suspended = NOT_SUSPENDED;
}
* (unmapping has to be done after the first step, because the
* dmap table is used in the first step.)
*/
- unsuspend_by_proc(exitee);
- dmap_unmap_by_proc(exitee);
+ unsuspend_by_endpt(exitee_e);
+ dmap_unmap_by_endpt(exitee_e);
+
+ /* Invalidate endpoint number for error and sanity checks. */
+ fp->fp_endpoint = NONE;
/* If a session leader exits then revoke access to its controlling tty from
* all other processes using it.
/* Set uid_t or gid_t field. */
register struct fproc *tfp;
+ int proc;
/* Only PM may make this call directly. */
- if (who != PM_PROC_NR) return(EGENERIC);
+ if (who_e != PM_PROC_NR) return(EGENERIC);
- tfp = &fproc[m_in.slot1];
+ okendpt(m_in.endpt1, &proc);
+ tfp = &fproc[proc];
if (call_nr == SETUID) {
tfp->fp_realuid = (uid_t) m_in.real_user_id;
tfp->fp_effuid = (uid_t) m_in.eff_user_id;
* 'SUSPEND' pseudo error, and the reply to the blocked process is done
* explicitly in revive().
*/
-
- revive(m_in.REP_PROC_NR, m_in.REP_STATUS);
+ revive(m_in.REP_ENDPT, m_in.REP_STATUS);
return(SUSPEND); /* don't reply to the TTY task */
}
return(EPERM);
/* Try to copy request structure to FS. */
- if ((r = sys_datacopy(who, (vir_bytes) m_in.svrctl_argp,
+ if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp,
FS_PROC_NR, (vir_bytes) &device,
(phys_bytes) sizeof(device))) != OK)
return(r);
/* Try to update device mapping. */
major = (device.dev >> MAJOR) & BYTE;
- r=map_driver(major, who, device.style);
+ r=map_driver(major, who_e, device.style);
return(r);
}
case FSDEVUNMAP: {
struct fsdevunmap fdu;
int r, major;
/* Try to copy request structure to FS. */
- if ((r = sys_datacopy(who, (vir_bytes) m_in.svrctl_argp,
+ if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp,
FS_PROC_NR, (vir_bytes) &fdu,
(phys_bytes) sizeof(fdu))) != OK)
return(r);
if (sp == NIL_SUPER) return(ENFILE); /* no super block available */
/* Open the device the file system lives on. */
- if (dev_open(dev, who, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK)
+ if (dev_open(dev, who_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK)
return(EINVAL);
/* Make the cache forget about blocks it has open on the filesystem */
case I_BLOCK_SPECIAL:
/* Invoke the driver for special processing. */
dev = (dev_t) rip->i_zone[0];
- r = dev_open(dev, who, bits | (oflags & ~O_ACCMODE));
+ r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
break;
case I_NAMED_PIPE:
if ((r = err_code) == OK) {
r = (bp = new_block(sip, (off_t) 0)) == NIL_BUF
? err_code
- : sys_vircopy(who, D, (vir_bytes) m_in.name1,
+ : sys_vircopy(who_e, D, (vir_bytes) m_in.name1,
SELF, D, (vir_bytes) bp->b_data,
(vir_bytes) m_in.name1_length-1);
#define acc_time m2_l1
#define addr m1_i3
#define buffer m1_p1
-#define child m1_i2
+#define child_endpt m1_i2
#define co_mode m1_i1
#define eff_grp_id m1_i3
#define eff_user_id m1_i3
#define name2_length m1_i2
#define nbytes m1_i2
#define owner m1_i2
-#define parent m1_i1
+#define parent_endpt m1_i1
#define pathname m3_ca1
#define pid m1_i3
-#define pro m1_i1
+#define ENDPT m1_i1
#define ctl_req m4_l1
#define driver_nr m4_l2
#define dev_nr m4_l3
#define real_user_id m1_i2
#define request m1_i2
#define sig m1_i2
-#define slot1 m1_i1
+#define endpt1 m1_i1
#define tp m2_l1
#define utime_actime m2_l1
#define utime_modtime m2_l2
* release: check to see if a suspended process can be released and do
* it
* revive: mark a suspended process as able to run again
- * unsuspend_by_proc: revive all processes blocking on a given process
+ * unsuspend_by_endpt: revive all processes blocking on a given process
* do_unpause: a signal has been sent to a process; see if it suspended
*/
#include <fcntl.h>
#include <signal.h>
#include <minix/callnr.h>
+#include <minix/endpoint.h>
#include <minix/com.h>
#include <sys/select.h>
#include <sys/time.h>
/* Process is writing to a pipe. */
if (find_filp(rip, R_BIT) == NIL_FILP) {
/* Tell kernel to generate a SIGPIPE signal. */
- if (!notouch)
- sys_kill((int)(fp - fproc), SIGPIPE);
+ if (!notouch) {
+ sys_kill(fp->fp_endpoint, SIGPIPE);
+ }
return(EPIPE);
}
if (task == XPIPE || task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/
fp->fp_suspended = SUSPENDED;
fp->fp_fd = m_in.fd << 8 | call_nr;
+ if(task == NONE)
+ panic(__FILE__,"suspend on NONE",NO_NUM);
fp->fp_task = -task;
if (task == XLOCK) {
fp->fp_buffer = (char *) m_in.name1; /* third arg to fcntl() */
}
/*===========================================================================*
- * unsuspend_by_proc *
+ * unsuspend_by_endpt *
*===========================================================================*/
-PUBLIC void unsuspend_by_proc(int proc)
+PUBLIC void unsuspend_by_endpt(int proc_e)
{
struct fproc *rp;
int client = 0;
* disappeared with return code EAGAIN.
*/
for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++, client++)
- if(rp->fp_suspended == SUSPENDED && rp->fp_task == -proc)
- revive(client, EAGAIN);
+ if(rp->fp_suspended == SUSPENDED && rp->fp_task == -proc_e) {
+ revive(rp->fp_endpoint, EAGAIN);
+ }
/* Revive processes waiting in drivers on select()s
* with EAGAIN too.
*/
- select_unsuspend_by_proc(proc);
+ select_unsuspend_by_endpt(proc_e);
return;
}
rp->fp_revived == NOT_REVIVING &&
(rp->fp_fd & BYTE) == call_nr &&
rp->fp_filp[rp->fp_fd>>8]->filp_ino == ip) {
- revive((int)(rp - fproc), 0);
+ revive(rp->fp_endpoint, 0);
susp_count--; /* keep track of who is suspended */
if (--count == 0) return;
}
/*===========================================================================*
* revive *
*===========================================================================*/
-PUBLIC void revive(proc_nr, returned)
-int proc_nr; /* process to revive */
+PUBLIC void revive(proc_nr_e, returned)
+int proc_nr_e; /* process to revive */
int returned; /* if hanging on task, how many bytes read */
{
/* Revive a previously blocked process. When a process hangs on tty, this
register struct fproc *rfp;
register int task;
+ int proc_nr;
+
+ if(isokendpt(proc_nr_e, &proc_nr) != OK)
+ return;
- if (proc_nr < 0 || proc_nr >= NR_PROCS)
- panic(__FILE__,"revive err", proc_nr);
rfp = &fproc[proc_nr];
if (rfp->fp_suspended == NOT_SUSPENDED || rfp->fp_revived == REVIVING)return;
} else {
rfp->fp_suspended = NOT_SUSPENDED;
if (task == XPOPEN) /* process blocked in open or create */
- reply(proc_nr, rfp->fp_fd>>8);
+ reply(proc_nr_e, rfp->fp_fd>>8);
else if (task == XSELECT) {
- reply(proc_nr, returned);
+ reply(proc_nr_e, returned);
} else {
/* Revive a process suspended on TTY or other device. */
rfp->fp_nbytes = returned; /*pretend it wants only what there is*/
- reply(proc_nr, returned); /* unblock the process */
+ reply(proc_nr_e, returned); /* unblock the process */
}
}
}
*/
register struct fproc *rfp;
- int proc_nr, task, fild;
+ int proc_nr_e, proc_nr_p, task, fild;
struct filp *f;
dev_t dev;
message mess;
- if (who > PM_PROC_NR) return(EPERM);
- proc_nr = m_in.pro;
- if (proc_nr < 0 || proc_nr >= NR_PROCS)
- panic(__FILE__,"unpause err 1", proc_nr);
- rfp = &fproc[proc_nr];
+ if (who_e != PM_PROC_NR) return(EPERM);
+ proc_nr_e = m_in.ENDPT;
+ okendpt(proc_nr_e, &proc_nr_p);
+ rfp = &fproc[proc_nr_p];
if (rfp->fp_suspended == NOT_SUSPENDED) return(OK);
task = -rfp->fp_task;
break;
case XSELECT: /* process blocking on select() */
- select_forget(proc_nr);
+ select_forget(proc_nr_e);
break;
case XPOPEN: /* process trying to open a fifo */
f = rfp->fp_filp[fild];
dev = (dev_t) f->filp_ino->i_zone[0]; /* device hung on */
mess.TTY_LINE = (dev >> MINOR) & BYTE;
- mess.PROC_NR = proc_nr;
+ mess.IO_ENDPT = proc_nr_e;
/* Tell kernel R or W. Mode is from current call, not open. */
mess.COUNT = (rfp->fp_fd & BYTE) == READ ? R_BIT : W_BIT;
}
rfp->fp_suspended = NOT_SUSPENDED;
- reply(proc_nr, EINTR); /* signal interrupted call */
+ reply(proc_nr_e, EINTR); /* signal interrupted call */
return(OK);
}
_PROTOTYPE( void build_dmap, (void) );
_PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style) );
_PROTOTYPE( int dmap_driver_match, (int proc, int major) );
-_PROTOTYPE( void dmap_unmap_by_proc, (int proc_nr) );
-_PROTOTYPE( void dmap_proc_up, (int proc_nr) );
+_PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr) );
+_PROTOTYPE( void dmap_endpt_up, (int proc_nr) );
/* filedes.c */
_PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits) );
_PROTOTYPE( int select_request_pipe, (struct filp *f, int *ops, int bl) );
_PROTOTYPE( int select_cancel_pipe, (struct filp *f) );
_PROTOTYPE( int select_match_pipe, (struct filp *f) );
-_PROTOTYPE( void unsuspend_by_proc, (int) );
+_PROTOTYPE( void unsuspend_by_endpt, (int) );
/* protect.c */
_PROTOTYPE( int do_access, (void) );
_PROTOTYPE( long conv4, (int norm, long x) );
_PROTOTYPE( int fetch_name, (char *path, int len, int flag) );
_PROTOTYPE( int no_sys, (void) );
+_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft));
_PROTOTYPE( void panic, (char *who, char *mess, int num) );
+#define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)
+#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0)
+
/* write.c */
_PROTOTYPE( void clear_zone, (struct inode *rip, off_t pos, int flag) );
_PROTOTYPE( int do_write, (void) );
_PROTOTYPE( void select_forget, (int fproc) );
_PROTOTYPE( void select_timeout_check, (timer_t *) );
_PROTOTYPE( void init_select, (void) );
-_PROTOTYPE( void select_unsuspend_by_proc, (int proc) );
+_PROTOTYPE( void select_unsuspend_by_endpt, (int proc) );
_PROTOTYPE( int select_notified, (int major, int minor, int ops) );
/* timers.c */
#include "fs.h"
#include <fcntl.h>
+#include <unistd.h>
#include <minix/com.h>
#include "buf.h"
#include "file.h"
int completed, r2 = OK;
phys_bytes p;
- /* left unfinished rw_chunk()s from previous call! this can't happen.
- * it means something has gone wrong we can't repair now.
+ /* PM loads segments by putting funny things in other bits of the
+ * message, indicated by a high bit in fd.
*/
- if (bufs_in_use < 0) {
- panic(__FILE__,"start - bufs_in_use negative", bufs_in_use);
- }
-
- /* MM loads segments by putting funny things in upper 10 bits of 'fd'. */
- if (who == PM_PROC_NR && (m_in.fd & (~BYTE)) ) {
- usr = m_in.fd >> 7;
- seg = (m_in.fd >> 5) & 03;
- m_in.fd &= 037; /* get rid of user and segment bits */
+ if (who_e == PM_PROC_NR && (m_in.fd & _PM_SEG_FLAG)) {
+ seg = (int) m_in.m1_p2;
+ usr = (int) m_in.m1_p3;
+ m_in.fd &= ~(_PM_SEG_FLAG); /* get rid of flag bit */
} else {
- usr = who; /* normal case */
+ usr = who_e; /* normal case */
seg = D;
}
* if not, copying will fail later.
* do this after 0-check above because umap doesn't want to map 0 bytes.
*/
- if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK)
+ if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) {
+ printf("FS: read_write: umap failed for process %d\n", usr);
return r;
+ }
position = f->filp_pos;
oflags = f->filp_flags;
rip = f->filp_ino;
fp->fp_cum_io_partial = 0;
return(cum_io);
}
- if (bufs_in_use < 0) {
- panic(__FILE__,"end - bufs_in_use negative", bufs_in_use);
- }
return(r);
}
* do_select: perform the SELECT system call
* select_callback: notify select system of possible fd operation
* select_notified: low-level entry for device notifying select
- * select_unsuspend_by_proc: cancel a blocking select on exiting driver
+ * select_unsuspend_by_endpt: cancel a blocking select on exiting driver
*
* Changes:
* 6 june 2005 Created (Ben Gras)
PRIVATE struct selectentry {
struct fproc *requestor; /* slot is free iff this is NULL */
- int req_procnr;
+ int req_endpt;
fd_set readfds, writefds, errorfds;
fd_set ready_readfds, ready_writefds, ready_errorfds;
fd_set *vir_readfds, *vir_writefds, *vir_errorfds;
{
if (e->vir_readfds)
sys_vircopy(SELF, D, (vir_bytes) &e->ready_readfds,
- e->req_procnr, D, (vir_bytes) e->vir_readfds, sizeof(fd_set));
+ e->req_endpt, D, (vir_bytes) e->vir_readfds, sizeof(fd_set));
if (e->vir_writefds)
sys_vircopy(SELF, D, (vir_bytes) &e->ready_writefds,
- e->req_procnr, D, (vir_bytes) e->vir_writefds, sizeof(fd_set));
+ e->req_endpt, D, (vir_bytes) e->vir_writefds, sizeof(fd_set));
if (e->vir_errorfds)
sys_vircopy(SELF, D, (vir_bytes) &e->ready_errorfds,
- e->req_procnr, D, (vir_bytes) e->vir_errorfds, sizeof(fd_set));
+ e->req_endpt, D, (vir_bytes) e->vir_errorfds, sizeof(fd_set));
return;
}
if (s >= MAXSELECTS)
return ENOSPC;
- selecttab[s].req_procnr = who;
+ selecttab[s].req_endpt = who_e;
selecttab[s].nfds = 0;
selecttab[s].nreadyfds = 0;
memset(selecttab[s].filps, 0, sizeof(selecttab[s].filps));
/* copy args */
if (selecttab[s].vir_readfds
- && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_READFDS,
+ && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_READFDS,
SELF, D, (vir_bytes) &selecttab[s].readfds, sizeof(fd_set))) != OK)
return r;
if (selecttab[s].vir_writefds
- && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_WRITEFDS,
+ && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_WRITEFDS,
SELF, D, (vir_bytes) &selecttab[s].writefds, sizeof(fd_set))) != OK)
return r;
if (selecttab[s].vir_errorfds
- && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_ERRORFDS,
+ && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_ERRORFDS,
SELF, D, (vir_bytes) &selecttab[s].errorfds, sizeof(fd_set))) != OK)
return r;
if (!m_in.SEL_TIMEOUT)
is_timeout = nonzero_timeout = 0;
else
- if ((r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_TIMEOUT,
+ if ((r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_TIMEOUT,
SELF, D, (vir_bytes) &timeout, sizeof(timeout))) != OK)
return r;
*===========================================================================*/
PRIVATE void select_wakeup(struct selectentry *e, int r)
{
- revive(e->req_procnr, r);
+ revive(e->req_endpt, r);
}
/*===========================================================================*
/*===========================================================================*
* select_forget *
*===========================================================================*/
-PUBLIC void select_forget(int proc)
+PUBLIC void select_forget(int proc_e)
{
/* something has happened (e.g. signal delivered that interrupts
* select()). totally forget about the select().
for(s = 0; s < MAXSELECTS; s++) {
if (selecttab[s].requestor &&
- selecttab[s].req_procnr == proc) {
+ selecttab[s].req_endpt == proc_e) {
break;
}
}
/*===========================================================================*
- * select_unsuspend_by_proc *
+ * select_unsuspend_by_endpt *
*===========================================================================*/
-PUBLIC void select_unsuspend_by_proc(int proc)
+PUBLIC void select_unsuspend_by_endpt(int proc_e)
{
int fd, s;
if (!selecttab[s].filps[fd] || !selecttab[s].filps[fd]->filp_ino)
continue;
maj = (selecttab[s].filps[fd]->filp_ino->i_zone[0] >> MAJOR)&BYTE;
- if(dmap_driver_match(proc, maj)) {
+ if(dmap_driver_match(proc_e, maj)) {
select_return(&selecttab[s], EAGAIN);
}
}
int r;
register struct fproc *rfp;
- if (who == PM_PROC_NR) {
- rfp = &fproc[m_in.slot1];
+ if (who_e == PM_PROC_NR) {
+ int slot;
+ if(isokendpt(m_in.endpt1, &slot) != OK)
+ return EINVAL;
+ rfp = &fproc[slot];
put_inode(fp->fp_rootdir);
dup_inode(fp->fp_rootdir = rfp->fp_rootdir);
put_inode(fp->fp_workdir);
/* Copy the struct to user space. */
r = sys_datacopy(FS_PROC_NR, (vir_bytes) &statbuf,
- who, (vir_bytes) user_addr, (phys_bytes) sizeof(statbuf));
+ who_e, (vir_bytes) user_addr, (phys_bytes) sizeof(statbuf));
return(r);
}
st.f_bsize = rfilp->filp_ino->i_sp->s_block_size;
r = sys_datacopy(FS_PROC_NR, (vir_bytes) &st,
- who, (vir_bytes) m_in.buffer, (phys_bytes) sizeof(st));
+ who_e, (vir_bytes) m_in.buffer, (phys_bytes) sizeof(st));
return(r);
}
else {
bp = get_block(rip->i_dev, b, NORMAL);
r = sys_vircopy(SELF, D, (vir_bytes) bp->b_data,
- who, D, (vir_bytes) m_in.name2, (vir_bytes) rip->i_size);
+ who_e, D, (vir_bytes) m_in.name2, (vir_bytes) rip->i_size);
if (r == OK) r = rip->i_size;
put_block(bp, DIRECTORY_BLOCK);
#include "fs.h"
#include <minix/com.h>
+#include <minix/endpoint.h>
#include <unistd.h>
#include "buf.h"
#include "file.h"
r = OK;
} else {
/* String is not contained in the message. Get it from user space. */
- r = sys_datacopy(who, (vir_bytes) path,
+ r = sys_datacopy(who_e, (vir_bytes) path,
FS_PROC_NR, (vir_bytes) user_path, (phys_bytes) len);
}
return(r);
return(l);
}
+/*===========================================================================*
+ * isokendpt_f *
+ *===========================================================================*/
+PUBLIC int isokendpt_f(char *file, int line, int endpoint, int *proc, int fatal)
+{
+ int failed = 0;
+ *proc = _ENDPOINT_P(endpoint);
+ if(*proc < 0 || *proc >= NR_PROCS) {
+ printf("FS:%s:%d: proc (%d) from endpoint (%d) out of range\n",
+ file, line, *proc, endpoint);
+ failed = 1;
+ } else if(fproc[*proc].fp_endpoint != endpoint) {
+ printf("FS:%s:%d: proc (%d) from endpoint (%d) doesn't match "
+ "known endpoint (%d)\n",
+ file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
+ failed = 1;
+ }
+
+ if(failed && fatal)
+ panic(__FILE__, "isokendpt_f failed", NO_NUM);
+
+ return failed ? EDEADSRCDST : OK;
+}
+
inet: $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) version.c $(LIBS)
-install: /usr/sbin/inet
-
-/usr/sbin/inet: inet
- install -c $? $@
+install: inet
+ install -c $? /usr/sbin/inet
clean:
rm -f $(OBJ) inet *.bak
#define NDEV_COUNT COUNT
#define NDEV_IOCTL REQUEST
#define NDEV_MINOR DEVICE
-#define NDEV_PROC PROC_NR
+#define NDEV_PROC IO_ENDPT
#endif
THIS_FILE
m->mq_mess.NDEV_REF,
m->mq_mess.NDEV_OPERATION);
#else /* Minix 3 */
- result= sr_repl_queue(m->mq_mess.PROC_NR, 0, 0);
+ result= sr_repl_queue(m->mq_mess.IO_ENDPT, 0, 0);
#endif
if (result)
{
sr_fd->srf_select_proc= m->m_source;
- m_ops= m->PROC_NR;
+ m_ops= m->IO_ENDPT;
i_ops= 0;
if (m_ops & SEL_RD) i_ops |= SR_SELECT_READ;
if (m_ops & SEL_WR) i_ops |= SR_SELECT_WRITE;
mp= &reply;
mp->m_type= DEVICE_REPLY;
- mp->REP_PROC_NR= proc;
+ mp->REP_ENDPT= proc;
mp->REP_STATUS= status;
#ifdef __minix_vmd
mp->REP_REF= ref;
cpvec[i].cpv_size= size;
#else /* Minix 3 */
vir_cp_req[i].count= size;
- vir_cp_req[i].src.proc_nr = proc;
+ vir_cp_req[i].src.proc_nr_e = proc;
vir_cp_req[i].src.segment = D;
vir_cp_req[i].src.offset = (vir_bytes) src;
- vir_cp_req[i].dst.proc_nr = this_proc;
+ vir_cp_req[i].dst.proc_nr_e = this_proc;
vir_cp_req[i].dst.segment = D;
vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc);
#endif
cpvec[i].cpv_dst= (vir_bytes)dest;
cpvec[i].cpv_size= size;
#else /* Minix 3 */
- vir_cp_req[i].src.proc_nr = this_proc;
+ vir_cp_req[i].src.proc_nr_e = this_proc;
vir_cp_req[i].src.segment = D;
vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc);
- vir_cp_req[i].dst.proc_nr = proc;
+ vir_cp_req[i].dst.proc_nr_e = proc;
vir_cp_req[i].dst.segment = D;
vir_cp_req[i].dst.offset= (vir_bytes)dest;
vir_cp_req[i].count= size;
for (m= repl_queue; m;)
{
#ifdef __minix_vmd
- if (m->mq_mess.REP_PROC_NR == proc &&
+ if (m->mq_mess.REP_ENDPT == proc &&
m->mq_mess.REP_REF ==ref &&
(m->mq_mess.REP_OPERATION == operation ||
operation == CANCEL_ANY))
#else /* Minix 3 */
- if (m->mq_mess.REP_PROC_NR == proc)
+ if (m->mq_mess.REP_ENDPT == proc)
#endif
{
assert(!m_cancel);
# install -S 256w $@
# install with other servers
-install: /sbin/$(SERVER)
-/sbin/$(SERVER): $(SERVER)
- install -o root -c $? $@
-# install -o root -cs $? $@
+install: $(SERVER)
+ install -o root -c $? /sbin/$(SERVER)
# clean up local files
clean:
getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap);
printf("File System (FS) device <-> driver mappings\n");
- printf("Major Proc Flags\n");
- printf("----- ---- -----\n");
+ printf("Major Driver ept Flags\n");
+ printf("----- ---------- -----\n");
for (i=0; i<NR_DEVICES; i++) {
if (dmap[i].dmap_driver == NONE) continue;
- printf("%5d %4d %s\n",
+ printf("%5d %10d %s\n",
i, dmap[i].dmap_driver, dmap_flags(dmap[i].dmap_flags));
}
}
#include "inc.h"
#include <timers.h>
#include <ibm/interrupt.h>
+#include <minix/endpoint.h>
#include "../../kernel/const.h"
#include "../../kernel/config.h"
#include "../../kernel/debug.h"
for (i=0; i<NR_IRQ_HOOKS; i++) {
e = &irq_hooks[i];
printf("%3d", i);
- if (e->proc_nr==NONE) {
+ if (e->proc_nr_e==NONE) {
printf(" <unused>\n");
continue;
}
- printf("%10d ", e->proc_nr);
+ printf("%10d ", e->proc_nr_e);
printf(" %9.9s (%02d) ", irq[e->irq], e->irq);
printf(" %s", (e->policy & IRQ_REENABLE) ? "reenable" : " - ");
printf(" %d", e->notify_id);
return;
}
- printf("\n--nr-name---- -prior-quant- -user---sys- -text---data---size- -rts flags-\n");
+ printf("\n-nr-----endpoint--name--- -prior-quant- -user---sys----size-rts flags-\n");
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
if (isemptyp(rp)) continue;
if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
else printf(" %2d ", proc_nr(rp));
- printf(" %-8.8s %02u/%02u %02d/%02u %6lu%6lu %6uK%6uK%6uK %s",
+ printf(" %10d ", rp->p_endpoint);
+ printf(" %-8.8s %02u/%02u %02d/%02u %6lu%6lu %6uK %s",
rp->p_name,
rp->p_priority, rp->p_max_priority,
rp->p_ticks_left, rp->p_quantum_size,
rp->p_user_time, rp->p_sys_time,
- click_to_round_k(text), click_to_round_k(data),
click_to_round_k(size),
p_rts_flags_str(rp->p_rts_flags));
if (rp->p_rts_flags & (SENDING|RECEIVING)) {
- printf(" %-7.7s", proc_name(rp->p_getfrom));
+ printf(" %-7.7s", proc_name(_ENDPOINT_P(rp->p_getfrom_e)));
}
printf("\n");
}
rp = &rproc[i];
if (! rp->r_flags & RS_IN_USE) continue;
if (++n > 22) break;
- printf("%3d %5d %s %3d/%2d %3u %8u %8u %3dx %3d %s (%d)",
- rp->r_proc_nr, rp->r_pid,
+ printf("%9d %5d %s %3d/%2d %3u %8u %8u %3dx %3d %s (%d)",
+ rp->r_proc_nr_e, rp->r_pid,
s_flags_str(rp->r_flags),
rp->r_dev_nr, rp->r_dev_style,
rp->r_period,
/* The parameters of the call are kept here. */
extern message m_in; /* the input message itself */
extern message m_out; /* the output message used for reply */
-extern int who; /* caller's proc number */
+extern int who_e; /* caller's proc number */
extern int callnr; /* system call number */
extern int dont_reply; /* normally 0; set to 1 to inhibit reply */
/* Allocate space for the global variables. */
message m_in; /* the input message itself */
message m_out; /* the output message used for reply */
-int who; /* caller's proc number */
+int who_e; /* caller's proc number */
int callnr; /* system call number */
int sys_panic; /* flag to indicate system-wide panic */
}
continue;
case PANIC_DUMPS:
- printf("Oops ... panic in %d. ", who);
+ printf("Oops ... panic in %d. ", who_e);
printf("Hit F-keys for debug dumps or F12 to shut down.\n");
sys_panic = TRUE; /* set flag to allow exit */
continue;
/* Finally send reply message, unless disabled. */
if (result != EDONTREPLY) {
- reply(who, result);
+ reply(who_e, result);
}
}
return(OK); /* shouldn't come here */
status = receive(ANY, &m_in); /* this blocks until message arrives */
if (OK != status)
panic("IS","failed to receive message!", status);
- who = m_in.m_source; /* message arrived! set sender */
+ who_e = m_in.m_source; /* message arrived! set sender */
callnr = m_in.m_type; /* set function call number */
}
if (swap_fd != -1) return(EBUSY); /* already have swap? */
- tell_fs(CHDIR, who, FALSE, 0); /* be like the caller for open() */
+ 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;
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(proc_nr, rmp->mp_seg);
+ 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, proc_nr, D, (phys_bytes)size << CLICK_SHIFT);
+ 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;
off = swap_offset + ((off_t) (new_base - swap_base) << CLICK_SHIFT);
lseek(swap_fd, off, SEEK_SET);
- rw_seg(1, swap_fd, proc_nr, D, (phys_bytes)size << CLICK_SHIFT);
+ 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(proc_nr, rmp->mp_seg);
+ sys_newmap(rmp->mp_endpoint, rmp->mp_seg);
free_mem(old_base, size);
rmp->mp_flags |= ONSWAP;
return(ENOMEM);
}
new_clicks -= rmp->mp_seg[D].mem_vir;
- if ((r=get_stack_ptr(who, &new_sp)) != OK) /* ask kernel for sp value */
+ 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);
rmp->mp_seg[S].mem_vir) ? ENOMEM : OK;
#endif
if (r == OK) {
- if (changed) sys_newmap((int)(rmp - mproc), rmp->mp_seg);
+ 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);
}
#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>
*/
register struct mproc *rmp;
struct mproc *sh_mp;
- int m, r, fd, ft, sn;
+ 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;
/* 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, (vir_bytes) src,
+ 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, (vir_bytes) src,
+ 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);
name = name_buf; /* name of file to exec. */
do {
s_p = &s_buf[r];
- tell_fs(CHDIR, who, FALSE, 0); /* switch to the user's FS environ */
+ 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 */
patch_ptr(mbuf, vsp);
src = (vir_bytes) mbuf;
r = sys_datacopy(PM_PROC_NR, (vir_bytes) src,
- who, (vir_bytes) vsp, (phys_bytes)stk_bytes);
- if (r != OK) panic(__FILE__,"do_exec stack copy err on", who);
+ 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, T, text_bytes);
+ rw_seg(0, fd, who_e, T, text_bytes);
}
- rw_seg(0, fd, who, D, data_bytes);
+ rw_seg(0, fd, who_e, D, data_bytes);
close(fd); /* don't need exec file any more */
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, (int)rmp->mp_realuid, (int)rmp->mp_effuid);
+ 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, (int)rmp->mp_realgid, (int)rmp->mp_effgid);
+ tell_fs(SETGID,who_e, (int)rmp->mp_realgid, (int)rmp->mp_effgid);
}
}
rmp->mp_flags |= ft; /* turn it on for separate I & D files */
new_sp = (char *) vsp;
- tell_fs(EXEC, who, 0, 0); /* allow FS to handle FD_CLOEXEC files */
+ 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';
- sys_exec(who, new_sp, basename, pc);
+ 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);
vir_clicks text_clicks, data_clicks, gap_clicks, stack_clicks, tot_clicks;
phys_clicks new_base;
phys_bytes bytes, base, bss_offset;
- int s;
+ int s, r2;
/* No need to allocate text if it can be shared. */
if (sh_mp != NULL) text_bytes = 0;
+ rmp->mp_seg[D].mem_len + gap_clicks;
#endif
- sys_newmap(who, rmp->mp_seg); /* report new map to the kernel */
+ 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);
/*===========================================================================*
* rw_seg *
*===========================================================================*/
-PUBLIC void rw_seg(rw, fd, proc, seg, seg_bytes0)
+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; /* process number */
+int proc_e; /* process number (endpoint) */
int seg; /* T, D, or S */
phys_bytes seg_bytes0; /* how much is to be transferred? */
{
* partially initialized.
*/
- int new_fd, bytes, r;
+ int bytes, r, proc_n;
char *ubuf_ptr;
- struct mem_map *sp = &mproc[proc].mp_seg[seg];
+ struct mem_map *sp;
phys_bytes seg_bytes = seg_bytes0;
- new_fd = (proc << 7) | (seg << 5) | fd;
+ 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 == 0) {
- r = read(new_fd, ubuf_ptr, bytes);
+ if(!rw) {
+ r = _read_pm(fd, ubuf_ptr, bytes, seg, proc_e);
} else {
- r = write(new_fd, ubuf_ptr, bytes);
+ r = _write_pm(fd, ubuf_ptr, bytes, seg, proc_e);
}
if (r != bytes) break;
ubuf_ptr += bytes;
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.
if (s < 0) panic(__FILE__,"do_fork can't copy", s);
/* Find a slot in 'mproc' for the child process. A slot must exist. */
- for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++)
- if ( (rmc->mp_flags & IN_USE) == 0) break;
-
+ 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; /* record child's parent */
+ 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_pid = new_pid; /* assign pid to child */
/* Tell kernel and file system about the (now successful) FORK. */
- sys_fork(who, child_nr);
- tell_fs(FORK, who, child_nr, rmc->mp_pid);
+ 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. */
- sys_newmap(child_nr, rmc->mp_seg);
+ 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.procnr = child_nr; /* child's process number */
+ rmp->mp_reply.endpt = rmc->mp_endpoint; /* child's process number */
+
return(new_pid); /* child's pid */
}
* parent is waiting, release the rest, else keep the process slot and
* become a zombie.
*/
- register int proc_nr;
- int parent_waiting, right_child;
+ 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, (unsigned) 0);
+ if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr_e, (unsigned) 0);
/* Do accounting: fetch usage times and accumulate at parent. */
- sys_times(proc_nr, t);
+ 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 and FS that the process is no longer runnable. */
- tell_fs(EXIT, proc_nr, 0, 0); /* file system can free the proc slot */
- sys_exit(proc_nr);
+ tell_fs(EXIT, proc_nr_e, 0, 0); /* file system can free the proc slot */
+ if((r=sys_exit(proc_nr_e)) != OK)
+ panic(__FILE__,"pm_exit: sys_exit failed", r);
/* Pending reply messages for the dead process cannot be delivered. */
rmp->mp_flags &= ~REPLY;
*/
children = 0;
for (rp = &mproc[0]; rp < &mproc[NR_PROCS]; rp++) {
- if ( (rp->mp_flags & IN_USE) && rp->mp_parent == who) {
+ 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;
#include "pm.h"
#include <minix/callnr.h>
+#include <minix/endpoint.h>
#include <signal.h>
#include "mproc.h"
#include "param.h"
*/
register struct mproc *rmp = mp;
- register int r;
+ int r, proc;
switch(call_nr) {
case GETUID:
break;
case GETPID:
- r = mproc[who].mp_pid;
+ r = mproc[who_p].mp_pid;
rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid;
- if (m_in.procnr >= 0 && m_in.procnr < NR_PROCS)
- rmp->mp_reply.reply_res3 = mproc[m_in.procnr].mp_pid;
+ if(pm_isokendpt(m_in.endpt, &proc) == OK && proc >= 0)
+ rmp->mp_reply.reply_res3 = mproc[proc].mp_pid;
break;
case SETEUID:
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, rmp->mp_realuid, rmp->mp_effuid);
+ tell_fs(SETUID, who_e, rmp->mp_realuid, rmp->mp_effuid);
r = OK;
break;
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, rmp->mp_realgid, rmp->mp_effgid);
+ 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, 0, 0);
+ tell_fs(SETSID, who_e, 0, 0);
/* fall through */
case GETPGRP:
/* The parameters of the call are kept here. */
EXTERN message m_in; /* the incoming message itself is kept here. */
-EXTERN int who; /* caller's proc number */
+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 */
#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>
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();
+ 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 {
+#if 0
+ printf("[pm: %s %d %d %d ",
+ who_p >= 0 ? mproc[who_p].mp_name : "?", who_e, who_p, call_nr);
+#endif
result = (*call_vec[call_nr])();
+#if 0
+ printf(" %d] ", result);
+#endif
}
/* Send the results back to the user to indicate completion. */
- if (result != SUSPEND) setreply(who, result);
+ if (result != SUSPEND) setreply(who_p, result);
swap_in(); /* maybe a process can be swapped in? */
*/
if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) ==
(REPLY | IN_USE)) {
- if ((s=send(proc_nr, &rmp->mp_reply)) != OK) {
- panic(__FILE__,"PM can't reply to", proc_nr);
+ if ((s=send(rmp->mp_endpoint, &rmp->mp_reply)) != OK) {
+ panic(__FILE__,"PM can't reply to",
+ rmp->mp_endpoint);
}
rmp->mp_flags &= ~REPLY;
}
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 = m_in.m_source; /* who sent the message */
+ 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 < 0 ? PM_PROC_NR : who];
+ 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);
+ }
}
/*===========================================================================*
*/
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 */
#endif
}
+ /* 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);
patch_mem_chunks(mem_chunks, rmp->mp_seg);
/* Tell FS about this system process. */
- mess.PR_PROC_NR = ip->proc_nr;
+ 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 */
sigfillset(&mproc[TTY_PROC_NR].mp_sig2mess); /* forward signals */
/* Tell FS that no more system processes follow and synchronize. */
- mess.PR_PROC_NR = NONE;
+ 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);
#include <minix/config.h>
#include <minix/type.h>
#include <string.h>
+#include <lib.h>
#include "mproc.h"
#include "param.h"
}
dst_addr = (vir_bytes) m_in.info_where;
- if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
+ if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len)))
return(s);
return(OK);
}
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.procnr = (int) (rmp - mproc);
+ 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, (vir_bytes) m_in.addr,
+ 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.procnr = (int) (rmp - mproc);
+ mp->mp_reply.endpt = rmp->mp_endpoint;
return(OK);
}
}
return(ESRCH);
- } else { /* return own/parent process number */
- mp->mp_reply.procnr = who;
- mp->mp_reply.pprocnr = mp->mp_parent;
+ } else { /* return own/parent process number */
+ mp->mp_reply.endpt = who_e;
+ mp->mp_reply.pendpt = mproc[mp->mp_parent].mp_endpoint;
}
+
return(OK);
}
case RBT_MONITOR:
code_len = m_in.reboot_strlen + 1;
if (code_len > sizeof(monitor_code)) return(EINVAL);
- if (sys_datacopy(who, (vir_bytes) m_in.reboot_code,
+ if (sys_datacopy(who_e, (vir_bytes) m_in.reboot_code,
PM_PROC_NR, (vir_bytes) monitor_code,
(phys_bytes) (code_len)) != OK) return(EFAULT);
if (monitor_code[code_len-1] != 0) return(EINVAL);
return(EINVAL);
if (arg_who == 0)
- rmp_nr = who;
+ rmp_nr = who_p;
else
if ((rmp_nr = proc_from_pid(arg_who)) < 0)
return(ESRCH);
size_t copy_len;
/* Copy sysgetenv structure to PM. */
- if (sys_datacopy(who, ptr, SELF, (vir_bytes) &sysgetenv,
+ if (sys_datacopy(who_e, ptr, SELF, (vir_bytes) &sysgetenv,
sizeof(sysgetenv)) != OK) return(EFAULT);
/* Set a param override? */
sizeof(local_param_overrides[local_params].value))
return EINVAL;
- if ((s = sys_datacopy(who, (vir_bytes) sysgetenv.key,
+ 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, (vir_bytes) sysgetenv.val,
+ if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.val,
SELF, (vir_bytes) local_param_overrides[local_params].value,
sysgetenv.keylen)) != OK)
return s;
int p;
/* Try to get a copy of the requested key. */
if (sysgetenv.keylen > sizeof(search_key)) return(EINVAL);
- if ((s = sys_datacopy(who, (vir_bytes) sysgetenv.key,
+ if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.key,
SELF, (vir_bytes) search_key, sysgetenv.keylen)) != OK)
return(s);
/* 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, (vir_bytes) sysgetenv.val, copy_len)) != OK)
+ who_e, (vir_bytes) sysgetenv.val, copy_len)) != OK)
return(s);
return OK;
if (mp->mp_effuid != SUPER_USER) return(EPERM);
- if (sys_datacopy(who, (phys_bytes) ptr,
+ if (sys_datacopy(who_e, (phys_bytes) ptr,
PM_PROC_NR, (phys_bytes) &swapon,
(phys_bytes) sizeof(swapon)) != OK) return(EFAULT);
}
}
+/*===========================================================================*
+ * _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));
+}
+
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 */
#define grp_id m1_i1
#define namelen m1_i2
#define pid m1_i1
-#define procnr m1_i1
-#define pprocnr m1_i2
+#define endpt m1_i1
+#define pendpt m1_i2
#define seconds m1_i1
#define sig m6_i1
#define stack_bytes m1_i2
_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) );
_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));
#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>
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, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec));
+ who_e, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec));
if (r != OK) return(r);
}
return(OK);
/* Read in the sigaction structure. */
- r = sys_datacopy(who, (vir_bytes) m_in.sig_nsa,
+ 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);
mp->mp_sigmask = (sigset_t) m_in.sig_set;
sigdelset(&mp->mp_sigmask, SIGKILL);
- r = sys_sigreturn(who, (struct sigmsg *) m_in.sig_context);
+ r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context);
check_pending(mp);
return(r);
}
* signals until all signals are handled. If there are no more signals,
* NONE is returned in the process number field.
*/
- int proc_nr;
+ int proc_nr_e;
sigset_t sig_map;
while (TRUE) {
- sys_getksig(&proc_nr, &sig_map); /* get an arbitrary pending signal */
- if (NONE == proc_nr) { /* stop if no more pending signals */
+ 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 {
- handle_sig(proc_nr, sig_map); /* handle the received signal */
- sys_endksig(proc_nr); /* tell kernel it's done */
+ int proc_nr_p;
+ if(pm_isokendpt(proc_nr_e, &proc_nr_p) != OK)
+ panic(__FILE__,"sys_getksig strange process", proc_nr_e);
+ handle_sig(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_sig *
*===========================================================================*/
-PRIVATE void handle_sig(proc_nr, sig_map)
-int proc_nr;
+PRIVATE void handle_sig(proc_nr_e, sig_map)
+int proc_nr_e;
sigset_t sig_map;
{
register struct mproc *rmp;
- int i;
+ 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;
+ 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 */
PUBLIC int do_alarm()
{
/* Perform the alarm(seconds) system call. */
- return(set_alarm(who, m_in.seconds));
+ return(set_alarm(who_e, m_in.seconds));
}
/*===========================================================================*
* set_alarm *
*===========================================================================*/
-PUBLIC int set_alarm(proc_nr, sec)
-int proc_nr; /* process that wants the 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
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].mp_flags & ALARM_ON) {
+ 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].mp_timer);
+ exptime = *tmr_exp_time(&mproc[proc_nr_n].mp_timer);
remaining = (int) ((exptime - uptime + (HZ-1))/HZ);
if (remaining < 0) remaining = 0;
} else {
ticks = LONG_MAX; /* eternity (really TMR_NEVER) */
if (ticks != 0) {
- pm_set_timer(&mproc[proc_nr].mp_timer, ticks, cause_sigalrm, proc_nr);
- mproc[proc_nr].mp_flags |= ALARM_ON;
- } else if (mproc[proc_nr].mp_flags & ALARM_ON) {
- pm_cancel_timer(&mproc[proc_nr].mp_timer);
- mproc[proc_nr].mp_flags &= ~ALARM_ON;
+ 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);
}
PRIVATE void cause_sigalrm(tp)
struct timer *tp;
{
- int proc_nr;
+ int proc_nr_e, proc_nr_n;
register struct mproc *rmp;
- proc_nr = tmr_arg(tp)->ta_int; /* get process from timer */
- rmp = &mproc[proc_nr];
+ /* get process from timer */
+ if(pm_isokendpt(tmr_arg(tp)->ta_int, &proc_nr_n) != OK) {
+ printf("PM: ignoring timer for invalid enpoint %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;
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(slot, &new_sp)) != OK)
- panic(__FILE__,"couldn't get new stack pointer",s);
+ 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. */
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
}
- if (OK == (s=sys_sigsend(slot, &sm))) {
+ if (OK == (s=sys_sigsend(rmp->mp_endpoint, &sm))) {
sigdelset(&rmp->mp_sigpending, signo);
/* If process is hanging on PAUSE, WAIT, SIGSUSPEND, tty,
unpause(slot);
return;
}
- panic(__FILE__, "warning, sys_sigsend failed", s);
+ panic(__FILE__, "sys_sigsend failed", s);
}
else if (sigismember(&rmp->mp_sig2mess, signo)) {
- if (OK != (s=sys_kill(slot,signo)))
+ if (OK != (s=sys_kill(rmp->mp_endpoint,signo)))
panic(__FILE__, "warning, sys_kill failed", s);
return;
}
}
#endif
/* Switch to the user's FS environment and dump core. */
- tell_fs(CHDIR, slot, FALSE, 0);
+ tell_fs(CHDIR, rmp->mp_endpoint, FALSE, 0);
dump_core(rmp);
}
pm_exit(rmp, 0); /* terminate process */
}
/* Process is not hanging on an PM call. Ask FS to take a look. */
- tell_fs(UNPAUSE, pro, 0, 0);
+ tell_fs(UNPAUSE, rmp->mp_endpoint, 0, 0);
}
/*===========================================================================*
* the adjust() for sending a signal to fail due to safety checking.
* Maybe make SAFETY_BYTES a parameter.
*/
- if ((s=get_stack_ptr(slot, ¤t_sp)) != OK)
- panic(__FILE__,"couldn't get new stack pointer",s);
+ if ((s=get_stack_ptr(rmp->mp_endpoint, ¤t_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. */
/* Write out the whole kernel process table entry to get the regs. */
trace_off = 0;
- while (sys_trace(T_GETUSER, slot, trace_off, &trace_data) == OK) {
+ 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);
/* Loop through segments and write the segments themselves out. */
for (seg = 0; seg < NR_LOCAL_SEGS; seg++) {
- rw_seg(1, fd, slot, seg,
+ rw_seg(1, fd, rmp->mp_endpoint, seg,
(phys_bytes) rmp->mp_seg[seg].mem_len << CLICK_SHIFT);
}
close(fd);
clock_t t[5];
int s;
- if (OK != (s=sys_times(who, t)))
+ 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 */
#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"
if (num != NO_NUM) printf(": %d",num);
printf("\n");
+#if 0
/* Allow for debug dumps if the IS server is available. */
m.m_type = PANIC_DUMPS;
if (OK == (s= nb_send(11, &m))) {
}
printf("Shutting down: IS is not answering: %d\n", s);
sys_abort(RBT_PANIC);
+#endif
+ sys_exit(SELF);
}
/*===========================================================================*
/*===========================================================================*
* get_stack_ptr *
*===========================================================================*/
-PUBLIC int get_stack_ptr(proc_nr, sp)
-int proc_nr; /* process to get sp of */
+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)) != OK)
+ if ((s=sys_getproc(&p, proc_nr_e)) != OK)
return(s);
*sp = p.p_reg.sp;
return(OK);
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;
+}
+
*/
#include "inc.h"
#include <minix/dmap.h>
+#include <minix/endpoint.h>
#include "../../kernel/const.h"
#include "../../kernel/type.h"
* sending the reply. The loop never terminates, unless a panic occurs.
*/
message m; /* request message */
- int call_nr, who; /* call number and caller */
+ int call_nr, who_e,who_p; /* call number and caller */
int result; /* result to return */
sigset_t sigset; /* system signal set */
int s;
/* Wait for request message. */
get_work(&m);
- who = m.m_source;
+ who_e = m.m_source;
+ who_p = _ENDPOINT_P(who_e);
+ if(who_p < -NR_TASKS || who_p >= NR_PROCS)
+ panic("RS","message from bogus source", who_e);
+
call_nr = m.m_type;
/* Now determine what to do. Three types of requests are expected:
if (sigismember(&sigset, SIGKSTOP)) do_shutdown(NULL);
continue;
default: /* heartbeat notification */
- if (rproc_ptr[who] != NULL) /* mark heartbeat time */
- rproc_ptr[who]->r_alive_tm = m.NOTIFY_TIMESTAMP;
+ if (rproc_ptr[who_p] != NULL) /* mark heartbeat time */
+ rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP;
}
}
/* Finally send reply message, unless disabled. */
if (result != EDONTREPLY) {
- reply(who, result);
+ reply(who_e, result);
}
}
}
if (ip->proc_nr >= 0) {
nr_in_use ++;
rproc[s].r_flags = RS_IN_USE;
- rproc[s].r_proc_nr = ip->proc_nr;
+ rproc[s].r_proc_nr_e = ip->endpoint;
rproc[s].r_pid = getnpid(ip->proc_nr);
for(t=0; t< NR_DEVICES; t++)
if (dmap[t].dmap_driver == ip->proc_nr)
#include <sys/types.h>
#include <sys/wait.h>
#include <minix/dmap.h>
+#include <minix/endpoint.h>
/* Allocate variables. */
struct rproc rproc[NR_SYS_PROCS]; /* system process table */
while ( (exit_pid = waitpid(-1, &exit_status, WNOHANG)) != 0 ) {
#if VERBOSE
- printf("RS: proc %d, pid %d, ", rp->r_proc_nr, exit_pid);
+ printf("RS: proc %d, pid %d, ", rp->r_proc_nr_e, exit_pid);
if (WIFSIGNALED(exit_status)) {
printf("killed, signal number %d\n", WTERMSIG(exit_status));
}
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
if ((rp->r_flags & RS_IN_USE) && rp->r_pid == exit_pid) {
- rproc_ptr[rp->r_proc_nr] = NULL; /* invalidate */
+ rproc_ptr[rp->r_proc_nr_e] = NULL; /* invalidate */
if ((rp->r_flags & RS_EXITING) || shutting_down) {
rp->r_flags = 0; /* release slot */
- rproc_ptr[rp->r_proc_nr] = NULL;
+ rproc_ptr[rp->r_proc_nr_e] = NULL;
}
else if(rp->r_flags & RS_REFRESHING) {
rp->r_restarts = -1; /* reset counter */
if (now - rp->r_alive_tm > 2*rp->r_period &&
rp->r_pid > 0) {
#if VERBOSE
- printf("RS: service %d reported late\n", rp->r_proc_nr);
+ printf("RS: service %d reported late\n", rp->r_proc_nr_e);
#endif
kill(rp->r_pid, SIGKILL); /* simulate crash */
}
*/
else if (now - rp->r_check_tm > rp->r_period) {
#if VERBOSE
- printf("RS: status request sent to %d\n", rp->r_proc_nr);
+ printf("RS: status request sent to %d\n", rp->r_proc_nr_e);
#endif
- notify(rp->r_proc_nr); /* request status */
+ notify(rp->r_proc_nr_e); /* request status */
rp->r_check_tm = now; /* mark time */
}
}
* process will be inhibited from running by the NO_PRIV flag. Only let the
* child run once its privileges have been set by the parent.
*/
- int child_proc_nr; /* child process slot */
+ int child_proc_nr_e, child_proc_nr_n; /* child process slot */
pid_t child_pid; /* child's process id */
char *file_only;
int s;
exit(EXEC_FAILED); /* terminate child */
default: /* parent process */
- child_proc_nr = getnprocnr(child_pid); /* get child slot */
+ child_proc_nr_e = getnprocnr(child_pid); /* get child slot */
break; /* continue below */
}
* not yet set. First try to set the device driver mapping at the FS.
*/
if (rp->r_dev_nr > 0) { /* set driver map */
- if ((s=mapdriver(child_proc_nr, rp->r_dev_nr, rp->r_dev_style)) < 0) {
+ if ((s=mapdriver(child_proc_nr_e, rp->r_dev_nr, rp->r_dev_style)) < 0) {
report("RS", "couldn't map driver", errno);
+ rp->r_flags |= RS_EXITING; /* expect exit */
if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */
else report("RS", "didn't kill pid", child_pid);
- rp->r_flags |= RS_EXITING; /* expect exit */
return(s); /* return error */
}
}
* Now, set the privilege structure for the child process to let is run.
* This should succeed: we tested number in use above.
*/
- if ((s = sys_privctl(child_proc_nr, SYS_PRIV_INIT, 0, NULL)) < 0) {
+ if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_INIT, 0, NULL)) < 0) {
report("RS","call to SYSTEM failed", s); /* to let child run */
+ rp->r_flags |= RS_EXITING; /* expect exit */
if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */
else report("RS", "didn't kill pid", child_pid);
- rp->r_flags |= RS_EXITING; /* expect exit */
return(s); /* return error */
}
#if VERBOSE
- printf("RS: started '%s', major %d, pid %d, proc_nr %d\n",
- rp->r_cmd, rp->r_dev_nr, child_pid, child_proc_nr);
+ printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n",
+ rp->r_cmd, rp->r_dev_nr, child_pid,
+ child_proc_nr_e, child_proc_nr_n);
#endif
/* The system service now has been successfully started. Update the rest
* thing that can go wrong now, is that execution fails at the child. If
* that's the case, the child will exit.
*/
+ child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e);
rp->r_flags = RS_IN_USE; /* mark slot in use */
rp->r_restarts += 1; /* raise nr of restarts */
- rp->r_proc_nr = child_proc_nr; /* set child details */
+ rp->r_proc_nr_e = child_proc_nr_e; /* set child details */
rp->r_pid = child_pid;
rp->r_check_tm = 0; /* not check yet */
getuptime(&rp->r_alive_tm); /* currently alive */
rp->r_stop_tm = 0; /* not exiting yet */
- rproc_ptr[child_proc_nr] = rp; /* mapping for fast access */
+ rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
return(OK);
}
* the servers and drivers, and thus is not directly indexed by slot number.
*/
extern struct rproc {
- int r_proc_nr; /* process slot number */
+ int r_proc_nr_e; /* process endpoint number */
pid_t r_pid; /* process id */
dev_t r_dev_nr; /* major device number */
int r_dev_style; /* device style */