⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display.c

📁 Ho Chi Minh City University of Technology Computer Science Department Distributed Computing E
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Top users/processes display for Unix *  Version 3 * *  This program may be freely redistributed, *  but this entire comment MUST remain intact. * *  Copyright (c) 1984, 1989, William LeFebvre, Rice University *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University *//* *  This file contains the routines that display information on the screen. *  Each section of the screen has two routines:  one for initially writing *  all constant and dynamic text, and one for only updating the text that *  changes.  The prefix "i_" is used on all the "initial" routines and the *  prefix "u_" is used for all the "updating" routines. * *  ASSUMPTIONS: *        None of the "i_" routines use any of the termcap capabilities. *        In this way, those routines can be safely used on terminals that *        have minimal (or nonexistant) terminal capabilities. * *        The routines are called in this order:  *_loadave, i_timeofday, *        *_procstates, *_cpustates, *_memory, *_message, *_header, *        *_process, u_endscreen. */#include "os.h"#include <ctype.h>#include <time.h>#include "screen.h"		/* interface to screen package */#include "layout.h"		/* defines for screen position layout */#include "display.h"#include "top.h"#include "top.local.h"#include "boolean.h"#include "machine.h"		/* we should eliminate this!!! */#include "utils.h"#ifdef DEBUGFILE *debug;#endif/* imported from screen.c */extern int overstrike;static int lmpid = 0;static int last_hi = 0;		/* used in u_process and u_endscreen */static int lastline = 0;static int display_width = MAX_COLS;#define lineindex(l) ((l)*display_width)char *printable();/* things initialized by display_init and used thruout *//* buffer of proc information lines for display updating */char *screenbuf = NULL;static char **procstate_names;static char **cpustate_names;static char **memory_names;static int num_procstates;static int num_cpustates;static int num_memory;static int *lprocstates;static int *lcpustates;static int *lmemory;static int *cpustate_columns;static int cpustate_total_length;static enum { OFF, ON, ERASE } header_status = ON;static int string_count();static void summary_format();static void line_update();int display_resize(){    register int lines;    /* first, deallocate any previous buffer that may have been there */    if (screenbuf != NULL)    {	free(screenbuf);    }    /* calculate the current dimensions */    /* if operating in "dumb" mode, we only need one line */    lines = smart_terminal ? screen_length - Header_lines : 1;    /* we don't want more than MAX_COLS columns, since the machine-dependent       modules make static allocations based on MAX_COLS and we don't want       to run off the end of their buffers */    display_width = screen_width;    if (display_width >= MAX_COLS)    {	display_width = MAX_COLS - 1;    }    /* now, allocate space for the screen buffer */    screenbuf = (char *)malloc(lines * display_width);    if (screenbuf == (char *)NULL)    {	/* oops! */	return(-1);    }    /* return number of lines available */    /* for dumb terminals, pretend like we can show any amount */    return(smart_terminal ? lines : Largest);}int display_init(statics)struct statics *statics;{    register int lines;    register char **pp;    register int *ip;    register int i;    /* call resize to do the dirty work */    lines = display_resize();    /* only do the rest if we need to */    if (lines > -1)    {	/* save pointers and allocate space for names */	procstate_names = statics->procstate_names;	num_procstates = string_count(procstate_names);	lprocstates = (int *)malloc(num_procstates * sizeof(int));	cpustate_names = statics->cpustate_names;	num_cpustates = string_count(cpustate_names);	lcpustates = (int *)malloc(num_cpustates * sizeof(int));	cpustate_columns = (int *)malloc(num_cpustates * sizeof(int));	memory_names = statics->memory_names;	num_memory = string_count(memory_names);	lmemory = (int *)malloc(num_memory * sizeof(int));	/* calculate starting columns where needed */	cpustate_total_length = 0;	pp = cpustate_names;	ip = cpustate_columns;	while (*pp != NULL)	{	    *ip++ = cpustate_total_length;	    if ((i = strlen(*pp++)) > 0)	    {		cpustate_total_length += i + 8;	    }	}    }    /* return number of lines available */    return(lines);}i_loadave(mpid, avenrun)int mpid;double *avenrun;{    register int i;    /* i_loadave also clears the screen, since it is first */    clear();    /* mpid == -1 implies this system doesn't have an _mpid */    if (mpid != -1)    {	printf("last pid: %5d;  ", mpid);    }    printf("load averages");    for (i = 0; i < 3; i++)    {	printf("%c %5.2f",	    i == 0 ? ':' : ',',	    avenrun[i]);    }    lmpid = mpid;}u_loadave(mpid, avenrun)int mpid;double *avenrun;{    register int i;    if (mpid != -1)    {	/* change screen only when value has really changed */	if (mpid != lmpid)	{	    Move_to(x_lastpid, y_lastpid);	    printf("%5d", mpid);	    lmpid = mpid;	}	/* i remembers x coordinate to move to */	i = x_loadave;    }    else    {	i = x_loadave_nompid;    }    /* move into position for load averages */    Move_to(i, y_loadave);    /* display new load averages */    /* we should optimize this and only display changes */    for (i = 0; i < 3; i++)    {	printf("%s%5.2f",	    i == 0 ? "" : ", ",	    avenrun[i]);    }}i_timeofday(tod)time_t *tod;{    /*     *  Display the current time.     *  "ctime" always returns a string that looks like this:     *       *	Sun Sep 16 01:03:52 1973     *      012345678901234567890123     *	          1         2     *     *  We want indices 11 thru 18 (length 8).     */    if (smart_terminal)    {	Move_to(screen_width - 8, 0);    }    else    {	fputs("    ", stdout);    }#ifdef DEBUG    {	char *foo;	foo = ctime(tod);	fputs(foo, stdout);    }#endif    printf("%-8.8s\n", &(ctime(tod)[11]));    lastline = 1;}static int ltotal = 0;static char procstates_buffer[MAX_COLS];/* *  *_procstates(total, brkdn, names) - print the process summary line * *  Assumptions:  cursor is at the beginning of the line on entry *		  lastline is valid */i_procstates(total, brkdn)int total;int *brkdn;{    register int i;    /* write current number of processes and remember the value */    printf("%d processes:", total);    ltotal = total;    /* put out enough spaces to get to column 15 */    i = digits(total);    while (i++ < 4)    {	putchar(' ');    }    /* format and print the process state summary */    summary_format(procstates_buffer, brkdn, procstate_names);    fputs(procstates_buffer, stdout);    /* save the numbers for next time */    memcpy(lprocstates, brkdn, num_procstates * sizeof(int));}u_procstates(total, brkdn)int total;int *brkdn;{    static char new[MAX_COLS];    register int i;    /* update number of processes only if it has changed */    if (ltotal != total)    {	/* move and overwrite */#if (x_procstate == 0)	Move_to(x_procstate, y_procstate);#else	/* cursor is already there...no motion needed */	/* assert(lastline == 1); */#endif	printf("%d", total);	/* if number of digits differs, rewrite the label */	if (digits(total) != digits(ltotal))	{	    fputs(" processes:", stdout);	    /* put out enough spaces to get to column 15 */	    i = digits(total);	    while (i++ < 4)	    {		putchar(' ');	    }	    /* cursor may end up right where we want it!!! */	}	/* save new total */	ltotal = total;    }    /* see if any of the state numbers has changed */    if (memcmp(lprocstates, brkdn, num_procstates * sizeof(int)) != 0)    {	/* format and update the line */	summary_format(new, brkdn, procstate_names);	line_update(procstates_buffer, new, x_brkdn, y_brkdn);	memcpy(lprocstates, brkdn, num_procstates * sizeof(int));    }}/* *  *_cpustates(states, names) - print the cpu state percentages * *  Assumptions:  cursor is on the PREVIOUS line */static int cpustates_column;/* cpustates_tag() calculates the correct tag to use to label the line */char *cpustates_tag(){    register char *use;    static char *short_tag = "CPU: ";    static char *long_tag = "CPU states: ";    /* if length + strlen(long_tag) >= screen_width, then we have to       use the shorter tag (we subtract 2 to account for ": ") */    if (cpustate_total_length + (int)strlen(long_tag) - 2 >= screen_width)    {	use = short_tag;    }    else    {	use = long_tag;    }    /* set cpustates_column accordingly then return result */    cpustates_column = strlen(use);    return(use);}i_cpustates(states)register int *states;{    register int i = 0;    register int value;    register char **names = cpustate_names;    register char *thisname;    /* print tag and bump lastline */    printf("\n%s", cpustates_tag());    lastline++;    /* now walk thru the names and print the line */    while ((thisname = *names++) != NULL)    {	if (*thisname != '\0')	{	    /* retrieve the value and remember it */	    value = *states++;	    /* if percentage is >= 1000, print it as 100% */	    printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"),		   i++ == 0 ? "" : ", ",		   ((float)value)/10.,		   thisname);	}    }    /* copy over values into "last" array */    memcpy(lcpustates, states, num_cpustates * sizeof(int));}u_cpustates(states)register int *states;{    register int value;    register char **names = cpustate_names;    register char *thisname;    register int *lp;    register int *colp;    Move_to(cpustates_column, y_cpustates);    lastline = y_cpustates;    lp = lcpustates;    colp = cpustate_columns;    /* we could be much more optimal about this */    while ((thisname = *names++) != NULL)    {	if (*thisname != '\0')	{	    /* did the value change since last time? */	    if (*lp != *states)	    {		/* yes, move and change */		Move_to(cpustates_column + *colp, y_cpustates);		lastline = y_cpustates;		/* retrieve value and remember it */		value = *states;		/* if percentage is >= 1000, print it as 100% */		printf((value >= 1000 ? "%4.0f" : "%4.1f"),		       ((double)value)/10.);		/* remember it for next time */		*lp = value;	    }	}	/* increment and move on */	lp++;	states++;	colp++;    }}z_cpustates(){    register int i = 0;    register char **names = cpustate_names;    register char *thisname;    register int *lp;    /* show tag and bump lastline */    printf("\n%s", cpustates_tag());    lastline++;    while ((thisname = *names++) != NULL)    {	if (*thisname != '\0')	{	    printf("%s    %% %s", i++ == 0 ? "" : ", ", thisname);	}    }    /* fill the "last" array with all -1s, to insure correct updating */    lp = lcpustates;    i = num_cpustates;    while (--i >= 0)    {	*lp++ = -1;    }}/* *  *_memory(stats) - print "Memory: " followed by the memory summary string * *  Assumptions:  cursor is on "lastline" *                for i_memory ONLY: cursor is on the previous line */char memory_buffer[MAX_COLS];i_memory(stats)int *stats;{    fputs("\nMemory: ", stdout);    lastline++;    /* format and print the memory summary */    summary_format(memory_buffer, stats, memory_names);    fputs(memory_buffer, stdout);}u_memory(stats)int *stats;{    static char new[MAX_COLS];    /* format the new line */    summary_format(new, stats, memory_names);    line_update(memory_buffer, new, x_mem, y_mem);}/* *  *_message() - print the next pending message line, or erase the one *                that is there. * *  Note that u_message is (currently) the same as i_message. * *  Assumptions:  lastline is consistent *//* *  i_message is funny because it gets its message asynchronously (with *	respect to screen updates). */static char next_msg[MAX_COLS + 5];static int msglen = 0;/* Invariant: msglen is always the length of the message currently displayed   on the screen (even when next_msg doesn't contain that message). */i_message(){    while (lastline < y_message)    {	fputc('\n', stdout);	lastline++;    }    if (next_msg[0] != '\0')    {	standout(next_msg);	msglen = strlen(next_msg);	next_msg[0] = '\0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -