void errmsg(char *s)
{
- static char *prompt = "settime: ";
+ static char *prompt = "readclock: ";
fprintf(stderr, "%s%s\n", prompt, s);
prompt = "";
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioc_memory.h>
+#include "../../kernel/const.h"
#include "../../kernel/type.h"
#if __minix_vmd
#define FUTURE_CODE 0 /* new code to be activated + tested later */
#define TEMP_CODE 1 /* active code to be removed later */
-/* Process name length in the process table, including '\0'. */
+/* Process name length in the PM process table, including '\0'. */
#define PROC_NAME_LEN 16
/* Miscellaneous */
* due to a race, since this will only delay the high-level
* processing by one tick, or call the high level unnecessarily.
* The variables which are changed require more care:
- * rp->user_time, rp->sys_time:
+ * rp->p_user_time, rp->p_sys_time:
* These are protected by explicit locks in system.c. They are
* not properly protected in dmp.c (the increment here is not
* atomic) but that hardly matters.
now = realtime + pending_ticks;
/* Update administration. */
- proc_ptr->user_time += ticks;
- if (proc_ptr != bill_ptr) bill_ptr->sys_time += ticks;
+ proc_ptr->p_user_time += ticks;
+ if (proc_ptr != bill_ptr) bill_ptr->p_sys_time += ticks;
/* Check if do_clocktick() must be called. Done for alarms and scheduling.
* If bill_ptr == prev_ptr, there are no ready users so don't need sched().
/* How many bytes for the kernel stack. Space allocated in mpx.s. */
#define K_STACK_BYTES 1024
+/* How long should the process names be in the kernel? */
+#define P_NAME_LEN 8
+
/* How many bytes for (port,value)-pairs vector to copy in. */
#define VDEVIO_BUF_SIZE 128
#define FRESH_ANSWER 0x20 /* ignore pending notifications as answer */
/* (default behaviour for SENDREC calls) */
-/* System calls (numbers passed when trapping to the kernel) */
+/* System calls (numbers passed when trapping to the kernel). */
#define ECHO 0 /* function code for echoing messages */
#define SEND 1 /* function code for sending messages */
#define RECEIVE 2 /* function code for receiving messages */
#define SENDREC 3 /* function code for SEND + RECEIVE */
#define NOTIFY 4 /* function code for notifications */
+#if 0
+/* Bit map operations used to bits of simple bit mask. */
+#define set_bit(mask, n) ((mask) |= (1 << (n)))
+#define clear_bit(mask, n) ((mask) &= ~(1 << (n)))
+#define isset_bit(mask, n) ((mask) & (1 << (n)))
+#define empty_mask (0)
+#define filled_mask (~0)
+#endif
+
+/* Call masks indicating which system calls a process can make. */
+#define EMPTY_CALL_MASK (0)
+#define USER_CALL_MASK (1 << SENDREC)
+#define SYSTEM_CALL_MASK (~0)
+
+
for (i=0; i < IMAGE_SIZE; ++i) {
ttp = &image[i]; /* t's task attributes */
rp = proc_addr(ttp->proc_nr); /* t's process slot */
- kstrncpy(rp->p_name, ttp->proc_name, PROC_NAME_LEN); /* set name */
+ kstrncpy(rp->p_name, ttp->proc_name, P_NAME_LEN); /* set name */
+ rp->p_name[P_NAME_LEN-1] = '\0'; /* just for safety */
rp->p_type = ttp->type; /* type of process */
rp->p_priority = ttp->priority; /* scheduling priority */
+ rp->p_call_mask = ttp->call_mask; /* allowed system calls */
rp->p_sendmask = ttp->sendmask; /* sendmask protection */
if (i-NR_TASKS < 0) { /* part of the kernel? */
if (ttp->stksize > 0) { /* HARDWARE stack size is 0 */
vir_bytes vb; /* message buffer pointer as vir_bytes */
vir_clicks vlo, vhi; /* virtual clicks containing message to send */
- /* Calls directed to the kernel may only be sendrec(), because tasks always
- * reply and may not block if the caller doesn't do receive().
+ /* Check if the process has privileges for the requested call. Calls to the
+ * kernel may only be SENDREC, because tasks always reply and may not block
+ * if the caller doesn't do receive().
*/
- if (iskernel(src_dst) && function != SENDREC) return(ECALLDENIED);
+ if (! (caller_ptr->p_call_mask & (1 << function)) ||
+ iskernel(src_dst) && function != SENDREC) return(ECALLDENIED);
/* Verify that requested source and/ or destination is a valid process. */
if (! isoksrc_dst(src_dst) && function != ECHO) return(EBADSRCDST);
char p_flags; /* SENDING, RECEIVING, etc. */
char p_type; /* task, system, driver, server, user, idle */
char p_priority; /* scheduling priority */
+ char p_call_mask; /* bit map with allowed system call traps */
- clock_t user_time; /* user time in ticks */
- clock_t sys_time; /* sys time in ticks */
- clock_t child_utime; /* cumulative user time of children */
- clock_t child_stime; /* cumulative sys time of children */
+ send_mask_t p_sendmask; /* mask indicating to whom proc may send */
+
+ clock_t p_user_time; /* user time in ticks */
+ clock_t p_sys_time; /* sys time in ticks */
timer_t p_signalrm; /* signal alarm timer */
timer_t p_flagalrm; /* flag alarm timer */
message *p_messbuf; /* pointer to message buffer */
proc_nr_t p_getfrom; /* from whom does process want to receive? */
proc_nr_t p_sendto; /* to whom does process want to send? */
- send_mask_t p_sendmask; /* mask indicating to whom proc may send */
sigset_t p_pending; /* bit map for pending signals */
unsigned p_pendcount; /* count of pending and unfinished signals */
- char p_name[PROC_NAME_LEN]; /* name of the process, including \0 */
+ char p_name[P_NAME_LEN]; /* name of the process, including \0 */
#if ENABLE_K_DEBUGGING
int p_ready, p_found;
}
/* Now clean up the process table entry. Reset to defaults. */
- kstrncpy(rc->p_name, "<noname>", PROC_NAME_LEN); /* unset name */
+ kstrncpy(rc->p_name, "<none>", P_NAME_LEN); /* unset name */
sigemptyset(&rc->p_pending); /* remove pending signals */
rc->p_pendcount = 0; /* all signals are gone */
rc->p_flags = 0; /* remove all flags */
* m4_l1: T_PROC_NR (get info for this process)
* m4_l1: T_USER_TIME (return values ...)
* m4_l2: T_SYSTEM_TIME
- * m4_l3: T_CHILD_UTIME
- * m4_l4: T_CHILD_STIME
* m4_l5: T_BOOT_TICKS
*/
rp = proc_addr(m_ptr->T_PROC_NR);
lock(); /* halt the volatile time counters in rp */
- m_ptr->T_USER_TIME = rp->user_time;
- m_ptr->T_SYSTEM_TIME = rp->sys_time;
+ m_ptr->T_USER_TIME = rp->p_user_time;
+ m_ptr->T_SYSTEM_TIME = rp->p_sys_time;
unlock();
- m_ptr->T_CHILD_UTIME = rp->child_utime;
- m_ptr->T_CHILD_STIME = rp->child_stime;
}
m_ptr->T_BOOT_TICKS = get_uptime();
return(OK);
rpc->p_pendcount = 0;
rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
- rpc->user_time = 0; /* set all the accounting times to 0 */
- rpc->sys_time = 0;
- rpc->child_utime = 0;
- rpc->child_stime = 0;
+ rpc->p_user_time = 0; /* set all the accounting times to 0 */
+ rpc->p_sys_time = 0;
return(OK);
}
reg_t sp; /* new sp */
phys_bytes phys_name;
char *np;
-#define NLEN (sizeof(rp->p_name)-1)
rp = proc_addr(m_ptr->PR_PROC_NR);
assert(isuserp(rp));
/* Save command name for debugging, ps(1) output, etc. */
phys_name = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->PR_NAME_PTR,
- (vir_bytes) NLEN);
+ (vir_bytes) P_NAME_LEN - 1);
if (phys_name != 0) {
- phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) NLEN);
+ phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1);
for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
- *np = 0;
+ *np = 0; /* mark end */
+ } else {
+ kstrncpy(rp->p_name, "<unset>", P_NAME_LEN);
}
return(OK);
}
if (! isokprocn(exit_proc_nr)) return(EINVAL);
rc = proc_addr(exit_proc_nr);
- /* If this is a user process and the PM passed in a valid parent process,
- * accumulate the child times at the parent.
- */
- if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
- rp = proc_addr(m_ptr->PR_PPROC_NR);
- lock();
- rp->child_utime += rc->user_time + rc->child_utime;
- rp->child_stime += rc->sys_time + rc->child_stime;
- unlock();
- }
-
/* Now call the routine to clean up of the process table slot. This cancels
* outstanding timers, possibly removes the process from the message queues,
* and resets important process table fields.
*/
#include "../kernel.h"
+#include "../ipc.h"
#include "../system.h"
#include "../protect.h"
#include <sys/svrctl.h>
/* fall through */
}
case SYSSENDMASK: {
+ rp->p_call_mask = SYSTEM_CALL_MASK;
rp->p_type = P_SERVER;
rp->p_sendmask = ALLOW_ALL_MASK;
send_mask_allow(proc_addr(USR8139)->p_sendmask, proc_nr);
#include "kernel.h"
#include "proc.h"
+#include "ipc.h"
#include "sendmask.h"
#include <minix/com.h>
#include <ibm/int86.h>
* routine and stack size is also provided.
*/
PUBLIC struct system_image image[] = {
- { IDLE, idle_task, P_IDLE, PPRI_IDLE, IDLE_STACK, IDLE_SENDMASK, "IDLE" },
- { CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, CLOCK_SENDMASK, "CLOCK" },
- { SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_SENDMASK, "SYS" },
- { HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" },
- { PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" },
- { FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" },
- { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, IS_SENDMASK, "IS" },
- { TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" },
- { MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, MEM_SENDMASK, "MEMORY" },
+ { IDLE, idle_task, P_IDLE, PPRI_IDLE, IDLE_STACK, EMPTY_CALL_MASK, IDLE_SENDMASK, "IDLE" },
+ { CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, SYSTEM_CALL_MASK, CLOCK_SENDMASK, "CLOCK" },
+ { SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_CALL_MASK, SYSTEM_SENDMASK, "SYS" },
+ { HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK, EMPTY_CALL_MASK, HARDWARE_SENDMASK,"HARDW." },
+ { PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PM_SENDMASK, "PM" },
+ { FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, FS_SENDMASK, "FS" },
+ { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, SYSTEM_CALL_MASK, IS_SENDMASK, "IS" },
+ { TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, SYSTEM_CALL_MASK, TTY_SENDMASK, "TTY" },
+ { MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, MEM_SENDMASK, "MEMORY" },
#if ENABLE_AT_WINI
- { AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, AT_SENDMASK, "AT_WINI" },
+ { AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, AT_SENDMASK, "AT_WINI" },
#endif
#if ENABLE_FLOPPY
- { FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, FLOPPY_SENDMASK, "FLOPPY" },
+ { FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FLOPPY_SENDMASK, "FLOPPY" },
#endif
#if ENABLE_PRINTER
- { PRINTER, 0, P_DRIVER, PPRI_NORMAL, 0, PRN_SENDMASK, "PRINTER" },
+ { PRINTER, 0, P_DRIVER, PPRI_NORMAL, 0, SYSTEM_CALL_MASK, PRN_SENDMASK, "PRINTER" },
#endif
#if ENABLE_RTL8139
- { USR8139, 0, P_DRIVER, PPRI_HIGH, 0, RTL8139_SENDMASK, "RTL8139" },
+ { USR8139, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, RTL8139_SENDMASK, "RTL8139" },
#endif
#if ENABLE_FXP
- { FXP, 0, P_DRIVER, PPRI_HIGH, 0, FXP_SENDMASK, "FXP" },
+ { FXP, 0, P_DRIVER, PPRI_HIGH, 0, SYSTEM_CALL_MASK, FXP_SENDMASK, "FXP" },
#endif
- { INIT_PROC_NR, 0, P_USER, PPRI_USER, 0, INIT_SENDMASK, "INIT" },
+ { INIT_PROC_NR, 0, P_USER, PPRI_USER, 0, USER_CALL_MASK, INIT_SENDMASK, "INIT" },
};
/* Verify the size of the system image table at compile time. If the number
int type; /* type of process */
int priority; /* scheduling priority */
int stksize; /* stack size for tasks */
+ char call_mask; /* allowed system calls */
send_mask_t sendmask; /* send mask protection */
- char proc_name[PROC_NAME_LEN]; /* name in process table */
+ char proc_name[P_NAME_LEN]; /* name in process table */
};
struct memory {
message m;
m.m2_l1 = *top;
- return(_syscall(FS, STIME, &m));
+ return(_syscall(MM, STIME, &m));
}
{
message m;
- if (_syscall(FS, TIME, &m) < 0) return( (time_t) -1);
+ if (_syscall(MM, TIME, &m) < 0) return( (time_t) -1);
if (tp != (time_t *) 0) *tp = m.m2_l1;
return(m.m2_l1);
}
message m;
m.m4_l5 = 0; /* return this if system is pre-1.6 */
- if (_syscall(FS, TIMES, &m) < 0) return( (clock_t) -1);
+ if (_syscall(MM, TIMES, &m) < 0) return( (clock_t) -1);
buf->tms_utime = m.m4_l1;
buf->tms_stime = m.m4_l2;
buf->tms_cutime = m.m4_l3;
* process. Thus NR_PROCS must be the same as in the kernel. It is not
* possible or even necessary to tell when a slot is free here.
*/
-
-
EXTERN struct fproc {
mode_t fp_umask; /* mask set by umask system call */
struct inode *fp_workdir; /* pointer to working directory's inode */
}
/* Call the internal function that does the work. */
- if (call_nr < 0 || call_nr >= NCALLS)
+ if (call_nr < 0 || call_nr >= NCALLS) {
error = ENOSYS;
- else
+ printf("FS, warning illegal %d system call by %d\n", call_nr, who);
+ } else {
error = (*call_vec[call_nr])();
+ }
/* Copy the results back to the user and send reply. */
if (error != SUSPEND) { reply(who, error); }
#define whence m2_i2
#define svrctl_req m2_i1
#define svrctl_argp m2_p1
+#define pm_stime m1_i1
/* The following names are synonyms for the variables in the output message. */
#define reply_type m_type
/* time.c */
_PROTOTYPE( int do_stime, (void) );
-_PROTOTYPE( int do_time, (void) );
-_PROTOTYPE( int do_tims, (void) );
_PROTOTYPE( int do_utime, (void) );
+
/* cmostime.c */
_PROTOTYPE( int do_cmostime, (void) );
do_unlink, /* 10 = unlink */
no_sys, /* 11 = waitpid */
do_chdir, /* 12 = chdir */
- do_time, /* 13 = time */
+ no_sys, /* 13 = time */
do_mknod, /* 14 = mknod */
do_chmod, /* 15 = chmod */
do_chown, /* 16 = chown */
do_unlink, /* 40 = rmdir */
do_dup, /* 41 = dup */
do_pipe, /* 42 = pipe */
- do_tims, /* 43 = times */
+ no_sys, /* 43 = times */
no_sys, /* 44 = (prof) */
no_sys, /* 45 = unused */
do_set, /* 46 = setgid */
*
* The entry points into this file are
* do_utime: perform the UTIME system call
- * do_time: perform the TIME system call
- * do_stime: perform the STIME system call
- * do_tims: perform the TIMES system call
+ * do_stime: PM informs FS about STIME system call
*/
#include "fs.h"
}
-
-/*===========================================================================*
- * do_time *
- *===========================================================================*/
-PUBLIC int do_time()
-
-{
-/* Perform the time(tp) system call. */
-
- m_out.reply_l1 = clock_time(); /* return time in seconds */
- 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'.
- */
-
- register int k;
- clock_t uptime;
-
- if (!super_user) return(EPERM);
- if ( (k=sys_getuptime(&uptime)) != OK) panic("do_stime error", k);
- boottime = (long) m_in.tp - (uptime/HZ);
+/* Perform the stime(tp) system call. */
+ boottime = (long) m_in.pm_stime;
return(OK);
}
-/*===========================================================================*
- * do_tims *
- *===========================================================================*/
-PUBLIC int do_tims()
-{
-/* Perform the times(buffer) system call. */
-
- clock_t t[5];
-
- sys_times(who, t);
- m_out.reply_t1 = t[0];
- m_out.reply_t2 = t[1];
- m_out.reply_t3 = t[2];
- m_out.reply_t4 = t[3];
- m_out.reply_t5 = t[4];
- return(OK);
-}
printf("%8s ", rp->p_name);
j = proc_nr(rp);
switch(rp->p_type) {
- case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break;
- case P_TASK: printf("[%3d] ", proc_nr(rp)); break;
- case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break;
- case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break;
- case P_SERVER: printf("(%3d) ", proc_nr(rp)); break;
- default: printf(" %3d ", proc_nr(rp));
+ case P_IDLE: printf("/%2d/ ", proc_nr(rp)); break;
+ case P_TASK: printf("[%2d] ", proc_nr(rp)); break;
+ case P_SYSTEM: printf("<%2d> ", proc_nr(rp)); break;
+ case P_DRIVER: printf("{%2d} ", proc_nr(rp)); break;
+ case P_SERVER: printf("(%2d) ", proc_nr(rp)); break;
+ default: printf(" %2d ", proc_nr(rp));
}
for (j=proc_nr(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
return;
}
- printf("\n-pid- -pri- --pc-- --sp-- -user- -sys- -text- -data- -size- -flags- -command-\n");
+ printf("\n--nr/name--- -q- -sc- -user- -sys- -text- -data- -size- -flags- -command-\n");
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
if (isemptyp(rp)) continue;
size = rp->p_memmap[T].mem_len
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
switch(rp->p_type) {
- case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break;
- case P_TASK: printf("[%3d] ", proc_nr(rp)); break;
- case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break;
- case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break;
- case P_SERVER: printf("(%3d) ", proc_nr(rp)); break;
- default: printf(" %3d ", proc_nr(rp));
+ case P_IDLE: printf("/%2d/ ", proc_nr(rp)); break;
+ case P_TASK: printf("[%2d] ", proc_nr(rp)); break;
+ case P_SYSTEM: printf("<%2d> ", proc_nr(rp)); break;
+ case P_DRIVER: printf("{%2d} ", proc_nr(rp)); break;
+ case P_SERVER: printf("(%2d) ", proc_nr(rp)); break;
+ default: printf(" %2d ", proc_nr(rp));
}
- printf("%3u %7lx%7lx %6lu%6lu%6uK%6uK%6uK %3x",
+ printf("%-7.7s %2u %02.2x %6lu%6lu%6uK%6uK%6uK %3x",
+ rp->p_name,
rp->p_priority,
- (unsigned long) rp->p_reg.pc,
- (unsigned long) rp->p_reg.sp,
- rp->user_time, rp->sys_time,
+ (char) rp->p_call_mask,
+ rp->p_user_time, rp->p_sys_time,
click_to_round_k(text), click_to_round_k(data),
click_to_round_k(size),
rp->p_flags);
if (rp->p_flags == 0) {
printf(" ");
}
- printf(" %s\n", rp->p_name);
+ printf("\n");
}
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
oldrp = rp;
PRIVATE void memmap_dmp()
{
register struct proc *rp;
- static struct proc *oldrp = cproc_addr(HARDWARE);
+ static struct proc *oldrp = proc;
int r, n = 0;
phys_clicks size;
return;
}
- printf("\n--proc name- -----text----- -----data----- ----stack----- -size-\n");
+ printf("\n-nr/name--- --pc-- --sp-- -----text----- -----data----- ----stack----- --size-\n");
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
if (isemptyp(rp)) continue;
if (++n > 23) break;
size = rp->p_memmap[T].mem_len
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
- rp->p_memmap[D].mem_phys);
- printf("%3d %-7.7s %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n",
+ printf("%3d %-7.7s%7lx%7lx %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n",
proc_nr(rp),
rp->p_name,
+ (unsigned long) rp->p_reg.pc,
+ (unsigned long) rp->p_reg.sp,
rp->p_memmap[T].mem_vir, rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len,
rp->p_memmap[D].mem_vir, rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,
rp->p_memmap[S].mem_vir, rp->p_memmap[S].mem_phys, rp->p_memmap[S].mem_len,
click_to_round_k(size));
}
- if (rp == END_PROC_ADDR) rp = cproc_addr(HARDWARE);
+ if (rp == END_PROC_ADDR) rp = proc;
else printf("--more--\r");
oldrp = rp;
}
CFLAGS = -I$i
LDFLAGS = -i
-OBJ = main.o forkexit.o break.o exec.o dmp.o \
+OBJ = main.o forkexit.o break.o exec.o dmp.o time.o \
signal.o alloc.o utility.o table.o trace.o getset.o misc.o
# build local binary
int parent_waiting, right_child;
pid_t pidarg, procgrp;
struct mproc *p_mp;
+ clock_t t[5];
proc_nr = (int) (rmp - mproc); /* get process slot number */
/* If the exited process has a timer pending, kill it. */
if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr, (unsigned) 0);
+ /* Do accounting: fetch usage times and accumulate at parent. */
+ sys_times(proc_nr, t);
+ p_mp = &mproc[rmp->mp_parent]; /* process' parent */
+ p_mp->mp_child_utime = t[2];
+ p_mp->mp_child_stime = t[3];
+
/* 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_xit(rmp->mp_parent, proc_nr);
/* The process slot can only be freed if the parent has done a WAIT. */
rmp->mp_exitstatus = (char) exit_status;
- p_mp = &mproc[rmp->mp_parent]; /* process' parent */
pidarg = p_mp->mp_wpid; /* who's being waited for? */
parent_waiting = p_mp->mp_flags & WAITING;
setreply(child->mp_parent, child->mp_pid);
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
- /* Release the process table entry. */
+ /* Release the process table entry and reinitialize some field. */
child->mp_flags = 0;
+ child->mp_child_utime = 0;
+ child->mp_child_stime = 0;
procs_in_use--;
}
if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM);
rmp->mp_procgrp = rmp->mp_pid;
tell_fs(SETSID, who, 0, 0);
- /*FALL THROUGH*/
+ /* fall through */
case GETPGRP:
r = rmp->mp_procgrp;
#include "mproc.h"
#include "param.h"
+#include "../../kernel/const.h"
#include "../../kernel/type.h"
FORWARD _PROTOTYPE( void get_work, (void) );
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 */
#define DONT_SWAP 0x1000 /* never swap out this process */
#define NIL_MPROC ((struct mproc *) 0)
+
#define reboot_size m1_i2
#define svrctl_req m2_i1
#define svrctl_argp m2_p1
+#define stime m2_l1
/* The following names are synonyms for the variables in a reply message. */
#define reply_res m_type
#define reply_ptr m2_p1
#define reply_mask m2_l1
#define reply_trace m2_l2
+#define reply_time m2_l1
+#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
_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) );
+
/* trace.c */
_PROTOTYPE( int do_trace, (void) );
_PROTOTYPE( void stop_proc, (struct mproc *rmp, int sig_nr) );
no_sys, /* 10 = unlink */
do_waitpid, /* 11 = waitpid */
no_sys, /* 12 = chdir */
- no_sys, /* 13 = time */
+ do_time, /* 13 = time */
no_sys, /* 14 = mknod */
no_sys, /* 15 = chmod */
no_sys, /* 16 = chown */
no_sys, /* 22 = umount */
do_getset, /* 23 = setuid */
do_getset, /* 24 = getuid */
- no_sys, /* 25 = stime */
+ do_stime, /* 25 = stime */
do_trace, /* 26 = ptrace */
do_alarm, /* 27 = alarm */
no_sys, /* 28 = fstat */
no_sys, /* 40 = rmdir */
no_sys, /* 41 = dup */
no_sys, /* 42 = pipe */
- no_sys, /* 43 = times */
+ do_times, /* 43 = times */
no_sys, /* 44 = (prof) */
no_sys, /* 45 = unused */
do_getset, /* 46 = setgid */
* tell_fs(SETSID, proc, 0, 0)
* tell_fs(SETUID, proc, realuid, effuid)
* tell_fs(UNPAUSE, proc, signr, 0)
+ * tell_fs(STIME, time, 0, 0)
*/
message m;