阅读top命令源码
课设要求实现一个系统监控器,本来打算在mac上实现一个类似activity monitor的程序,但似乎mac系统并没有这么开源。还是linux系统下的/proc文件系统方便。
看了一部分top命令的实现(看了两三个小时头都大了。。。),稍微记录一下,便于未来翻阅。
top.c
首先查看main函数前面的配置部分函数,主要是窗口初始化和对命令对选项解析。
之前以为应该只需要一个窗口,不过代码中初始化了四个窗口,以便于后面的扩展
(没有了解过top命令的用法,但是猜测这里应该是可以通过加参数扩展)
// Set up the raw/incomplete field group windows --
// they'll be finished off after startup completes.
// [ and very likely that will override most/all of our efforts ]
// [ --- life-is-NOT-fair --- ]
static void windows_stage1 (void)
{
WIN_t *w;
int i;
for (i = 0; i < GROUPSMAX; i++) {
w = &Winstk[i];
w->winnum = i + 1;
w->rc = Rc.win[i];
w->captab[0] = Cap_norm;
w->captab[1] = Cap_norm;
w->captab[2] = w->cap_bold;
w->captab[3] = w->capclr_sum;
w->captab[4] = w->capclr_msg;
w->captab[5] = w->capclr_pmt;
w->captab[6] = w->capclr_hdr;
w->captab[7] = w->capclr_rowhigh;
w->captab[8] = w->capclr_rownorm;
w->next = w + 1;
w->prev = w - 1;
++w;
}
/* fixup the circular chains... */
Winstk[3].next = &Winstk[0];
Winstk[0].prev = &Winstk[3];
Curwin = Winstk;
}
看了注释小哥这说话风格有点不确认自己下的是不是官方源码了。。。
再来看下输出格式设计,用结构体的模式有利于未来扩展和复用。
// This structure consolidates the information that's used
// in a variety of display roles.
typedef struct FLD_t {
const char keys [4]; // order: New-on New-off Old-on Old-off
// misaligned on 64-bit, but part of a table -- oh well
const char *head; // name for col heads + toggle/reorder fields
const char *fmts; // sprintf format string for field display
const int width; // field width, if applicable
const int scale; // scale_num type, if applicable
const QFP_t sort; // sort function
const char *desc; // description for toggle/reorder fields
const int lflg; // PROC_FILLxxx flag(s) needed by this field
} FLD_t;
具体在top指令中的实现格式如下,数组组织形式:
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,