📄 m_ultrix4.c
字号:
#ifdef vax#define PCTCPU_NONZERO (pp->p_pctcpu != 0.0)#else#define PCTCPU_NONZERO (pp->p_pctcpu != 0)#endif total_procs++; process_states[pp->p_stat]++; if ((pp->p_stat != SZOMB) && (pp->p_stat != SIDL) && (show_idle || PCTCPU_NONZERO || (pp->p_stat == SRUN)) && (!show_uid || pp->p_uid == (uid_t)sel->uid)) { *prefp++ = pp; active_procs++; if (getu(pp, &u) == -1) { PROCTIME(pp) = 0; } else { PROCTIME(pp) = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec; } } } } /* if requested, sort the "interesting" processes */ if (compare != NULL) { qsort((char *)pref, active_procs, sizeof(struct proc *), compare); } /* remember active and total counts */ si->p_total = total_procs; si->p_active = pref_len = active_procs; /* pass back a handle */ handle.next_proc = pref; handle.remaining = active_procs; return((caddr_t)&handle);}char fmt[MAX_COLS]; /* static area where result is built */char *format_next_process(handle, get_userid)caddr_t handle;char *(*get_userid)();{ struct proc *pp; double pct; int where; struct user u; struct handle *hp; /* find and remember the next proc structure */ hp = (struct handle *)handle; pp = *(hp->next_proc++); hp->remaining--; /* get the process's user struct */ where = getu(pp, &u); if (where == -1) { (void) strcpy(u.u_comm, "<swapped>"); } else { /* set u_comm for system processes */ if (u.u_comm[0] == '\0') { if (pp->p_pid == 0) { (void) strcpy(u.u_comm, "Swapper"); } else if (pp->p_pid == 2) { (void) strcpy(u.u_comm, "Pager"); } } if (where == 1) { /* * Print swapped processes as <pname> */ char buf[sizeof(u.u_comm)]; (void) strncpy(buf, u.u_comm, sizeof(u.u_comm)); u.u_comm[0] = '<'; (void) strncpy(&u.u_comm[1], buf, sizeof(u.u_comm) - 2); u.u_comm[sizeof(u.u_comm) - 2] = '\0'; (void) strncat(u.u_comm, ">", sizeof(u.u_comm) - 1); u.u_comm[sizeof(u.u_comm) - 1] = '\0'; } } /* calculate the base for cpu percentages */ pct = pctdouble(pp->p_pctcpu); /* format this entry */ sprintf(fmt, Proc_format, pp->p_pid, (*get_userid)(pp->p_uid), pp->p_pri - PZERO, pp->p_nice - NZERO, format_k(pagetok(PROCSIZE(pp))), format_k(pagetok(pp->p_rssize)), state_abbrev[pp->p_stat], format_time(PROCTIME(pp)), 100.0 * weighted_cpu(pct, pp), 100.0 * pct, printable(u.u_comm)); /* return the result */ return(fmt);}/* * getu(p, u) - get the user structure for the process whose proc structure * is pointed to by p. The user structure is put in the buffer pointed * to by u. Return 0 if successful, -1 on failure (such as the process * being swapped out). */#ifdef ibm032static struct alignuser { char userfill[UPAGES*NBPG-sizeof (struct user)]; struct user user;} au;# define USERSIZE sizeof(struct alignuser)# define GETUSER(b) (&au)# define SETUSER(b) *(b) = au.user#else# define USERSIZE sizeof(struct user)# define GETUSER(b) (b)# define SETUSER(b) /* Nothing */#endifgetu(p, u)struct proc *p;struct user *u;{ struct pte uptes[UPAGES]; caddr_t upage; struct pte *pte; int nbytes, n; /* * Check if the process is currently loaded or swapped out. The way we * get the u area is totally different for the two cases. For this * application, we just don't bother if the process is swapped out. */ if ((p->p_sched & SLOAD) == 0) {#ifdef DOSWAP if (lseek(swap, (long)dtob(p->p_swaddr), 0) == -1) { perror("lseek(swap)"); return(-1); } if (read(swap, (char *) GETUSER(u), USERSIZE) != USERSIZE) { perror("read(swap)"); return(-1); } SETUSER(u); return (1);#else return(-1);#endif } /* * Process is currently in memory, we hope! */ if (!getkval((unsigned long)p->p_addr, (int *)uptes, sizeof(uptes), "!p->p_addr")) {#ifdef DEBUG perror("getkval(uptes)");#endif /* we can't seem to get to it, so pretend it's swapped out */ return(-1); } upage = (caddr_t) GETUSER(u); pte = uptes; for (nbytes = USERSIZE; nbytes > 0; nbytes -= NBPG) { (void) lseek(mem, (long)(pte++->pg_pfnum * NBPG), 0);#ifdef DEBUG perror("lseek(mem)");#endif n = MIN(nbytes, NBPG); if (read(mem, upage, n) != n) {#ifdef DEBUG perror("read(mem)");#endif /* we can't seem to get to it, so pretend it's swapped out */ return(-1); } upage += n; } SETUSER(u); return(0);}/* * check_nlist(nlst) - checks the nlist to see if any symbols were not * found. For every symbol that was not found, a one-line * message is printed to stderr. The routine returns the * number of symbols NOT found. */int check_nlist(nlst)struct nlist *nlst;{ int i; /* check to see if we got ALL the symbols we requested */ /* this will write one line to stderr for every symbol not found */ i = 0; while (nlst->n_name != NULL) { if (nlst->n_type == 0) { /* this one wasn't found */ fprintf(stderr, "kernel: no symbol named `%s'\n", nlst->n_name); i = 1; } nlst++; } return(i);}/* * getkval(offset, ptr, size, refstr) - get a value out of the kernel. * "offset" is the byte offset into the kernel for the desired value, * "ptr" points to a buffer into which the value is retrieved, * "size" is the size of the buffer (and the object to retrieve), * "refstr" is a reference string used when printing error meessages, * if "refstr" starts with a '!', then a failure on read will not * be fatal (this may seem like a silly way to do things, but I * really didn't want the overhead of another argument). * */getkval(offset, ptr, size, refstr)unsigned long offset;int *ptr;int size;char *refstr;{ if (lseek(kmem, (long)offset, L_SET) == -1) { if (*refstr == '!') refstr++; (void) fprintf(stderr, "%s: lseek to %s: %s\n", KMEM, refstr, strerror(errno)); quit(23); } if (read(kmem, (char *) ptr, size) == -1) { if (*refstr == '!') return(0); else { (void) fprintf(stderr, "%s: reading %s: %s\n", KMEM, refstr, strerror(errno)); quit(23); } } return(1);} /* comparison routines for qsort *//* * There are currently four possible comparison routines. main selects * one of these by indexing in to the array proc_compares. * * Possible keys are defined as macros below. Currently these keys are * defined: percent cpu, cpu ticks, process state, resident set size, * total virtual memory usage. The process states are ordered as follows * (from least to most important): WAIT, zombie, sleep, stop, start, run. * The array declaration below maps a process state index into a number * that reflects this ordering. *//* First, the possible comparison keys. These are defined in such a way that they can be merely listed in the source code to define the actual desired ordering. */#define ORDERKEY_PCTCPU if (lresult = p2->p_pctcpu - p1->p_pctcpu,\ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)#define ORDERKEY_CPTICKS if ((result = PROCTIME(p2) - PROCTIME(p1)) == 0)#define ORDERKEY_STATE if ((result = sorted_state[p2->p_stat] - \ sorted_state[p1->p_stat]) == 0)#define ORDERKEY_PRIO if ((result = p2->p_pri - p1->p_pri) == 0)#define ORDERKEY_RSSIZE if ((result = p2->p_rssize - p1->p_rssize) == 0)#define ORDERKEY_MEM if ((result = PROCSIZE(p2) - PROCSIZE(p1)) == 0)/* Now the array that maps process state to a weight */static unsigned char sorted_state[] ={ 0, /* not used */ 3, /* sleep */ 1, /* ABANDONED (WAIT) */ 6, /* run */ 5, /* start */ 2, /* zombie */ 4 /* stop */}; /* compare_cpu - the comparison function for sorting by cpu percentage */compare_cpu(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}/* compare_size - the comparison function for sorting by total memory usage */compare_size(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_MEM ORDERKEY_RSSIZE ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return(result);}/* compare_res - the comparison function for sorting by resident set size */compare_res(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_RSSIZE ORDERKEY_MEM ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return(result);}/* compare_time - the comparison function for sorting by total cpu time */compare_time(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_CPTICKS ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}/* * proc_owner(pid) - returns the uid that owns process "pid", or -1 if * the process does not exist. * It is EXTREMLY IMPORTANT that this function work correctly. * If top runs setuid root (as in SVR4), then this function * is the only thing that stands in the way of a serious * security problem. It validates requests for the "kill" * and "renice" commands. */int proc_owner(pid)int pid;{ int cnt; struct proc **prefp; struct proc *pp; prefp = pref; cnt = pref_len; while (--cnt >= 0) { if ((pp = *prefp++)->p_pid == (pid_t)pid) { return((int)pp->p_uid); } } return(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -