stailey@iris613.gsfc.nasa.gov (Ken Stailey) (03/05/90)
This is a fix for ps.c, by Peter Valkenburg (valke@psy.vu.nl), january 1990. This fix allows it to see the user process names under MINIX ST. It may even be portable to the PC too. If you have PC MINIX I would appreciate some feedback about this. It works by looking at yet another system variable, "aout", an array of proccess names generated for the PF1 key dump by the system task routine, "do_exec()". This hack does not allow you to see path argv[0] too look at the command arguements, but future enhancements will hopefully support this. [climbing on soapbox] Imagine if you had to locate and decode the inode table "by hand" in order to find out basic information about files that the stat() call will tell you. The program "ps" is just about as stupid. Why isn't there a system call to divulge process table entries? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *** ps.c.1.5.3 Sun Mar 4 20:26:32 1990 --- ps.c Sun Mar 4 23:20:07 1990 *************** *** 85,96 **** #define ID_MPROC "_mproc" /* from mm namelist */ #define ID_FPROC "_fproc" /* from fs namelist */ #define ID_TASKTAB "_tasktab" /* from kernel namelist */ /* * Structure for system address info (also layout of ps's database). */ typedef struct { ! struct nlist ke_proc[2], ke_tasktab[2]; struct nlist mm_mproc[2]; struct nlist fs_fproc[2]; } sysinfo_t; --- 85,97 ---- #define ID_MPROC "_mproc" /* from mm namelist */ #define ID_FPROC "_fproc" /* from fs namelist */ #define ID_TASKTAB "_tasktab" /* from kernel namelist */ + #define ID_AOUT "_aout" /* from kernel namelist */ /* * Structure for system address info (also layout of ps's database). */ typedef struct { ! struct nlist ke_proc[2], ke_tasktab[2], ke_aout[2]; struct nlist mm_mproc[2]; struct nlist fs_fproc[2]; } sysinfo_t; *************** *** 104,109 **** --- 105,111 ---- #define MPROC mproc #define FPROC fproc #define TASKTAB tasktab + #define AOUT aout /* default paths for system binaries */ #define KERNEL_PATH "/usr/src/kernel/kernel.mix" *************** *** 125,130 **** --- 127,134 ---- struct tasktab tasktab[NR_TASKS + INIT_PROC_NR + 1]; /* task table */ + phys_bytes aout[NR_TASKS]; + /* * Short and long listing formats: * *************** *** 299,306 **** if (opt_update || (db_fd = open(DBASE_PATH, O_RDONLY)) == -1) { strncpy(sysinfo.ke_proc[0].n_name, ID_PROC, NAME_SIZ); strncpy(sysinfo.ke_tasktab[0].n_name, ID_TASKTAB, NAME_SIZ); ! if (nlist(kpath, sysinfo.ke_proc) != 0 || ! nlist(kpath, sysinfo.ke_tasktab) != 0) err("Can't read kernel namelist"); strncpy(sysinfo.mm_mproc[0].n_name, ID_MPROC, NAME_SIZ); if (nlist(mpath, sysinfo.mm_mproc) != 0) --- 303,312 ---- if (opt_update || (db_fd = open(DBASE_PATH, O_RDONLY)) == -1) { strncpy(sysinfo.ke_proc[0].n_name, ID_PROC, NAME_SIZ); strncpy(sysinfo.ke_tasktab[0].n_name, ID_TASKTAB, NAME_SIZ); ! strncpy(sysinfo.ke_aout[0].n_name, ID_AOUT, NAME_SIZ); ! if (nlist(kpath, sysinfo.ke_proc) != 0 || ! nlist(kpath, sysinfo.ke_tasktab) != 0 || ! nlist(kpath, sysinfo.ke_aout)) err("Can't read kernel namelist"); strncpy(sysinfo.mm_mproc[0].n_name, ID_MPROC, NAME_SIZ); if (nlist(mpath, sysinfo.mm_mproc) != 0) *************** *** 322,328 **** err("Can't read psdatabase"); } (void) close (db_fd); ! /* get kernel tables */ if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH); --- 328,334 ---- err("Can't read psdatabase"); } (void) close (db_fd); ! /* get kernel tables */ if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH); *************** *** 334,339 **** --- 340,349 ---- (vir_bytes) sysinfo.ke_tasktab[0].n_value, (char *) TASKTAB, sizeof(TASKTAB)) != sizeof(TASKTAB)) err("Can't get kernel task table from /dev/kmem"); + if (addrread(kmemfd, (phys_clicks) 0, + (vir_bytes) sysinfo.ke_aout[0].n_value, + (char *) AOUT, sizeof(AOUT)) != sizeof(AOUT)) + err("Can't get kernel aout table from /dev/kmem"); /* get mm/fs tables */ if ((memfd = open(MEM_PATH, O_RDONLY)) == -1) *************** *** 346,352 **** (vir_bytes) sysinfo.fs_fproc[0].n_value, (char *) FPROC, sizeof(FPROC)) != sizeof(FPROC)) err("Can't get fs proc table from /dev/mem"); ! /* now loop through process table and handle each entry */ printf("%s", opt_long ? L_HEADER : S_HEADER); for (i = -NR_TASKS; i < NR_PROCS; i++) { --- 356,362 ---- (vir_bytes) sysinfo.fs_fproc[0].n_value, (char *) FPROC, sizeof(FPROC)) != sizeof(FPROC)) err("Can't get fs proc table from /dev/mem"); ! /* now loop through process table and handle each entry */ printf("%s", opt_long ? L_HEADER : S_HEADER); for (i = -NR_TASKS; i < NR_PROCS; i++) { *************** *** 477,489 **** } if (state != DONE) ! return NULL; /* get a local version of argv[0]; l is offset back from end of stack */ l = (bufp->ps_stack + bufp->ps_ssize) - (bufp->ps_data + (vir_bytes) sp[1].stk_cp); if (l < 0 || l > cnt) ! return NULL; args = &((char *) stk)[cnt - (int) l]; neos = 0; for (cp = args; cp < &((char *) stk)[cnt]; cp++) --- 487,499 ---- } if (state != DONE) ! return (char *) NULL; /* get a local version of argv[0]; l is offset back from end of stack */ l = (bufp->ps_stack + bufp->ps_ssize) - (bufp->ps_data + (vir_bytes) sp[1].stk_cp); if (l < 0 || l > cnt) ! return (char *) NULL; args = &((char *) stk)[cnt - (int) l]; neos = 0; for (cp = args; cp < &((char *) stk)[cnt]; cp++) *************** *** 493,499 **** else *cp = ' '; if (neos != sp[0].stk_i) ! return NULL; return args; } --- 503,509 ---- else *cp = ' '; if (neos != sp[0].stk_i) ! return (char *) NULL; return args; } *************** *** 576,582 **** if (bufp->ps_state == Z_STATE) bufp->ps_args = "<defunct>"; else if (p_nr > INIT_PROC_NR) ! bufp->ps_args = get_args(bufp); return 0; } --- 586,593 ---- if (bufp->ps_state == Z_STATE) bufp->ps_args = "<defunct>"; else if (p_nr > INIT_PROC_NR) ! /* bufp->ps_args = get_args(bufp); */ ! bufp->ps_args = (off_t) AOUT[p_nr]; return 0; } INET stailey@iris613.gsfc.nasa.gov UUCP {backbone}!dftsrv!iris613!stailey
leo@marco.UUCP (Matthias Pfaller) (03/12/90)
In article <1057@dftsrv.gsfc.nasa.gov>, stailey@iris613.gsfc.nasa.gov (Ken Stailey) writes: > > This is a fix for ps.c, by Peter Valkenburg (valke@psy.vu.nl), january 1990. > This fix allows it to see the user process names under MINIX ST. It may > even be portable to the PC too. If you have PC MINIX I would appreciate ^^^^^^^^ ????? Do you real think it is portable to dereference an absolute pointer to read data of another process? The following patch makes the 1.5.3-ps run with the st. It examines, like the pc-version, the stack to figure out the commandname and arguments. It also uses the aout kernel variable (based on <1057@dftsrv.gsfc.nasa.gov>) leo@marco.UUCP (Matthias Pfaller) *** ps.c.1.5.3 Mon Mar 12 16:34:28 1990 --- ps.c Mon Mar 12 16:28:05 1990 *************** *** 85,96 **** #define ID_MPROC "_mproc" /* from mm namelist */ #define ID_FPROC "_fproc" /* from fs namelist */ #define ID_TASKTAB "_tasktab" /* from kernel namelist */ /* * Structure for system address info (also layout of ps's database). */ typedef struct { ! struct nlist ke_proc[2], ke_tasktab[2]; struct nlist mm_mproc[2]; struct nlist fs_fproc[2]; } sysinfo_t; --- 85,104 ---- #define ID_MPROC "_mproc" /* from mm namelist */ #define ID_FPROC "_fproc" /* from fs namelist */ #define ID_TASKTAB "_tasktab" /* from kernel namelist */ + #if (MACHINE == ATARI) + #define ID_AOUT "_aout" /* from kernel namelist */ + #endif /* * Structure for system address info (also layout of ps's database). */ typedef struct { ! struct nlist ke_proc[2], ke_tasktab[2] ! #if (MACHINE == ATARI) ! , ke_aout[2]; ! #else ! ; ! #endif struct nlist mm_mproc[2]; struct nlist fs_fproc[2]; } sysinfo_t; *************** *** 104,109 **** --- 112,120 ---- #define MPROC mproc #define FPROC fproc #define TASKTAB tasktab + #if (MACHINE == ATARI) + #define AOUT aout + #endif /* default paths for system binaries */ #define KERNEL_PATH "/usr/src/kernel/kernel" *************** *** 125,130 **** --- 136,145 ---- struct tasktab tasktab[NR_TASKS + INIT_PROC_NR + 1]; /* task table */ + #if (MACHINE == ATARI) + phys_bytes aout[NR_TASKS]; + #endif + /* * Short and long listing formats: * *************** *** 299,306 **** if (opt_update || (db_fd = open(DBASE_PATH, O_RDONLY)) == -1) { strncpy(sysinfo.ke_proc[0].n_name, ID_PROC, NAME_SIZ); strncpy(sysinfo.ke_tasktab[0].n_name, ID_TASKTAB, NAME_SIZ); if (nlist(kpath, sysinfo.ke_proc) != 0 || ! nlist(kpath, sysinfo.ke_tasktab) != 0) err("Can't read kernel namelist"); strncpy(sysinfo.mm_mproc[0].n_name, ID_MPROC, NAME_SIZ); if (nlist(mpath, sysinfo.mm_mproc) != 0) --- 314,329 ---- if (opt_update || (db_fd = open(DBASE_PATH, O_RDONLY)) == -1) { strncpy(sysinfo.ke_proc[0].n_name, ID_PROC, NAME_SIZ); strncpy(sysinfo.ke_tasktab[0].n_name, ID_TASKTAB, NAME_SIZ); + #if (MACHINE == ATARI) + strncpy(sysinfo.ke_aout[0].n_name, ID_AOUT, NAME_SIZ); + #endif if (nlist(kpath, sysinfo.ke_proc) != 0 || ! nlist(kpath, sysinfo.ke_tasktab) != 0 ! #if (MACHINE == ATARI) ! || nlist(kpath, sysinfo.ke_aout)) ! #else ! )) ! #endif err("Can't read kernel namelist"); strncpy(sysinfo.mm_mproc[0].n_name, ID_MPROC, NAME_SIZ); if (nlist(mpath, sysinfo.mm_mproc) != 0) *************** *** 322,328 **** err("Can't read psdatabase"); } (void) close (db_fd); ! /* get kernel tables */ if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH); --- 345,351 ---- err("Can't read psdatabase"); } (void) close (db_fd); ! /* get kernel tables */ if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH); *************** *** 334,339 **** --- 357,368 ---- (vir_bytes) sysinfo.ke_tasktab[0].n_value, (char *) TASKTAB, sizeof(TASKTAB)) != sizeof(TASKTAB)) err("Can't get kernel task table from /dev/kmem"); + #if (MACHINE == ATARI) + if (addrread(kmemfd, (phys_clicks) 0, + (vir_bytes) sysinfo.ke_aout[0].n_value, + (char *) AOUT, sizeof(AOUT)) != sizeof(AOUT)) + err("Can't get kernel aout table from /dev/kmem"); + #endif /* get mm/fs tables */ if ((memfd = open(MEM_PATH, O_RDONLY)) == -1) *************** *** 346,352 **** (vir_bytes) sysinfo.fs_fproc[0].n_value, (char *) FPROC, sizeof(FPROC)) != sizeof(FPROC)) err("Can't get fs proc table from /dev/mem"); ! /* now loop through process table and handle each entry */ printf("%s", opt_long ? L_HEADER : S_HEADER); for (i = -NR_TASKS; i < NR_PROCS; i++) { --- 375,381 ---- (vir_bytes) sysinfo.fs_fproc[0].n_value, (char *) FPROC, sizeof(FPROC)) != sizeof(FPROC)) err("Can't get fs proc table from /dev/mem"); ! /* now loop through process table and handle each entry */ printf("%s", opt_long ? L_HEADER : S_HEADER); for (i = -NR_TASKS; i < NR_PROCS; i++) { *************** *** 409,419 **** * Warning: this routine is inherently unreliable and probably doesn't work if * ptrs and ints have different sizes. */ ! char *get_args(bufp) ! struct pstat *bufp; { union { int stk_i; char *stk_cp; char stk_c; } stk[ARG_MAX / sizeof(char *)], *sp; --- 438,452 ---- * Warning: this routine is inherently unreliable and probably doesn't work if * ptrs and ints have different sizes. */ ! char *get_args(bufp, p_nr) ! struct pstat *bufp; int p_nr; { union { + #if (CHIP == M68000) /* should be sizeof(int) != sizeof(void *) */ + long stk_i; + #else int stk_i; + #endif char *stk_cp; char stk_c; } stk[ARG_MAX / sizeof(char *)], *sp; *************** *** 421,428 **** int nargv; /* guessed # of (non-NULL) argv pointers seen */ int cnt; /* # of bytes read from stack frame */ int neos; /* # of '\0's seen in argv string space */ off_t l; ! char *cp, *args; if (bufp->ps_ssize < ARG_MAX) --- 454,462 ---- int nargv; /* guessed # of (non-NULL) argv pointers seen */ int cnt; /* # of bytes read from stack frame */ int neos; /* # of '\0's seen in argv string space */ + int flag=0; /* argv not found */ off_t l; ! char *e, *cp, *args; if (bufp->ps_ssize < ARG_MAX) *************** *** 463,469 **** case NULL2: /* two NULLs seen */ if (sp[0].stk_cp == NULL) nargv = 0; /* restart counting */ ! else if (sp[0].stk_i == nargv) state = DONE; /* think i got it */ /* next is same ugly patch as above */ else if (sp > &stk[0] && sp[0].stk_cp == sp[-1].stk_cp) --- 497,507 ---- case NULL2: /* two NULLs seen */ if (sp[0].stk_cp == NULL) nargv = 0; /* restart counting */ ! #if (CHIP == M68000) /* should be sizeof(int) != sizeof(void *) */ ! else if ((sp[0].stk_i & 0xffff) == nargv) ! #else ! else if ((sp[0].stk_i) == nargv) ! #endif state = DONE; /* think i got it */ /* next is same ugly patch as above */ else if (sp > &stk[0] && sp[0].stk_cp == sp[-1].stk_cp) *************** *** 475,501 **** break; } } ! ! if (state != DONE) ! return NULL; /* get a local version of argv[0]; l is offset back from end of stack */ l = (bufp->ps_stack + bufp->ps_ssize) - ! (bufp->ps_data + (vir_bytes) sp[1].stk_cp); if (l < 0 || l > cnt) ! return NULL; args = &((char *) stk)[cnt - (int) l]; neos = 0; ! for (cp = args; cp < &((char *) stk)[cnt]; cp++) if (*cp == '\0') if (++neos >= sp[0].stk_i) break; else *cp = ' '; if (neos != sp[0].stk_i) ! return NULL; ! return args; } /* --- 513,576 ---- break; } } ! ! if (state != DONE) ! flag = 1; /* get a local version of argv[0]; l is offset back from end of stack */ l = (bufp->ps_stack + bufp->ps_ssize) - ! #if (MACHINE == ATARI) ! (vir_bytes) sp[1].stk_cp; ! #else ! (bufp->ps_data + (vir_bytes) sp[1].stk_cp); ! #endif if (l < 0 || l > cnt) ! flag = 1; args = &((char *) stk)[cnt - (int) l]; neos = 0; ! for (cp = args; cp < &((char *) stk)[cnt] && !flag; cp++) if (*cp == '\0') + #if (CHIP == M68000) /* should be sizeof(int) != sizeof(void *) */ + if (++neos >= (sp[0].stk_i & 0xffff)) + #else if (++neos >= sp[0].stk_i) + #endif break; else *cp = ' '; + #if (CHIP == M68000) /* should be sizeof(int) != sizeof(void *) */ + if (neos != (sp[0].stk_i & 0xffff)) + #else if (neos != sp[0].stk_i) ! #endif ! flag = 1; ! if (flag) ! { ! #if (MACHINE == ATARI) ! l = (bufp->ps_stack + bufp->ps_ssize) - (vir_bytes) AOUT[p_nr]; ! args = &((char *) stk)[cnt - (int) l]; ! e = &((char *) stk)[cnt]; ! if ((args - 2) >= (char *)stk) ! { ! args -= 2; ! args[0] = '['; ! args[1] = ' '; ! } ! for (l = 0, cp = args; cp < e && *cp; cp++, l++) ! if (*cp < 0x20 || *cp > 0x7f) ! return (char *) NULL; ! if (cp >= e) ! return (char *) NULL; ! if ((args + strlen(args) + 3) < e) ! strcat(args, " ]"); ! return(args); ! #else ! return (char *) NULL; ! #endif ! } ! else ! return args; } /* *************** *** 576,582 **** if (bufp->ps_state == Z_STATE) bufp->ps_args = "<defunct>"; else if (p_nr > INIT_PROC_NR) ! bufp->ps_args = get_args(bufp); return 0; } --- 651,657 ---- if (bufp->ps_state == Z_STATE) bufp->ps_args = "<defunct>"; else if (p_nr > INIT_PROC_NR) ! bufp->ps_args = get_args(bufp, p_nr); return 0; }