📄 m_freebsd.c
字号:
total_procs++; process_states[(unsigned char) PP(pp, p_stat)]++; if ((PP(pp, p_stat) != SZOMB) && (show_idle || (PP(pp, p_pctcpu) != 0) || (PP(pp, p_stat) == SRUN)) && (!show_uid || EP(pp, e_pcred.p_ruid) == (uid_t)sel->uid)) { *prefp++ = pp; active_procs++; } } } /* if requested, sort the "interesting" processes */ if (compare != NULL) { qsort((char *)pref, active_procs, sizeof(struct kinfo_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[128]; /* static area where result is built */char *format_next_process(handle, get_userid)caddr_t handle;char *(*get_userid)();{ register struct kinfo_proc *pp; register long cputime; register double pct; struct handle *hp; char status[16]; int state; /* find and remember the next proc structure */ hp = (struct handle *)handle; pp = *(hp->next_proc++); hp->remaining--; /* get the process's command name */ if ((PP(pp, p_flag) & P_INMEM) == 0) { /* * Print swapped processes as <pname> */ char *comm = PP(pp, p_comm);#define COMSIZ sizeof(PP(pp, p_comm)) char buf[COMSIZ]; (void) strncpy(buf, comm, COMSIZ); comm[0] = '<'; (void) strncpy(&comm[1], buf, COMSIZ - 2); comm[COMSIZ - 2] = '\0'; (void) strncat(comm, ">", COMSIZ - 1); comm[COMSIZ - 1] = '\0'; } /* * Convert the process's runtime from microseconds to seconds. This * time includes the interrupt time although that is not wanted here. * ps(1) is similarly sloppy. */ cputime = (PP(pp, p_runtime) + 500000) / 1000000; /* calculate the base for cpu percentages */ pct = pctdouble(PP(pp, p_pctcpu)); /* generate "STATE" field */ switch (state = PP(pp, p_stat)) { case SRUN: if (smpmode && PP(pp, p_oncpu) != 0xff) sprintf(status, "CPU%d", PP(pp, p_oncpu)); else strcpy(status, "RUN"); break; case SSLEEP: if (PP(pp, p_wmesg) != NULL) { sprintf(status, "%.6s", EP(pp, e_wmesg)); break; } /* fall through */ default: if (state >= 0 && state < sizeof(state_abbrev) / sizeof(*state_abbrev)) sprintf(status, "%.6s", state_abbrev[(unsigned char) state]); else sprintf(status, "?%5d", state); break; } /* format this entry */ sprintf(fmt, smpmode ? smp_Proc_format : up_Proc_format, PP(pp, p_pid), namelength, namelength, (*get_userid)(EP(pp, e_pcred.p_ruid)), PP(pp, p_priority) - PZERO, /* * normal time -> nice value -20 - +20 * real time 0 - 31 -> nice value -52 - -21 * idle time 0 - 31 -> nice value +21 - +52 */ (PP(pp, p_rtprio.type) == RTP_PRIO_NORMAL ? PP(pp, p_nice) - NZERO : (RTP_PRIO_IS_REALTIME(PP(pp, p_rtprio.type)) ? (PRIO_MIN - 1 - RTP_PRIO_MAX + PP(pp, p_rtprio.prio)) : (PRIO_MAX + 1 + PP(pp, p_rtprio.prio)))), format_k(PROCSIZE(pp)), format_k(pagetok(VP(pp, vm_rssize))), status, smpmode ? PP(pp, p_lastcpu) : 0, format_time(cputime), 100.0 * weighted_cpu(pct, pp), 100.0 * pct, cmdlength, printable(PP(pp, p_comm))); /* return the result */ return(fmt);}/* * 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. */static 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 */ (void) 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). * */static int getkval(offset, ptr, size, refstr)unsigned long offset;int *ptr;int size;char *refstr;{ if (kvm_read(kd, offset, (char *) ptr, size) != size) { if (*refstr == '!') { return(0); } else { fprintf(stderr, "top: kvm_read for %s: %s\n", refstr, strerror(errno)); quit(23); } } return(1);} /* comparison routines 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 */}; #define ORDERKEY_PCTCPU \ if (lresult = (long) PP(p2, p_pctcpu) - (long) PP(p1, p_pctcpu), \ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)#define ORDERKEY_CPTICKS \ if ((result = PP(p2, p_runtime) > PP(p1, p_runtime) ? 1 : \ PP(p2, p_runtime) < PP(p1, p_runtime) ? -1 : 0) == 0)#define ORDERKEY_STATE \ if ((result = sorted_state[(unsigned char) PP(p2, p_stat)] - \ sorted_state[(unsigned char) PP(p1, p_stat)]) == 0)#define ORDERKEY_PRIO \ if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0)#define ORDERKEY_RSSIZE \ if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) #define ORDERKEY_MEM \ if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )/* compare_cpu - the comparison function for sorting by cpu percentage */int#ifdef ORDERcompare_cpu(pp1, pp2)#elseproc_compare(pp1, pp2)#endifstruct proc **pp1;struct proc **pp2;{ register struct kinfo_proc *p1; register struct kinfo_proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *(struct kinfo_proc **) pp1; p2 = *(struct kinfo_proc **) pp2; ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}#ifdef ORDER/* compare routines */int compare_size(), compare_res(), compare_time(), compare_prio();int (*proc_compares[])() = { compare_cpu, compare_size, compare_res, compare_time, compare_prio, NULL};/* compare_size - the comparison function for sorting by total memory usage */intcompare_size(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct kinfo_proc *p1; register struct kinfo_proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *(struct kinfo_proc **) pp1; p2 = *(struct kinfo_proc **) 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 */intcompare_res(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct kinfo_proc *p1; register struct kinfo_proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *(struct kinfo_proc **) pp1; p2 = *(struct kinfo_proc **) 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 */intcompare_time(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct kinfo_proc *p1; register struct kinfo_proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *(struct kinfo_proc **) pp1; p2 = *(struct kinfo_proc **) pp2; ORDERKEY_CPTICKS ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result); } /* compare_prio - the comparison function for sorting by cpu percentage */intcompare_prio(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct kinfo_proc *p1; register struct kinfo_proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *(struct kinfo_proc **) pp1; p2 = *(struct kinfo_proc **) pp2; ORDERKEY_PRIO ORDERKEY_CPTICKS ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}#endif/* * 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 kinfo_proc **prefp; register struct kinfo_proc *pp; prefp = pref; cnt = pref_len; while (--cnt >= 0) { pp = *prefp++; if (PP(pp, p_pid) == (pid_t)pid) { return((int)EP(pp, e_pcred.p_ruid)); } } return(-1);}/* * swapmode is based on a program called swapinfo written * by Kevin Lahey <kml@rokkaku.atl.ga.us>. */#define SVAR(var) __STRING(var) /* to force expansion */#define KGET(idx, var) \ KGET1(idx, &var, sizeof(var), SVAR(var))#define KGET1(idx, p, s, msg) \ KGET2(nlst[idx].n_value, p, s, msg)#define KGET2(addr, p, s, msg) \ if (kvm_read(kd, (u_long)(addr), p, s) != s) { \ warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \ return (0); \ }#define KGETRET(addr, p, s, msg) \ if (kvm_read(kd, (u_long)(addr), p, s) != s) { \ warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \ return (0); \ }intswapmode(retavail, retfree) int *retavail; int *retfree;{ int n; int pagesize = getpagesize(); struct kvm_swap swapary[1]; *retavail = 0; *retfree = 0;#define CONVERT(v) ((quad_t)(v) * pagesize / 1024) n = kvm_getswapinfo(kd, swapary, 1, 0); if (n < 0 || swapary[0].ksw_total == 0) return(0); *retavail = CONVERT(swapary[0].ksw_total); *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used); n = (int)((double)swapary[0].ksw_used * 100.0 / (double)swapary[0].ksw_total); return(n);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -