📄 top.c
字号:
table[curmax]->cmdline = NULL; } if (!(ttsk = readtask(PT, ptsk, table[curmax]))) break; prochlp(ttsk); ++curmax; } free(ptsk); // readproc() proc_t not used } } // ii) Unallocated Chunks: *New* or *Existing* table; extend + fill if (!(CHKw(Curwin, Show_THREADS))) { while (ptsk) { // realloc as we go, keeping 'table' ahead of 'currmax++' table = alloc_r(table, (curmax + 1) * PTRsz); // here, readproc will allocate the underlying proc_t stg if (likely(ptsk = readproc(PT, NULL))) { prochlp(ptsk); // tally & complete this proc_t table[curmax++] = ptsk; } } } else { // show each thread in a process separately while (ptsk) { proc_t *ttsk; if (likely(ptsk = readproc(PT, NULL))) { show_threads_was_enabled = 1; while (1) { table = alloc_r(table, (curmax + 1) * PTRsz); if (!(ttsk = readtask(PT, ptsk, NULL))) break; prochlp(ttsk); table[curmax++] = ttsk; } free(ptsk); // readproc() proc_t not used } } } closeproc(PT); // iii) Chunkless: make 'eot' entry, after ensuring proc_t exists if (curmax >= savmax) { table = alloc_r(table, (curmax + 1) * PTRsz); // here, we must allocate the underlying proc_t stg ourselves table[curmax] = alloc_c(ENTsz); savmax = curmax + 1; } // this frame's end, but not necessarily end of allocated space table[curmax]->tid = -1; return table;#undef PTRsz#undef ENTsz}/*###### Field Table/RCfile compatability support ######################*/// from either 'stat' or 'status' (preferred), via bits not otherwise used#define L_EITHER PROC_SPARE_1// These are the Fieldstab.lflg values used here and in reframewins.// (own identifiers as documentation and protection against changes)#define L_stat PROC_FILLSTAT#define L_statm PROC_FILLMEM#define L_status PROC_FILLSTATUS#define L_CMDLINE L_EITHER | PROC_FILLARG#define L_EUSER PROC_FILLUSR#define L_RUSER L_status | PROC_FILLUSR#define L_GROUP L_status | PROC_FILLGRP#define L_NONE 0// for reframewins and summary_show 1st pass#define L_DEFAULT PROC_FILLSTAT// a temporary macro, soon to be undef'd...#define SF(f) (QFP_t)sort_P_ ## f /* These are our gosh darn 'Fields' ! They MUST be kept in sync with pflags !! note: for integer data, the length modifiers found in .fmts may NOT reflect the true field type found in proc_t -- this plus a cast when/if displayed provides minimal width protection. */static FLD_t Fieldstab[] = {/* .lflg anomolies: P_UID, L_NONE - natural outgrowth of 'stat()' in readproc (euid) P_CPU, L_stat - never filled by libproc, but requires times (pcpu) P_CMD, L_stat - may yet require L_CMDLINE in reframewins (cmd/cmdline) L_EITHER - must L_status, else 64-bit math, __udivdi3 on 32-bit ! keys head fmts width scale sort desc lflg ------ ----------- ------- ------ ----- ----- ---------------------- -------- */ { "AaAa", " PID", " %5u", -1, -1, SF(PID), "Process Id", L_NONE }, { "BbBb", " PPID", " %5u", -1, -1, SF(PPD), "Parent Process Pid", L_EITHER }, { "CcQq", " RUSER ", " %-8.8s", -1, -1, SF(URR), "Real user name", L_RUSER }, { "DdCc", " UID", " %4u", -1, -1, SF(UID), "User Id", L_NONE }, { "EeDd", " USER ", " %-8.8s", -1, -1, SF(URE), "User Name", L_EUSER }, { "FfNn", " GROUP ", " %-8.8s", -1, -1, SF(GRP), "Group Name", L_GROUP }, { "GgGg", " TTY ", " %-8.8s", 8, -1, SF(TTY), "Controlling Tty", L_stat }, { "HhHh", " PR", " %3d", -1, -1, SF(PRI), "Priority", L_stat }, { "IiIi", " NI", " %3d", -1, -1, SF(NCE), "Nice value", L_stat }, { "JjYy", " #C", " %2u", -1, -1, SF(CPN), "Last used cpu (SMP)", L_stat }, { "KkEe", " %CPU", " %#4.1f", -1, -1, SF(CPU), "CPU usage", L_stat }, { "LlWw", " TIME", " %6.6s", 6, -1, SF(TME), "CPU Time", L_stat }, { "MmRr", " TIME+ ", " %9.9s", 9, -1, SF(TME), "CPU Time, hundredths", L_stat }, { "NnFf", " %MEM", " %#4.1f", -1, -1, SF(RES), "Memory usage (RES)", L_statm }, { "OoMm", " VIRT", " %5.5s", 5, SK_Kb, SF(VRT), "Virtual Image (kb)", L_statm }, { "PpOo", " SWAP", " %4.4s", 4, SK_Kb, SF(SWP), "Swapped size (kb)", L_statm }, { "QqTt", " RES", " %4.4s", 4, SK_Kb, SF(RES), "Resident size (kb)", L_statm }, { "RrKk", " CODE", " %4.4s", 4, SK_Kb, SF(COD), "Code size (kb)", L_statm }, { "SsLl", " DATA", " %4.4s", 4, SK_Kb, SF(DAT), "Data+Stack size (kb)", L_statm }, { "TtPp", " SHR", " %4.4s", 4, SK_Kb, SF(SHR), "Shared Mem size (kb)", L_statm }, { "UuJj", " nFLT", " %4.4s", 4, SK_no, SF(FLT), "Page Fault count", L_stat }, { "VvSs", " nDRT", " %4.4s", 4, SK_no, SF(DRT), "Dirty Pages count", L_statm }, { "WwVv", " S", " %c", -1, -1, SF(STA), "Process Status", L_EITHER }, // next entry's special: '.head' will be formatted using table entry's own // '.fmts' plus runtime supplied conversion args! { "XxXx", " COMMAND", " %-*.*s", -1, -1, SF(CMD), "Command name/line", L_EITHER }, { "YyUu", " WCHAN ", " %-9.9s", -1, -1, SF(WCH), "Sleeping in Function", L_stat }, // next entry's special: the 0's will be replaced with '.'! { "ZzZz", " Flags ", " %08lx", -1, -1, SF(FLG), "Task Flags <sched.h>", L_stat },#if 0 { "..Qq", " A", " %4.4s", 4, SK_no, SF(PID), "Accessed Page count", L_stat }, { "..Nn", " TRS", " %4.4s", 4, SK_Kb, SF(PID), "Code in memory (kb)", L_stat }, { "..Rr", " WP", " %4.4s", 4, SK_no, SF(PID), "Unwritable Pages", L_stat }, { "Jj[{", " #C", " %2u", -1, -1, SF(CPN), "Last used cpu (SMP)", L_stat }, { "..\\|"," Bad", " %2u", -1, -1, SF(CPN), "-- must ignore | --", 0 }, { "..]}", " Bad", " %2u", -1, -1, SF(CPN), "-- not used --", 0 }, { "..^~", " Bad", " %2u", -1, -1, SF(CPN), "-- not used --", 0 },#endif};#undef SF /* All right, those-that-follow -- Listen Up! * For the above table keys and the following present/future rc file * compatibility support, you have Mr. Albert D. Cahalan to thank. * He must have been in a 'Christmas spirit'. Were it left to me, * this top would never have gotten that close to the former top's * crufty rcfile. Not only is it illogical, it's odoriferous ! */ // used as 'to' and/or 'from' args in the ft_xxx utilities...#define FT_NEW_fmt 0#define FT_OLD_fmt 2#if 0 // convert, or 0 for failurestatic int ft_cvt_char (const int fr, const int to, int c) { int j = -1; while (++j < MAXTBL(Fieldstab)) { if (c == Fieldstab[j].keys[fr]) return Fieldstab[j].keys[to]; if (c == Fieldstab[j].keys[fr+1]) return Fieldstab[j].keys[to+1]; } return 0;}#endif // convertstatic inline int ft_get_char (const int fr, int i) { int c; if (i < 0) return 0; if (i >= MAXTBL(Fieldstab)) return 0; c = Fieldstab[i].keys[fr]; if (c == '.') c = 0; // '.' marks a bad entry return c;}#if 0 // convert, or -1 for failurestatic int ft_get_idx (const int fr, int c) { int j = -1; while (++j < MAXTBL(Fieldstab)) { if (c == Fieldstab[j].keys[fr]) return j; if (c == Fieldstab[j].keys[fr+1]) return j; } return -1;}#endif // convert, or NULL for failurestatic const FLD_t *ft_get_ptr (const int fr, int c) { int j = -1; while (++j < MAXTBL(Fieldstab)) { if (c == Fieldstab[j].keys[fr]) return Fieldstab+j; if (c == Fieldstab[j].keys[fr+1]) return Fieldstab+j; } return NULL;}#if 0 // convert, or NULL for failurestatic const FLD_t *ft_idx_to_ptr (const int i) { if (i < 0) return NULL; if (i >= MAXTBL(Fieldstab)) return NULL; return Fieldstab + i;} // convert, or -1 for failurestatic int ft_ptr_to_idx (const FLD_t *p) { int i; if (p < Fieldstab) return -1; i = p - Fieldstab; if (i >= MAXTBL(Fieldstab)) return -1; return i;}#endif#if 0static void rc_bugless (const RCF_t *const rc) { const RCW_t *w; int i = 0; fprintf(stderr,"\n%d %d %f %d\n", rc->mode_altscr, rc->mode_irixps, rc->delay_time, rc->win_index ); while(i < 4) { w = &rc->win[i++]; fprintf(stderr, "<%s> <%s> %d %08x %d %d %d %d %d\n", w->winname, w->fieldscur, w->sortindx, w->winflags, w->maxtasks, w->summclr, w->msgsclr, w->headclr, w->taskclr ); }}#endif// '$HOME/Rc_name' contains multiple lines - 2 global + 3 per window.// line 1: an eyecatcher, with a shameless advertisement// line 2: an id, Mode_altcsr, Mode_irixps, Delay_time and Curwin.// For each of the 4 windows:// line a: contains winname, fieldscur// line b: contains winflags, sortindx, maxtasks// line c: contains summclr, msgsclr, headclr, taskclr// line d: if present, would crash procps-3.1.1static int rc_read_new (const char *const buf, RCF_t *rc) { int i; int cnt; const char *cp; cp = strstr(buf, "\n\n" RCF_EYECATCHER); if (!cp) return -1; cp = strchr(cp + 2, '\n'); if (!cp++) return -2; cnt = sscanf(cp, "Id:a, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%f, Curwin=%d\n", &rc->mode_altscr, &rc->mode_irixps, &rc->delay_time, &rc->win_index ); if (cnt != 4) return -3; cp = strchr(cp, '\n'); if (!cp++) return -4; for (i = 0; i < GROUPSMAX; i++) { RCW_t *ptr = &rc->win[i]; cnt = sscanf(cp, "%3s\tfieldscur=%31s\n", ptr->winname, ptr->fieldscur); if (cnt != 2) return 5+100*i; // OK to have less than 4 windows if (WINNAMSIZ <= strlen(ptr->winname)) return -6; if (strlen(DEF_FIELDS) != strlen(ptr->fieldscur)) return -7; cp = strchr(cp, '\n'); if (!cp++) return -(8+100*i); cnt = sscanf(cp, "\twinflags=%d, sortindx=%u, maxtasks=%d \n", &ptr->winflags, &ptr->sortindx, &ptr->maxtasks ); if (cnt != 3) return -(9+100*i); cp = strchr(cp, '\n'); if (!cp++) return -(10+100*i); cnt = sscanf(cp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d \n", &ptr->summclr, &ptr->msgsclr, &ptr->headclr, &ptr->taskclr ); if (cnt != 4) return -(11+100*i); cp = strchr(cp, '\n'); if (!cp++) return -(12+100*i); while (*cp == '\t') { // skip unknown per-window settings cp = strchr(cp, '\n'); if (!cp++) return -(13+100*i); } } return 13;}static int rc_read_old (const char *const buf, RCF_t *rc) { const char std[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzJj......"; const char old[] = "AaBb..CcDd..GgHhIiYyEeWw..FfMmOoTtKkLlPpJjSsVvXxUuZz[{QqNnRr"; unsigned u; const char *cp; unsigned c_show = 0; int badchar = 0; // allow a limited number of duplicates and junk char scoreboard[256]; memset(scoreboard, '\0', sizeof scoreboard); cp = buf+2; // skip the "\n\n" we stuck at the beginning u = 0; for (;;) { const char *tmp; int c = *cp++; if (u+1 >= sizeof rc->win[0].fieldscur) return -1; if (c == '\0') return -2; if (c == '\n') break; if (c & ~0x7f) return -3; if (~c & 0x20) c_show |= 1 << (c & 0x1f); // 0x20 means lowercase means hidden if (scoreboard[c|0xe0u]) badchar++; // duplicates not allowed scoreboard[c|0xe0u]++; tmp = strchr(old,c); if (!tmp) continue; c = *((tmp-old)+std); if (c == '.') continue; if (scoreboard[c&0x1fu]) badchar++; // duplicates not allowed scoreboard[c&0x1fu]++; rc->win[0].fieldscur[u++] = c; } rc->win[0].fieldscur[u++] = '\0'; if (u < 21) return -6; // catch junk, not good files (had 23 chars in one) if (u > 33) return -7; // catch junk, not good files (had 29 chars in one)// fprintf(stderr, "badchar: %d\n", badchar); sleep(2); if (badchar > 8) return -8; // too much junk if (!c_show) return -9; // nothing was shown // rest of file is optional, but better look right if it exists if (!*cp) return 12; if (*cp < '2' || *cp > '9') return -13; // stupid, and why isn't '1' valid? rc->delay_time = *cp - '0'; memset(scoreboard, '\0', sizeof(scoreboard)); for (;;) { int c = *++cp & 0xffu; // protect scoreboard[] from negative char if (!c) return -14; // not OK to hit EOL w/o '\n' if (c == '\n') break; switch (c) { case ' ': case '.': case '0' ... '9': return -15; // not supposed to have digits here// case 's': // mostly for global rcfile// rc->mode_secure = 1;// break; case 'S': rc->win[0].winflags |= Show_CTIMES; break; case 'c': rc->win[0].winflags |= Show_CMDLIN; break; case 'i': rc->win[0].winflags &= ~Show_IDLEPS; break; case 'H': rc->win[0].winflags |= Show_THREADS; break; case 'm': rc->win[0].winflags &= ~View_MEMORY; break; case 'l': rc->win[0].winflags &= ~View_LOADAV; break; case 't': rc->win[0].winflags &= ~View_STATES; break; case 'I': rc->mode_irixps = 0; break; case 'M': c = 0; // for scoreboard rc->win[0].sortindx = P_MEM; break; case 'P': c = 0; // for scoreboard rc->win[0].sortindx = P_CPU;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -