Path: utzoo!mnetor!uunet!husc6!hao!gatech!udel!mmdf From: Postmaster@locke.bitnet (PMDF Mail Server) Newsgroups: comp.os.minix Subject: Undeliverable mail Message-ID: <860@louie.udel.EDU> Date: 19 Dec 87 20:40:49 GMT Sender: mmdf@udel.EDU Lines: 660 The message could not be delivered to: Addressee: MINIX Reason: %MAIL-E, no such user MINIX at node LOCKE ---------------------------------------- Received: from JNET-DAEMON by locke.hs.washington.edu; Sat, 19 Dec 87 12:37 PST Received: From NDSUVM1(MAILER) by UWALOCKE with RSCS id 4947 for MINIX@UWALOCKE; Sat, 19 Dec 87 12:37 PST Received: by NDSUVM1 (Mailer X1.24) id 4908; Sat, 19 Dec 87 14:20:30 CST Date: 19 Dec 87 09:14:10 GMT From: monty walls Subject: PS for MINIX Sender: Minix operating system To: Local Redistribution Reply-to: INFO-MINIX@UDEL.edu Comments: To: info-minix@UDEL.EDU Enclosed is my implementation of PS for minix. Please excuse the strange coding style. PS expects a native minix maintence enviornment( minix c compiler, asld, ...). For a cross compiler based minix it will require some changes. This version of PS is based on the V7 documentation with some slight changes in the output for minix. ---------------------cut here ---------------------------------------- echo x - maint.info gres '^X' '' > maint.info << '/' XB 71C6 _proc XB 8216 _aout XB 3076 _mproc XB 5CC2 _fproc / echo x - maint.sh gres '^X' '' > maint.sh << '/' Xgrep '_proc$' ../kernel/kernel.map >/etc/maint.info Xgrep _aout ../kernel/kernel.map >>/etc/maint.info Xgrep _mproc ../mm/mm.map >>/etc/maint.info Xgrep _fproc ../fs/fs.map >>/etc/maint.info Xcat /etc/maint.info / echo x - makefile gres '^X' '' > makefile << '/' X# ps needs offsets for X# 1). proc(kernel) X# 2). aout(kernel) X# 3). fproc(fs) X# 4). mproc(mm) X# 5). getopts X# X# These do not normally change except after maintence to the X# the system(fs,bootblok,mm,kernel) that adds or deletes variables X# from working storage. What I do is maintain an info file containing X# the kernel, mm, fs offsets that are automatically generated by making X# the system software(examine maint.sh). X# X# X# ps needs the setuid bit set & 4096 bytes of memory X# Xl=/usr/lib Xi=/usr/include XCFLAGS= -Di8088 X Xpsobj = ps.s psutil.s ps_mm.s ps_k.s ps_fs.s ps_aout.s Xps: $(psobj) X @asld -T. -o ps $l/crtso.s $(psobj) $l/libaux.a $l/libc.a $l/end.s X / echo x - ps.c gres '^X' '' > ps.c << '/' X/* X * ps: display processes X * options: X * a: - wants information about all processes with terminals X * l: - long listing X * x: - even processes with no terminals X * X * author: Monty Walls X * written: 11/18/87 X * Copyright: Copyright (c) 1987 by Monty Walls. X * Not derived from licensed software. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). This notice must remain intact. X * 2). The author is not responsible for the consequences of use X * this software, no matter how awful, even if they X * arise from defects in it. X * 3). Altered version must not be represented as being the X * original software. X * X * change log: X * X * mrw(12/1/87) - 1) changed method for determining offsets for X * kernel(aout, proc), mm(mproc), fs(fproc). X * now we read it from file(no longer maintence X * level dependent). X */ X X#include "/usr/src/h/const.h" X#include "/usr/src/h/type.h" X#include "/usr/src/h/callnr.h" X#include "/usr/src/h/com.h" X#include "/usr/src/h/error.h" X#include "/usr/src/kernel/const.h" X#include "/usr/src/kernel/type.h" X#include "/usr/src/kernel/glo.h" X#include "/usr/src/kernel/proc.h" X X#include X#include "ps.h" X Xint errflag = 0; Xlong _aout, _kproc, _mproc, _fproc; Xlong mm_offset, fs_offset; X Xextern int getopt(), ps_k(); Xextern int ps_fs(), ps_mm(); Xextern int print_ps(); Xextern long getlong(), getblock(); Xextern FILE *fopen(); X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X FILE *fd; X int c, n, opt = 0; X unsigned ptr; X struct proc fs_proc, mm_proc; X struct process_status p; X char seg_flag[2]; X char verify_name[MAXSTR]; X X while ((c = getopt(argc, argv, OPTIONS)) != EOF) { X switch (c) { X case 'a': X opt |= ALL; X break; X case 'l': X opt |= VERBOSE; X break; X case 'x': X opt |= TERMINALS; X break; X case '?': X default: X errflag++; X break; X } X } X if (errflag) { X fprintf(stderr,"USAGE: %s [-%s ]\n",argv[0],OPTIONS); X exit(2); X } X if ((fd = fopen(MAINT_INFO,"r")) != NULL) { X /* get maintence dependent kernel info or panic */ X if (fscanf(fd, "%1s %x %s", seg_flag, &ptr, verify_name) == 3) { X if (strcmp(PROC,verify_name)) { X fprintf(stderr,"ERROR: %s - invalid specification for proc(%s) in %s\n", argv[0], verify_name, MAINT_INFO); X exit(1); X } X else X _kproc = ptr + KERNELBASE; X } X else { X fprintf(stderr,"ERROR: %s - EOF on scanning kernel info in %s\n", argv[0], MAINT_INFO); X exit(1); X } X if (fscanf(fd, "%1s %x %s", seg_flag, &ptr, verify_name) == 3) { X if (strcmp(AOUT,verify_name)) { X fprintf(stderr,"ERROR: %s - invalid specification for aout(%s) in %s\n", argv[0], verify_name, MAINT_INFO); X exit(1); X } X else X _aout = ptr + KERNELBASE; X } X else { X fprintf(stderr,"ERROR: %s - EOF on scanning kernel info in %s\n", argv[0], MAINT_INFO); X exit(1); X } X /* get maintence dependent mm info or panic */ X if (fscanf(fd, "%1s %x %s", seg_flag, &ptr, verify_name) == 3) { X if (strcmp(MPROC,verify_name)) { X fprintf(stderr,"ERROR: %s - invalid specification for mproc(%s ) in %s\n", argv[0], verify_name, MAINT_INFO); X exit(1); X } X else X _mproc = ptr; X } X else { X fprintf(stderr,"ERROR: %s - EOF on scanning MM info in %s\n", argv[0], MAINT_INFO); X exit(1); X } X /* get maintence dependent fs info or panic */ X if (fscanf(fd, "%1s %x %s", seg_flag, &ptr, verify_name) == 3) { X if (strcmp(FPROC,verify_name)) { X fprintf(stderr,"ERROR: %s - invalid specification for fproc(%s ) in %s\n", argv[0], verify_name, MAINT_INFO); X exit(1); X } X else X _fproc = ptr; X } X else { X fprintf(stderr,"ERROR: %s - EOF on scanning FS info in %s\n", argv[0], MAINT_INFO); X exit(1); X } X fclose(fd); X } X else { X fprintf(stderr,"ERROR: %s could not open %s\n",argv[0],MAINT_INFO); X exit(1); X } X X if ((fd = fopen(KERNEL,"r")) != NULL) { X /* compute the mem offsets for mm and fs */ X getblock(fd, _kproc+(MM_SLOT)*sizeof(struct proc), &mm_proc, sizeof (struct proc)); X getblock(fd, _kproc+(FS_SLOT)*sizeof(struct proc), &fs_proc, sizeof (struct proc)); X mm_offset = _mproc+mm_proc.p_map[D].mem_phys*CLICK_SIZE; X fs_offset = _fproc+fs_proc.p_map[D].mem_phys*CLICK_SIZE; X X print_hdr(stdout,opt); X /* now loop through slots telling about them */ X for (n = 0; n < NR_PROCS; n++) { X if (ps_k(fd, n+NR_TASKS, &p)) { /* get kernel ps info */ X ps_mm(fd, n, &p); /* get mm ps info */ X ps_fs(fd, n, &p); /* get fs ps info */ X ps_aout(fd, n, &p); /* get cmd */ X print_ps(stdout, opt, &p); X } X } X } X else { X perror(argv[0]); X exit(2); X } X} X Xprint_ps(fd, opt, p) XFILE *fd; Xint opt; Xstruct process_status *p; X{ X if (p->tty || (opt & TERMINALS)) { X if (opt & VERBOSE) { /* flags & status */ X fprintf(fd," %2.2o",p->flag); X fprintf(fd," %c",p->status); X if (p->real_uid != -1) X fprintf(fd, " %4.4d",p->real_uid); X else X fputs(" ----",fd); X } X X fprintf(fd," %4.4d",p->pid); X X if (opt & VERBOSE) { X fprintf(fd," %4.4d",p->owner); X showname(fd, " ", p->getfrom); X fprintf(fd," %5.5X",p->addr); X fprintf(fd," %2.2x",p->size); X } X X if (p->tty) X fprintf(fd, " tty%1.1d", (int)((p->tty >> MINOR) & 0377)); X else X fputs(" ?",fd); X X fprintf(fd, " %2.2d:%02.2d", (int)(p->time / 3600),(int)(p->time / 60 % 60)); X X if (p->pgm) { X fprintf(fd," %s",p->pgm); X free(p->pgm); X } X else { X showname(fd," ",p->slot-NR_TASKS); X } X fputc('\n',fd); X fflush(fd); X } X} X Xprint_hdr(fd, opt) XFILE *fd; Xint opt; X{ X if (opt & VERBOSE) { /* flags & status */ X fputs(" F S UID",fd); X } X fputs(" PID",fd); X if (opt & VERBOSE) X fputs(" PPID WCHAN ADDR SZ",fd); X fputs(" TTY TIME CMD\n",fd); X fflush(fd); X} / echo x - ps.h gres '^X' '' > ps.h << '/' X/* X * ps : display process status for executing process X */ X X/* device name for main memory */ X#define KERNEL "/dev/mem" X X/* info filename for system */ X#define MAINT_INFO "/etc/maint.info" X X/* variable names */ X#define PROC "_proc" X#define AOUT "_aout" X#define MPROC "_mproc" X#define FPROC "_fproc" X X/* KERNEL BASE ADDRESS */ X#define KERNELBASE ((long)03000) X X/* slot indexes for fs & mm */ X#define FS_SLOT (NR_TASKS+FS_PROC_NR) /* slot number in proc table o f fs */ X#define MM_SLOT (NR_TASKS+MM_PROC_NR) /* slot number in proc table o f mm */ X X/* ps: options X * a: - wants information about all processes with terminals X * l: - long listing X * x: - even processes with no terminals X */ X#define OPTIONS "alx" X X/* bit patterns for selected options */ X#define VERBOSE 0x04 X#define ALL 0x08 X#define TERMINALS 0x10 X X#define MAXSTR 256 X Xstruct process_status { X int pid; /* process pid */ X int slot; /* kernel slot number */ X int getfrom; /* slot of who task wants to receive from */ X int owner; /* pid of parent process */ X uid real_gid; X uid real_uid; X uid effective_gid; X uid effective_uid; X real_time time; X dev_nr tty; X int size; /* bytes total for process */ X long addr; /* physical base address of process */ X char *pgm; /* pointer to cmd name */ X int pflag; /* kernel process flags */ X unsigned flag; /* flag: IN_USE, WAITING, HANGING, PAUSED .. */ X char status; /* flag: NOT_SUSPENDED, SUSPENDED, NOT_REVIVED, REVIVING */ X}; / echo x - ps_aout.c gres '^X' '' > ps_aout.c << '/' X/* X * get aout table entry corresponding to n X */ X X#include "/usr/src/h/const.h" X#include "/usr/src/h/type.h" X#include "/usr/src/h/callnr.h" X#include "/usr/src/h/com.h" X#include "/usr/src/h/error.h" X#include "/usr/src/kernel/const.h" X#include "/usr/src/kernel/type.h" X#include "/usr/src/kernel/glo.h" X#include "/usr/src/kernel/proc.h" X X#include X#include "ps.h" X Xextern long getlong(); Xextern char *strsave(); Xextern long _aout; X Xps_aout(fd, n, p) XFILE *fd; Xint n; Xstruct process_status *p; X{ X long where; X int limit = MAXSTR; X char buf[MAXSTR], *bp = buf; X X if (n == LOW_USER + 1) { X p->pgm = strsave("/bin/sh"); X } X else { X where = getlong(fd, (_aout+n*sizeof(long))); X if (where) { X fseek(fd, where, 0); X while (*bp++ = fgetc(fd)) X if (--limit == 0) X break; X if (bp == buf) X p->pgm = NULL; X else X p->pgm = strsave(buf); X } X else X p->pgm = NULL; X } X} X / echo x - ps_fs.c gres '^X' '' > ps_fs.c << '/' X/* X * ps_fs: get information for ps from fs X */ X#include "/usr/src/h/const.h" X#include "/usr/src/h/type.h" X#include "/usr/src/h/stat.h" X#include "/usr/src/fs/const.h" X#include "/usr/src/fs/type.h" X#include "/usr/src/fs/fproc.h" X X#include "ps.h" X#include X Xextern getblock(); Xextern long fs_offset; X Xps_fs(fd, n, p) XFILE *fd; Xint n; Xstruct process_status *p; X{ X long fp; X struct fproc fs_info; X X /* on entry n contains the slot number we are to look up */ X fp = fs_offset + (n * sizeof(struct fproc)); X getblock(fd, fp, &fs_info, sizeof(struct fproc)); X X /* no reliable way to check if this is right task we are looking at */ X p->tty = fs_info.fs_tty; X if (fs_info.fp_suspended) X p->status = 'w'; X else X p->status = 'r'; X return; X} / echo x - ps_k.c gres '^X' '' > ps_k.c << '/' X/* X * ps: kernel dependent information retieval X */ X X#include "/usr/src/h/const.h" X#include "/usr/src/h/type.h" X#include "/usr/src/h/callnr.h" X#include "/usr/src/h/com.h" X#include "/usr/src/h/error.h" X#include "/usr/src/kernel/const.h" X#include "/usr/src/kernel/type.h" X#include "/usr/src/kernel/glo.h" X#include "/usr/src/kernel/proc.h" X X#include X#include "ps.h" X Xextern getblock(); Xextern long _kproc; X Xint Xps_k(fd, n, p) XFILE *fd; Xint n; Xstruct process_status *p; X{ X long kp; X struct proc k_info, k_getfrom; X X /* on entry n contains the slot number were do look ups on */ X kp = _kproc + (n * sizeof(struct proc)); X X /* copy mem to us for looking at */ X getblock(fd, kp, &k_info, sizeof(struct proc)); X X if (k_info.p_flags & P_SLOT_FREE) X return (0); X else { X /* valid slot */ X p->pid = k_info.p_pid; X p->slot = n; X p->pflag = k_info.p_flags; X p->time = k_info.user_time + k_info.sys_time; X p->addr = (long)k_info.p_map[T].mem_phys*CLICK_SIZE; X p->size = ((long)k_info.p_map[T].mem_len+(long)k_info.p_map[D].mem_len + (long)k_info.p_map[S].mem_len)*CLICK_SIZE/BLOCK_SIZE; X p->getfrom = k_info.p_getfrom; X return (1); X } X} / echo x - ps_mm.c gres '^X' '' > ps_mm.c << '/' X/* X * ps_mm: get information for ps from mm X */ X#include "/usr/src/h/const.h" X#include "/usr/src/h/type.h" X#include "/usr/src/h/stat.h" X#include "/usr/src/mm/const.h" X#include "/usr/src/mm/mproc.h" X X#include "ps.h" X#include X Xextern getblock(); Xextern long mm_offset; X Xps_mm(fd, n, p) XFILE *fd; Xint n; Xstruct process_status *p; X{ X static __ps_mm_descent; /* stop recursion */ X long mp; X struct mproc mm_info, mm_parent; X X /* on entry n contains the slot number were do look ups on */ X mp = mm_offset + (n * sizeof(struct mproc)); X X /* get copy of this proc entry for us */ X getblock(fd, mp, &mm_info, sizeof(struct mproc)); X X if (p->pid == mm_info.mp_pid) { /* safety */ X if (!__ps_mm_descent) { X /* get the pid of the parent process */ X __ps_mm_descent = 1; X ps_mm(fd, mm_info.mp_parent, &mm_parent); X p->owner = mm_parent.mp_pid; X } X else X __ps_mm_descent = 0; X /* fill in the normal info */ X p->real_gid = mm_info.mp_realgid; X p->real_uid = mm_info.mp_realuid; X p->effective_gid = mm_info.mp_effgid; X p->effective_uid = mm_info.mp_effuid; X p->flag = mm_info.mp_flags; X } X else { X p->owner = -1; X p->real_gid = -1; X p->real_uid = -1; X p->effective_gid = -1; X p->effective_uid = -1; X p->flag = 0; X } X return; X} X / echo x - psutil.c gres '^X' '' > psutil.c << '/' X/* X * utility routines for ps X */ X X#include "/usr/src/h/const.h" X#include "/usr/src/h/com.h" X#include X Xunsigned Xgetword(fd, offset) XFILE *fd; Xlong offset; X{ X int n; X X fseek(fd, offset, 0); X fread(&n, sizeof(int), 1, fd); X return (n); X} X Xlong Xgetlong(fd, offset) XFILE *fd; Xlong offset; X{ X long n; X X fseek(fd, offset, 0); X fread(&n, sizeof(long), 1, fd); X return (n); X} X Xunsigned Xgetblock(fd, offset, p, cnt) XFILE *fd; Xlong offset; Xchar *p; Xint cnt; X{ X fseek(fd, offset, 0); X fread(p, cnt, 1, fd); X return (offset); X} X X/* fast and simple way of showing the process name */ X Xstatic char *taskname[] = { X "MM ", X "FS ", X "INIT " X}; X Xshowname(fd,pad,n) XFILE *fd; Xchar *pad; Xint n; X{ X if (pad) X fputs(pad,fd); X if (n >= ANY || n < 0) X fputs("ANY ",fd); X else if (n <= LOW_USER) X fprintf(fd,"%6.6s",taskname[n]); X else X fprintf(fd,"%4.4d", n); X} X / ` X{ X X{ X . X. X.x %sTTTTT2T,fop[T]) == ) == )ty defi/* spo 2ep->st by by upare('w* n>ra s\ns\nssusr/src* n>fi/' X//' X//