📄 m_hpux7.c
字号:
{ register int i; register int total_procs; register int active_procs; register struct proc **prefp; register struct proc *pp; /* these are copied out of sel for speed */ int show_idle; int show_system; int show_uid; int show_command; /* read all the proc structures in one fell swoop */ (void) getkval(proc, (int *)pbase, bytes, "proc array"); /* get a pointer to the states summary array */ si->procstates = process_states; /* set up flags which define what we are going to select */ show_idle = sel->idle; show_system = sel->system; show_uid = sel->uid != -1; show_command = sel->command != NULL; /* count up process states and get pointers to interesting procs */ total_procs = 0; active_procs = 0; memset((char *)process_states, 0, sizeof(process_states)); prefp = pref; for (pp = pbase, i = 0; i < nproc; pp++, i++) { /* * Place pointers to each valid proc structure in pref[]. * Process slots that are actually in use have a non-zero * status field. Processes with SSYS set are system * processes---these get ignored unless show_sysprocs is set. */ if (pp->p_stat != 0 && (show_system || ((pp->p_flag & SSYS) == 0))) { total_procs++; process_states[pp->p_stat]++; if ((pp->p_stat != SZOMB) && (show_idle || (pp->p_pctcpu != 0) || (pp->p_stat == SRUN)) && (!show_uid || pp->p_uid == (uid_t)sel->uid)) { *prefp++ = pp; active_procs++; } } } /* 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)();{ register struct proc *pp; register long cputime; register 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 and set cputime */ where = getu(pp, &u); if (where == -1) { (void) strcpy(u.u_comm, "<swapped>"); cputime = 0; } 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'; } cputime = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec; } /* 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(cputime), 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). */#define USERSIZE sizeof(struct user)getu(p, u)register struct proc *p;struct user *u;{ struct pte uptes[UPAGES]; register caddr_t upage; register struct pte *pte; register 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_flag & SLOAD) == 0) {#ifdef DOSWAP if (lseek(swap, (long)dtob(p->p_swaddr), 0) == -1) { perror("lseek(swap)"); return(-1); } if (read(swap, (char *) u, USERSIZE) != USERSIZE) { perror("read(swap)"); return(-1); } 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) 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; } 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)register struct nlist *nlst;{ register 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 routine for qsort *//* * proc_compare - comparison function for "qsort" * Compares the resource consumption of two processes using five * distinct keys. The keys (in descending order of importance) are: * percent cpu, cpu ticks, 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. */static unsigned char sorted_state[] ={ 0, /* not used */ 3, /* sleep */ 1, /* ABANDONED (WAIT) */ 6, /* run */ 5, /* start */ 2, /* zombie */ 4 /* stop */}; proc_compare(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; /* compare percent cpu (pctcpu) */ if ((lresult = p2->p_pctcpu - p1->p_pctcpu) == 0) { /* use cpticks to break the tie */ if ((result = p2->p_cpticks - p1->p_cpticks) == 0) { /* use process state to break the tie */ if ((result = sorted_state[p2->p_stat] - sorted_state[p1->p_stat]) == 0) { /* use priority to break the tie */ if ((result = p2->p_pri - p1->p_pri) == 0) { /* use resident set size (rssize) to break the tie */ if ((result = p2->p_rssize - p1->p_rssize) == 0) { /* use total memory to break the tie */ result = PROCSIZE(p2) - PROCSIZE(p1); } } } } } else { result = lresult < 0 ? -1 : 1; } return(result);}void (*signal(sig, func))() int sig; void (*func)();{ struct sigvec osv, sv; /* * XXX: we should block the signal we are playing with, * in case we get interrupted in here. */ if (sigvector(sig, NULL, &osv) == -1) return BADSIG; sv = osv; sv.sv_handler = func;#ifdef SV_BSDSIG sv.sv_flags |= SV_BSDSIG;#endif if (sigvector(sig, &sv, NULL) == -1) return BADSIG; return osv.sv_handler;}int getpagesize() { return 1 << PGSHIFT; }int setpriority(a, b, c) { errno = ENOSYS; return -1; }/* * 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;{ register int cnt; register struct proc **prefp; register 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 + -