📄 top.c
字号:
fprintf(fp, "\n\tProgram" "\n\t Linux version = %u.%u.%u, %s" "\n\t Hertz = %u (%u bytes, %u-bit time)" "\n\t Page_size = %d, Cpu_tot = %d, sizeof(proc_t) = %u" "\n\t sizeof(CPU_t) = %u, sizeof(HST_t) = %u (%u HST_t's/Page)" "\n" , LINUX_VERSION_MAJOR(linux_version_code) , LINUX_VERSION_MINOR(linux_version_code) , LINUX_VERSION_PATCH(linux_version_code) , procps_version , (unsigned)Hertz, sizeof(Hertz), sizeof(Hertz) * 8 , Page_size, Cpu_tot, sizeof(proc_t) , sizeof(CPU_t), sizeof(HST_t), Page_size / sizeof(HST_t) );#endif if (str) fputs(str, fp); exit(eno);} /* * Normal end of execution. * catches: * SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT and SIGTERM */static void end_pgm (int dont_care_sig) NORETURN;static void end_pgm (int dont_care_sig){ (void)dont_care_sig; bye_bye(stdout, 1, NULL);} /* * Standard error handler to normalize the look of all err o/p */static void std_err (const char *str) NORETURN;static void std_err (const char *str){ static char buf[SMLBUFSIZ]; fflush(stdout); /* we'll use our own buffer so callers can still use fmtmk() and, yes the leading tab is not the standard convention, but the standard is wrong -- OUR msg won't get lost in screen clutter, like so many others! */ snprintf(buf, sizeof(buf), "\t%s: %s\n", Myname, str); if (!Ttychanged) { fprintf(stderr, "%s\n", buf); exit(1); } /* not to worry, he'll change our exit code to 1 due to 'buf' */ bye_bye(stderr, 1, buf);} /* * Standard out handler */static void std_out (const char *str) NORETURN;static void std_out (const char *str){ static char buf[SMLBUFSIZ]; fflush(stdout); /* we'll use our own buffer so callers can still use fmtmk() and, yes the leading tab is not the standard convention, but the standard is wrong -- OUR msg won't get lost in screen clutter, like so many others! */ snprintf(buf, sizeof(buf), "\t%s: %s\n", Myname, str); if (!Ttychanged) { fprintf(stdout, "%s\n", buf); exit(0); } bye_bye(stdout, 0, buf);} /* * Suspend ourself. * catches: * SIGTSTP, SIGTTIN and SIGTTOU */static void suspend (int dont_care_sig){ (void)dont_care_sig; /* reset terminal */ tcsetattr(STDIN_FILENO, TCSAFLUSH, &Savedtty); putp(tg2(0, Screen_rows)); putp(Cap_curs_norm); putp(Cap_smam); putp("\n"); fflush(stdout); raise(SIGSTOP); /* later, after SIGCONT... */ ZAP_TIMEOUT if (!Batch) tcsetattr(STDIN_FILENO, TCSAFLUSH, &Rawtty); putp(Cap_clr_scr); putp(Cap_rmam);}/*###### Misc Color/Display support ####################################*/ /* macro to test if a basic (non-color) capability is valid thanks: Floyd Davidson <floyd@ptialaska.net> */#define tIF(s) s ? s : ""#define CAPCOPY(dst,src) src && strcpy(dst,src) /* * Make the appropriate caps/color strings and set some * lengths which are used to distinguish twix the displayed * columns and an actual printed row! * note: we avoid the use of background color so as to maximize * compatibility with the user's xterm settings */static void capsmk (WIN_t *q){ static int capsdone = 0; // we must NOT disturb our 'empty' terminfo strings! if (Batch) return; // these are the unchangeable puppies, so we only do 'em once if (!capsdone) { CAPCOPY(Cap_clr_eol, clr_eol); CAPCOPY(Cap_clr_eos, clr_eos); CAPCOPY(Cap_clr_scr, clear_screen); if (!eat_newline_glitch) { // we like the eat_newline_glitch CAPCOPY(Cap_rmam, exit_am_mode); CAPCOPY(Cap_smam, enter_am_mode); if (!*Cap_rmam || !*Cap_smam) { // need both *Cap_rmam = '\0'; *Cap_smam = '\0'; if (auto_right_margin) { avoid_last_column = 1; } } } CAPCOPY(Cap_curs_huge, cursor_visible); CAPCOPY(Cap_curs_norm, cursor_normal); CAPCOPY(Cap_home, cursor_home); CAPCOPY(Cap_norm, exit_attribute_mode); CAPCOPY(Cap_reverse, enter_reverse_mode); snprintf(Caps_off, sizeof(Caps_off), "%s%s", Cap_norm, tIF(orig_pair)); if (tgoto(cursor_address, 1, 1)) Cap_can_goto = 1; capsdone = 1; } /* the key to NO run-time costs for configurable colors -- we spend a little time with the user now setting up our terminfo strings, and the job's done until he/she/it has a change-of-heart */ strcpy(q->cap_bold, CHKw(q, View_NOBOLD) ? Cap_norm : tIF(enter_bold_mode)); if (CHKw(q, Show_COLORS) && max_colors > 0) { strcpy(q->capclr_sum, tparm(set_a_foreground, q->rc.summclr)); snprintf(q->capclr_msg, sizeof(q->capclr_msg), "%s%s" , tparm(set_a_foreground, q->rc.msgsclr), Cap_reverse); snprintf(q->capclr_pmt, sizeof(q->capclr_pmt), "%s%s" , tparm(set_a_foreground, q->rc.msgsclr), q->cap_bold); snprintf(q->capclr_hdr, sizeof(q->capclr_hdr), "%s%s" , tparm(set_a_foreground, q->rc.headclr), Cap_reverse); snprintf(q->capclr_rownorm, sizeof(q->capclr_rownorm), "%s%s" , Caps_off, tparm(set_a_foreground, q->rc.taskclr)); } else { q->capclr_sum[0] = '\0'; strcpy(q->capclr_msg, Cap_reverse); strcpy(q->capclr_pmt, q->cap_bold); strcpy(q->capclr_hdr, Cap_reverse); strcpy(q->capclr_rownorm, Cap_norm); } // composite(s), so we do 'em outside and after the if snprintf(q->capclr_rowhigh, sizeof(q->capclr_rowhigh), "%s%s" , q->capclr_rownorm, CHKw(q, Show_HIBOLD) ? q->cap_bold : Cap_reverse); q->len_rownorm = strlen(q->capclr_rownorm); q->len_rowhigh = strlen(q->capclr_rowhigh);#undef tIF}// Show an error, but not right now.// Due to the postponed opening of ksym, using open_psdb_message,// if P_WCH had been selected and the program is restarted, the// message would otherwise be displayed prematurely.static void msg_save (const char *fmts, ...) __attribute__((format(printf,1,2)));static void msg_save (const char *fmts, ...){ char tmp[SMLBUFSIZ]; va_list va; va_start(va, fmts); vsnprintf(tmp, sizeof(tmp), fmts, va); va_end(va); /* we'll add some extra attention grabbers to whatever this is */ snprintf(Msg_delayed, sizeof(Msg_delayed), "\a*** %s ***", strim_0(tmp)); Msg_awaiting = 1;} /* * Show an error message (caller may include a '\a' for sound) */static void show_msg (const char *str){ PUTT("%s%s %s %s%s", tg2(0, Msg_row), Curwin->capclr_msg, str, Caps_off, Cap_clr_eol ); fflush(stdout); sleep(MSG_SLEEP); Msg_awaiting = 0;} /* * Show an input prompt + larger cursor */static void show_pmt (const char *str){ PUTT("%s%s%s: %s%s", tg2(0, Msg_row), Curwin->capclr_pmt, str, Cap_curs_huge, Caps_off ); fflush(stdout);} /* * Show lines with specially formatted elements, but only output * what will fit within the current screen width. * Our special formatting consists of: * "some text <_delimiter_> some more text <_delimiter_>...\n" * Where <_delimiter_> is a single byte in the range of: * \01 through \10 (in decimalizee, 1 - 8) * and is used to select an 'attribute' from a capabilities table * which is then applied to the *preceding* substring. * Once recognized, the delimiter is replaced with a null character * and viola, we've got a substring ready to output! Strings or * substrings without delimiters will receive the Cap_norm attribute. * * Caution: * This routine treats all non-delimiter bytes as displayable * data subject to our screen width marching orders. If callers * embed non-display data like tabs or terminfo strings in our * glob, a line will truncate incorrectly at best. Worse case * would be truncation of an embedded tty escape sequence. * * Tabs must always be avoided or our efforts are wasted and * lines will wrap. To lessen but not eliminate the risk of * terminfo string truncation, such non-display stuff should * be placed at the beginning of a "short" line. * (and as for tabs, gimme 1 more color then no worries, mate) */static void show_special (int interact, const char *glob){ /* note: the following is for documentation only, the real captab is now found in a group's WIN_t ! +------------------------------------------------------+ | char *captab[] = { : Cap's/Delim's | | Cap_norm, Cap_norm, Cap_bold, = \00, \01, \02 | | Sum_color, = \03 | | Msg_color, Pmt_color, = \04, \05 | | Hdr_color, = \06 | | Row_color_high, = \07 | | Row_color_norm }; = \10 [octal!] | +------------------------------------------------------+ */ char lin[BIGBUFSIZ], row[ROWBUFSIZ], tmp[ROWBUFSIZ]; char *rp, *cap, *lin_end, *sub_beg, *sub_end; int room; /* handle multiple lines passed in a bunch */ while ((lin_end = strchr(glob, '\n'))) { /* create a local copy we can extend and otherwise abuse */ memcpy(lin, glob, (unsigned)(lin_end - glob)); /* zero terminate this part and prepare to parse substrings */ lin[lin_end - glob] = '\0'; room = Screen_cols; sub_beg = sub_end = lin; *(rp = row) = '\0'; while (*sub_beg) { switch (*sub_end) { case 0: /* no end delim, captab makes normal */ *(sub_end + 1) = '\0'; /* extend str end, then fall through */ case 1 ... 8: cap = Curwin->captab[(int)*sub_end]; *sub_end = '\0'; snprintf(tmp, sizeof(tmp), "%s%.*s%s", cap, room, sub_beg, Caps_off); rp = scat(rp, tmp); room -= (sub_end - sub_beg); sub_beg = ++sub_end; break; default: /* nothin' special, just text */ ++sub_end; } if (unlikely(0 >= room)) break; /* skip substrings that won't fit */ } if (interact) PUTT("%s%s\n", row, Cap_clr_eol); else PUFF("%s%s\n", row, Cap_clr_eol); glob = ++lin_end; /* point to next line (maybe) */ } /* end: while 'lines' */ /* If there's anything left in the glob (by virtue of no trailing '\n'), it probably means caller wants to retain cursor position on this final line. That, in turn, means we're interactive and so we'll just do our 'fit-to-screen' thingy... */ if (*glob) PUTT("%.*s", Screen_cols, glob);}/*###### Small Utility routines ########################################*/// Get a string from the userstatic char *ask4str (const char *prompt){ static char buf[GETBUFSIZ]; show_pmt(prompt); memset(buf, '\0', sizeof(buf)); chin(1, buf, sizeof(buf) - 1); putp(Cap_curs_norm); return strim_0(buf);}// Get a float from the userstatic float get_float (const char *prompt){ char *line; float f; if (!(*(line = ask4str(prompt)))) return -1; // note: we're not allowing negative floats if (strcspn(line, ",.1234567890")) { show_msg("\aNot valid"); return -1; } sscanf(line, "%f", &f); return f;}// Get an integer from the userstatic int get_int (const char *prompt){ char *line; int n; if (!(*(line = ask4str(prompt)))) return -1; // note: we've got to allow negative ints (renice) if (strcspn(line, "-1234567890")) { show_msg("\aNot valid"); return -1; } sscanf(line, "%d", &n); return n;} /* * Do some scaling stuff. * We'll interpret 'num' as one of the following types and * try to format it to fit 'width'. * SK_no (0) it's a byte count * SK_Kb (1) it's kilobytes * SK_Mb (2) it's megabytes * SK_Gb (3) it's gigabytes * SK_Tb (4) it's terabytes */static const char *scale_num (unsigned long num, const int width, const unsigned type){ /* kilobytes, megabytes, gigabytes, terabytes, duh! */ static double scale[] = { 1024.0, 1024.0*1024, 1024.0*1024*1024, 1024.0*1024*1024*1024, 0 }; /* kilo, mega, giga, tera, none */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -