📄 top.c
字号:
break; case 'A': // supposed to be start_time c = 0; // for scoreboard rc->win[0].sortindx = P_PID; break; case 'T': c = 0; // for scoreboard rc->win[0].sortindx = P_TM2; break; case 'N': c = 0; // for scoreboard rc->win[0].sortindx = P_PID; break; default: // just ignore it, except for the scoreboard of course break; } if (scoreboard[c]) return -16; // duplicates not allowed scoreboard[c] = 1; } return 17;}static void rc_write_new (FILE *fp) { int i; fprintf(fp, RCF_EYECATCHER "\"%s with windows\"\t\t# shameless braggin'\n", Myname ); fprintf(fp, RCF_DEPRECATED "Mode_altscr=%d, Mode_irixps=%d, Delay_time=%.3f, Curwin=%u\n", Rc.mode_altscr, Rc.mode_irixps, Rc.delay_time, (unsigned)(Curwin - Winstk) ); for (i = 0; i < GROUPSMAX; i++) { char buf[40]; char *cp = Winstk[i].rc.fieldscur; int j = 0; while (j < 36) { int c = *cp++ & 0xff; switch (c) { case '.': case 1 ... ' ': case 0x7f ... 0xff: continue; // throw away junk (some of it) default: buf[j++] = c; // gets the '\0' too } if (!c) break; } fprintf(fp, "%s\tfieldscur=%s\n", Winstk[i].rc.winname, buf ); fprintf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n", Winstk[i].rc.winflags, Winstk[i].rc.sortindx, Winstk[i].rc.maxtasks ); fprintf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n", Winstk[i].rc.summclr, Winstk[i].rc.msgsclr, Winstk[i].rc.headclr, Winstk[i].rc.taskclr ); }}static const char *rc_write_whatever (void) { FILE *fp = fopen(Rc_name, "w"); if (!fp) return strerror(errno); rc_write_new(fp); fclose(fp); return NULL;}/*###### Startup routines ##############################################*/// No mater what *they* say, we handle the really really BIG and// IMPORTANT stuff upon which all those lessor functions depend!static void before (char *me){ int i; /* setup our program name -- big! */ Myname = strrchr(me, '/'); if (Myname) ++Myname; else Myname = me; /* establish cpu particulars -- even bigger! */ Cpu_tot = smp_num_cpus; if (linux_version_code > LINUX_VERSION(2, 5, 41)) States_fmts = STATES_line2x5; if (linux_version_code >= LINUX_VERSION(2, 6, 0)) // grrr... only some 2.6.0-testX :-( States_fmts = STATES_line2x6; if (linux_version_code >= LINUX_VERSION(2, 6, 11)) States_fmts = STATES_line2x7; /* get virtual page size -- nearing huge! */ Page_size = getpagesize(); i = Page_size; while(i>1024){ i >>= 1; page_to_kb_shift++; } pcpu_max_value = 99.9; Fieldstab[P_CPN].head = " P"; Fieldstab[P_CPN].fmts = " %1u"; if(smp_num_cpus>9){ Fieldstab[P_CPN].head = " P"; Fieldstab[P_CPN].fmts = " %2u"; } if(smp_num_cpus>99){ Fieldstab[P_CPN].head = " P"; Fieldstab[P_CPN].fmts = " %3u"; } if(smp_num_cpus>999){ Fieldstab[P_CPN].head = " P"; Fieldstab[P_CPN].fmts = " %4u"; } { static char pid_fmt[6]; unsigned pid_digits = get_pid_digits(); if(pid_digits<4) pid_digits=4; snprintf(pid_fmt, sizeof pid_fmt, " %%%uu", pid_digits); Fieldstab[P_PID].fmts = pid_fmt; Fieldstab[P_PID].head = " PID" + 10 - pid_digits; Fieldstab[P_PPD].fmts = pid_fmt; Fieldstab[P_PPD].head = " PPID" + 10 - pid_digits; }}// Config file read *helper* function.// Anything missing won't show as a choice in the field editor,// so make sure there is exactly one of each letter.//// Due to Rik blindly accepting damem's broken patches, procps-2.0.1x// has 3 ("three"!!!) instances of "#C", "LC", or "CPU". Fix that too.static void confighlp (char *fields) { unsigned upper[PFLAGSSIZ]; unsigned lower[PFLAGSSIZ]; char c; char *cp; memset(upper, '\0', sizeof upper); memset(lower, '\0', sizeof lower); cp = fields; for (;;) { c = *cp++; if (!c) break; if(isupper(c)) upper[c&0x1f]++; else lower[c&0x1f]++; } c = 'a'; while (c <= 'z') { if (upper[c&0x1f] && lower[c&0x1f]) { lower[c&0x1f] = 0; // got both, so wipe out unseen column for (;;) { cp = strchr(fields, c); if (cp) memmove(cp, cp+1, strlen(cp)); else break; } } while (lower[c&0x1f] > 1) { // got too many a..z lower[c&0x1f]--; cp = strchr(fields, c); memmove(cp, cp+1, strlen(cp)); } while (upper[c&0x1f] > 1) { // got too many A..Z upper[c&0x1f]--; cp = strchr(fields, toupper(c)); memmove(cp, cp+1, strlen(cp)); } if (!upper[c&0x1f] && !lower[c&0x1f]) { // both missing lower[c&0x1f]++; memmove(fields+1, fields, strlen(fields)+1); fields[0] = c; } c++; }}// First attempt to read the /etc/rcfile which contains two lines// consisting of the secure mode switch and an update interval.// It's presence limits what ordinary users are allowed to do.// (it's actually an old-style config file)//// Then build the local rcfile name and try to read a crufty old-top// rcfile (whew, odoriferous), which may contain an embedded new-style// rcfile. Whether embedded or standalone, new-style rcfile values// will always override that crufty stuff!// note: If running in secure mode via the /etc/rcfile,// Delay_time will be ignored except for root.static void configs_read (void){ const RCF_t def_rcf = DEF_RCFILE; char fbuf[MEDBUFSIZ]; int i, fd; RCF_t rcf; float delay = Rc.delay_time; // read part of an old-style config in /etc/toprc fd = open(SYS_RCFILESPEC, O_RDONLY); if (fd > 0) { ssize_t num; num = read(fd, fbuf, sizeof(fbuf) - 1); if (num > 0) { const char *sec = strchr(fbuf, 's'); const char *eol = strchr(fbuf, '\n'); if (eol) { const char *two = eol + 1; // line two if (sec < eol) Secure_mode = !!sec; eol = strchr(two, '\n'); if (eol && eol > two && isdigit(*two)) Rc.delay_time = atof(two); } } close(fd); } if (getenv("TOPRC")) { // should switch on Myname before documenting this? // not the most optimal here... snprintf(Rc_name, sizeof(Rc_name), "%s", getenv("TOPRC")); } else { snprintf(Rc_name, sizeof(Rc_name), ".%src", Myname); // eeew... if (getenv("HOME")) snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", getenv("HOME"), Myname); } rcf = def_rcf; fd = open(Rc_name, O_RDONLY); if (fd > 0) { ssize_t num; num = read(fd, fbuf+2, sizeof(fbuf) -3); if (num > 0) { fbuf[0] = '\n'; fbuf[1] = '\n'; fbuf[num+2] = '\0';//fprintf(stderr,"rc_read_old returns %d\n",rc_read_old(fbuf, &rcf));//sleep(2); if (rc_read_new(fbuf, &rcf) < 0) { rcf = def_rcf; // on failure, maybe mangled if (rc_read_old(fbuf, &rcf) < 0) rcf = def_rcf; } delay = rcf.delay_time; } close(fd); } // update Rc defaults, establish a Curwin and fix up the window stack Rc.mode_altscr = rcf.mode_altscr; Rc.mode_irixps = rcf.mode_irixps; if (rcf.win_index >= GROUPSMAX) rcf.win_index = 0; Curwin = &Winstk[rcf.win_index]; for (i = 0; i < GROUPSMAX; i++) { memcpy(&Winstk[i].rc, &rcf.win[i], sizeof rcf.win[i]); confighlp(Winstk[i].rc.fieldscur); } if(Rc.mode_irixps && smp_num_cpus>1){ // good for 100 CPUs per process pcpu_max_value = 9999.0; Fieldstab[P_CPU].fmts = " %4.0f"; } // lastly, establish the true runtime secure mode and delay time if (!getuid()) Secure_mode = 0; if (!Secure_mode) Rc.delay_time = delay;}// Parse command line arguments.// Note: it's assumed that the rc file(s) have already been read// and our job is to see if any of those options are to be// overridden -- we'll force some on and negate others in our// best effort to honor the loser's (oops, user's) wishes...static void parse_args (char **args){ /* differences between us and the former top: -C (separate CPU states for SMP) is left to an rcfile -p (pid monitoring) allows a comma delimited list -q (zero delay) eliminated as redundant, incomplete and inappropriate use: "nice -n-10 top -d0" to achieve what was only claimed -c,i,S act as toggles (not 'on' switches) for enhanced user flexibility . no deprecated/illegal use of 'breakargv:' with goto . bunched args are actually handled properly and none are ignored . we tolerate NO whitespace and NO switches -- maybe too tolerant? */ static const char usage[] = " -hv | -bcisSH -d delay -n iterations [-u user | -U user] -p pid [,pid ...]"; float tmp_delay = MAXFLOAT; char *p; while (*args) { const char *cp = *(args++); while (*cp) { switch (*cp) { case '\0': case '-': break; case 'b': Batch = 1; break; case 'c': TOGw(Curwin, Show_CMDLIN); break; case 'd': if (cp[1]) ++cp; else if (*args) cp = *args++; else std_err("-d requires argument"); /* a negative delay will be dealt with shortly... */ if (sscanf(cp, "%f", &tmp_delay) != 1) std_err(fmtmk("bad delay '%s'", cp)); break; case 'H': TOGw(Curwin, Show_THREADS); break; case 'h': case 'v': case 'V': std_out(fmtmk("%s\nusage:\t%s%s", procps_version, Myname, usage)); case 'i': TOGw(Curwin, Show_IDLEPS); Curwin->rc.maxtasks = 0; break; case 'n': if (cp[1]) cp++; else if (*args) cp = *args++; else std_err("-n requires argument"); if (sscanf(cp, "%d", &Loops) != 1 || Loops < 1) std_err(fmtmk("bad iterations arg '%s'", cp)); break; case 'p': do { if (selection_type && selection_type != 'p') std_err("conflicting process selection"); selection_type = 'p'; if (cp[1]) cp++; else if (*args) cp = *args++; else std_err("-p argument missing"); if (Monpidsidx >= MONPIDMAX) std_err(fmtmk("pid limit (%d) exceeded", MONPIDMAX)); if (sscanf(cp, "%d", &Monpids[Monpidsidx]) != 1 || Monpids[Monpidsidx] < 0) std_err(fmtmk("bad pid '%s'", cp)); if (!Monpids[Monpidsidx]) Monpids[Monpidsidx] = getpid(); Monpidsidx++; if (!(p = strchr(cp, ','))) break; cp = p; } while (*cp); break; case 's': Secure_mode = 1; break; case 'S': TOGw(Curwin, Show_CTIMES); break; case 'u': do { const char *errmsg; if (selection_type /* && selection_type != 'u' */) std_err("conflicting process selection"); if (cp[1]) cp++; else if (*args) cp = *args++; else std_err("-u missing name"); errmsg = parse_uid(cp, &selection_uid); if (errmsg) std_err(errmsg); selection_type = 'u'; cp += snprintf(Curwin->colusrnam, USRNAMSIZ-1, "%s", cp); // FIXME: junk } while(0); break; case 'U': do { const char *errmsg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -