* as follows:
* cpus[0] thru cpus[n] == tics for each separate cpu
* cpus[Cpu_tot] == tics from the 1st /proc/stat line */
-static CPUS_t *cpus_refresh (CPUS_t *restrict cpus)
+static CPUS_t *cpus_refresh (CPUS_t *cpus)
{
static FILE *fp = NULL;
int i;
char *p;
while (*args) {
- char *cp = *(args++);
+ const char *cp = *(args++);
while (*cp) {
switch (*cp) {
#define L_CMDLINE L_stat | PROC_FILLARG
#define L_EUSER L_status | PROC_FILLUSR
#define L_GROUP L_status | PROC_FILLGRP
-#define L_EITHER PROC_SPARE_1
#define L_NONE 0
+ // from either 'stat' or 'status' (preferred), via bits not otherwise used
+#define L_EITHER ~(L_stat|L_statm|L_status|L_CMDLINE|L_EUSER|L_GROUP)
// for reframewins and summary_show 1st pass
#define L_DEFAULT PROC_FILLSTAT
{ "USER ", "%-8.8s ", -1, -1, _SF(P_USR), "User Name", L_EUSER },
{ "GROUP ", "%-8.8s ", -1, -1, _SF(P_GRP), "Group Name", L_GROUP },
{ "TTY ", "%-8.8s ", 8, -1, _SF(P_TTY), "Controlling Tty", L_stat },
- { " PR ", "%s ", -1, -1, _SF(P_PRI), "Priority", L_stat },
+ { " PR ", "%3d ", -1, -1, _SF(P_PRI), "Priority", L_stat },
{ " NI ", "%3d ", -1, -1, _SF(P_NCE), "Nice value", L_stat },
{ "#C ", "%2u ", -1, -1, _SF(P_CPN), "Last used cpu (SMP)", L_stat },
{ "%CPU ", "%#4.1f ", -1, -1, _SF(P_CPU), "CPU usage", L_stat },
{ "Command ", "%-*.*s ", -1, -1, _SF(P_CMD), "Command name/line", L_stat },
{ "WCHAN ", "%-9.9s ", -1, -1, _SF(P_WCH), "Sleeping in Function", L_stat },
// next entry's special: the 0's will be replaced with '.'!
- { "Flags ", "%s ", -1, -1, _SF(P_FLG), "Task Flags <sched.h>", L_stat }
+#ifdef CASEUP_HEXES
+ { "Flags ", "%08lX ", -1, -1, _SF(P_FLG), "Task Flags <sched.h>", L_stat }
+#else
+ { "Flags ", "%08lx ", -1, -1, _SF(P_FLG), "Task Flags <sched.h>", L_stat }
+#endif
};
* 2) modest smp boxes with room for each cpu's percentages
* 3) massive smp guys leaving little or no room for process
* display and thus requiring the cpu summary toggle */
-static void summaryhlp (CPUS_t *restrict const cpu, const char *restrict const pfx)
+static void summaryhlp (CPUS_t *cpu, const char *pfx)
{
/* we'll trim to zero if we get negative time ticks,
which has happened with some SMP kernels (pre-2.4?) */
/*
* Display information for a single task row. */
-static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
+static void task_show (const WIN_t *q, const proc_t *p)
{
/* the following macro is our means to 'inline' emitting a column -- next to
procs_refresh, that's the most frequent and costly part of top's job ! */
for (x = 0; x < q->maxpflgs; x++) {
char cbuf[ROWBUFSIZ], _z[ROWBUFSIZ];
- PFLG_t i = q->procflags[x]; // support for our make column
- const char *restrict const f = Fieldstab[i].fmts; // macro AND sometimes
- unsigned s = Fieldstab[i].scale; // fmt string must be altered !
+ PFLG_t i = q->procflags[x]; // support for our field/column
+ const char *f = Fieldstab[i].fmts; // macro AND sometimes the fmt
+ unsigned s = Fieldstab[i].scale; // string must be altered !
unsigned w = Fieldstab[i].width;
switch (i) {
case P_CMD:
- { const char *restrict ret;
+ { char *cp;
if (CHKw(q, Show_CMDLIN)) {
char tmp[ROWBUFSIZ];
if (p->cmdline) {
- char *cp;
j = 0;
*(cp = tmp) = '\0';
do {
strim(1, tmp);
} else
strcpy(tmp, fmtmk(CMDLINE_FMTS, p->cmd));
- ret = tmp;
+ cp = tmp;
} else
- ret = p->cmd;
- MKCOL(q->maxcmdln, q->maxcmdln, ret);
+ cp = (char *)p->cmd;
+ MKCOL(q->maxcmdln, q->maxcmdln, cp);
}
break;
case P_COD:
break;
case P_FLG:
{ char tmp[TNYBUFSIZ];
- snprintf(tmp, sizeof(tmp), "%08x", (unsigned)p->flags);
+ snprintf(tmp, sizeof(tmp), f, (long)p->flags);
for (j = 0; tmp[j]; j++) if ('0' == tmp[j]) tmp[j] = '.';
- MKCOL(tmp);
+ f = tmp;
+ MKCOL();
}
break;
case P_FLT:
MKCOL((unsigned)p->ppid);
break;
case P_PRI:
- { char tmp[TNYBUFSIZ];
- snprintf(tmp, sizeof(tmp), "%3d", (int)(p->priority));
- if (-99 > p->priority || 999 < p->priority) {
- memcpy(tmp, " RT", 4);
- }
- MKCOL(tmp);
- }
+ if (-99 > p->priority || +99 < p->priority) {
+ f = " RT ";
+ MKCOL();
+ } else
+ MKCOL((int)p->priority);
break;
case P_RES:
MKCOL(scale_num(PAGES_2K(p->resident), w, s));
break;
case P_WCH:
if (No_ksyms) {
- char tmp[TNYBUFSIZ];
- snprintf(tmp, sizeof(tmp), "%08lx ", (unsigned long)p->wchan);
- MKCOL(tmp);
+#ifdef CASEUP_HEXES
+ f = "%08lX ";
+#else
+ f = "%08lx ";
+#endif
+ MKCOL((long)p->wchan);
} else {
MKCOL(wchan(p->wchan));
}
static int sort_ ## f (const proc_t **P, const proc_t **Q) { \
return Frame_srtflg * strcmp((*Q)->s, (*P)->s); }
- /* Used in the following ways, to 'inline' those portions of the
- display requiring formatting while protecting against potential
- embedded 'millesecond delay' escape sequences.
- PUTT - Put to Tty
- . for temporary interactive 'REPLACEMENT' output
+ /* The following two macros are used to 'inline' those portions of the
+ * display process requiring formatting, while protecting against any
+ * potential embedded 'millesecond delay' escape sequences. */
+ /** PUTT - Put to Tty (used in many places)
+ . for temporary, possibly interactive, 'replacement' output
. may contain ANY valid terminfo escape sequences
- . need NOT represent an entire screen row
- PUFF - Put for Frame
- . for more permanent frame-oriented 'UPDATE' output
- . may NOT contain cursor motion terminfo escapes
- . represents a complete screen ROW
- . subject to optimization, thus MAY be discarded
- . when discarded, replaced by a NEWLINE */
+ . need NOT represent an entire screen row */
#define PUTT(fmt,arg...) do { \
char _str[ROWBUFSIZ]; \
snprintf(_str, sizeof(_str), fmt, ## arg); \
putp(_str); \
} while (0)
+ /** PUFF - Put for Frame (used in only 3 places)
+ . for more permanent frame-oriented 'update' output
+ . may NOT contain cursor motion terminfo escapes
+ . assumed to represent a complete screen ROW
+ . subject to optimization, thus MAY be discarded */
#define PUFF(fmt,arg...) do { \
char _str[ROWBUFSIZ]; \
char *_ptr = &Pseudo_scrn[Pseudo_row++ * Pseudo_cols]; \
calculations. It exists primarily for SMP support but serves
all environments. */
typedef struct {
- // ticks count as represented in /proc/stat
- TICS_t u, n, s, i, w;
- // tics count in the order of our display
- TICS_t u_sav, s_sav, n_sav, i_sav, w_sav;
+ TICS_t u, n, s, i, w; // as represented in /proc/stat
+ TICS_t u_sav, s_sav, n_sav, i_sav, w_sav; // in the order of our display
} CPUS_t;
/* The scaling 'type' used with scale_num() -- this is how
"commands plus the 'G' sub-commands NOW. Press <Enter> to make 'Current' " \
""
+
+/*###### For Piece of mind and/or backward compatability ################*/
+
+ /* just sanity check(s)... */
+#if USRNAMSIZ < GETBUFSIZ
+# error "Jeeze, USRNAMSIZ Must NOT be less than GETBUFSIZ !"
+#endif
+#ifndef MALLOC
+# define MALLOC
+#endif
+#ifndef restrict
+# define restrict
+#endif
+
\f
/*###### Some Prototypes (ha!) #########################################*/
* source code navigation, which often influences the identifers. */
/*------ Sort callbacks ------------------------------------------------*/
/* for each possible field, in the form of: */
-/*atic int sort_P_XXX (const proc_t **P, const proc_t **Q); */
+/*atic int sort_P_XXX (const proc_t **P, const proc_t **Q); */
/* additional specialized sort callback(s) */
-//atic int sort_HIST_t (const HIST_t *P, const HIST_t *Q);
+/*atic int sort_HIST_t (const HIST_t *P, const HIST_t *Q); */
/*------ Tiny useful routine(s) ----------------------------------------*/
//atic int chin (int ech, char *buf, unsigned cnt);
//atic const char *fmtmk (const char *fmts, ...);
/*------ Library Alternatives ------------------------------------------*/
//atic void *alloc_c (unsigned numb) MALLOC;
//atic void *alloc_r (void *q, unsigned numb) MALLOC;
-//atic CPUS_t *cpus_refresh (CPUS_t *restrict cpus);
+//atic CPUS_t *cpus_refresh (CPUS_t *cpus);
//atic void prochlp (proc_t *this);
//atic proc_t **procs_refresh (proc_t **table, int flags);
/*------ Startup routines ----------------------------------------------*/
//atic void parse_args (char **args);
//atic void whack_terminal (void);
/*------ Field Selection/Ordering routines -----------------------------*/
-/*atic FTAB_t Fieldstab[] = { ... } */
+/*atic FTAB_t Fieldstab[] = { ... } */
//atic void display_fields (const char *fields, const char *xtra);
//atic void fields_reorder (void);
//atic void fields_sort (void);
//atic void windows_stage2 (void);
/*------ Main Screen routines ------------------------------------------*/
//atic void do_key (unsigned c);
-//atic void summaryhlp (CPUS_t *restrict const cpu, const char *restrict const pfx);
+//atic void summaryhlp (CPUS_t *cpu, const char *pfx);
//atic proc_t **summary_show (void);
-//atic void task_show (const WIN_t *restrict q, const proc_t *restrict p);
+//atic void task_show (const WIN_t *q, const proc_t *p);
//atic void window_show (proc_t **ppt, WIN_t *q, int *lscr);
/*------ Entry point plus two ------------------------------------------*/
//atic void framehlp (int wix, int max);
//atic void frame_make (void);
// int main (int dont_care_argc, char **argv);
- /* just sanity check(s)... */
-#if USRNAMSIZ < GETBUFSIZ
-# error "Jeeze, USRNAMSIZ Must NOT be less than GETBUFSIZ !"
-#endif
-
#endif /* _Itop */
\f
* Mike Coleman <mkc@acm.org>.
*/
-
#define VERSION "0.2.0"
#include <ctype.h>
#include <unistd.h>
#include <locale.h>
-static struct option longopts[] =
- {
- { "differences", optional_argument, 0, 'd' },
- { "help", no_argument, 0, 'h' },
- { "interval", required_argument, 0, 'n' },
- { "version", no_argument, 0, 'v' },
- { 0, 0, 0, 0 }
- };
-
-static char usage[] = "Usage: %s [-dhnv] [--differences[=cumulative]] [--help] [--interval=<n>] [--version] <command>\n";
+static struct option longopts[] = {
+ {"differences", optional_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"interval", required_argument, 0, 'n'},
+ {"version", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+};
+static char usage[] =
+ "Usage: %s [-dhnv] [--differences[=cumulative]] [--help] [--interval=<n>] [--version] <command>\n";
static char *progname;
static int curses_started = 0;
-static int height=24, width=80;
-static int screen_size_changed=0;
-static int first_screen=1;
-
+static int height = 24, width = 80;
+static int screen_size_changed = 0;
+static int first_screen = 1;
#define min(x,y) ((x) > (y) ? (y) : (x))
-
static void
do_usage(void)
{
- fprintf(stderr, usage, progname);
- exit(1);
+ fprintf(stderr, usage, progname);
+ exit(1);
}
-
static void
-do_exit(int status) {
- if (curses_started)
- endwin();
- exit(status);
+do_exit(int status)
+{
+ if (curses_started)
+ endwin();
+ exit(status);
}
-
/* signal handler */
static void
die(int notused)
{
- (void)notused;
- do_exit(0);
+ (void) notused;
+ do_exit(0);
}
-
static void
winch_handler(int notused)
{
- (void)notused;
- screen_size_changed = 1;
+ (void) notused;
+ screen_size_changed = 1;
}
-
static void
get_terminal_size(void)
{
- struct winsize w;
- if (ioctl(2, TIOCGWINSZ, &w) == 0)
- {
- if (w.ws_row > 0)
- height = w.ws_row;
- if (w.ws_col > 0)
- width = w.ws_col;
- }
+ struct winsize w;
+ if (ioctl(2, TIOCGWINSZ, &w) == 0) {
+ if (w.ws_row > 0)
+ height = w.ws_row;
+ if (w.ws_col > 0)
+ width = w.ws_col;
+ }
}
-
int
main(int argc, char *argv[])
{
- int optc;
- int option_differences=0,
- option_differences_cumulative=0,
- option_help=0,
- option_version=0;
- int interval=2;
- char *command;
- int command_length=0; /* not including final \0 */
-
- setlocale(LC_ALL,"");
- progname = argv[0];
-
- while ((optc = getopt_long(argc, argv, "+d::hn:v", longopts, (int *) 0))
- != EOF)
- {
- switch (optc)
- {
- case 'd':
- option_differences = 1;
- if (optarg)
- option_differences_cumulative = 1;
- break;
- case 'h':
- option_help = 1;
- break;
- case 'n':
- {
- char *str;
- interval = strtol(optarg, &str, 10);
- if (!*optarg || *str)
- do_usage();
- }
- break;
- case 'v':
- option_version = 1;
- break;
- default:
- do_usage();
- break;
+ int optc;
+ int option_differences = 0,
+ option_differences_cumulative = 0,
+ option_help = 0, option_version = 0;
+ int interval = 2;
+ char *command;
+ int command_length = 0; /* not including final \0 */
+
+ setlocale(LC_ALL, "");
+ progname = argv[0];
+
+ while ((optc = getopt_long(argc, argv, "+d::hn:v", longopts, (int *) 0))
+ != EOF) {
+ switch (optc) {
+ case 'd':
+ option_differences = 1;
+ if (optarg)
+ option_differences_cumulative = 1;
+ break;
+ case 'h':
+ option_help = 1;
+ break;
+ case 'n':
+ {
+ char *str;
+ interval = strtol(optarg, &str, 10);
+ if (!*optarg || *str)
+ do_usage();
+ }
+ break;
+ case 'v':
+ option_version = 1;
+ break;
+ default:
+ do_usage();
+ break;
+ }
}
- }
-
- if (option_version)
- {
- fprintf (stderr, "%s\n", VERSION);
- if (!option_help)
- exit(0);
- }
-
- if (option_help)
- {
- fprintf(stderr, usage, progname);
- fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr);
- fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr);
- fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr);
- fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr);
- fputs(" -v, --version\t\t\t\tprint the version number\n", stderr);
- exit(0);
- }
-
- if (optind >= argc)
- do_usage();
-
- command = strdup(argv[optind++]);
- command_length = strlen(command);
- for (;optind<argc;optind++)
- {
- char *endp;
- int s = strlen(argv[optind]);
- command = realloc(command, command_length+s+2); /* space and \0 */
- endp = command + command_length;
- *endp = ' ';
- memcpy(endp+1, argv[optind],s);
- command_length += 1+s; /* space then string length */
- command[command_length] = '\0';
- }
-
- get_terminal_size();
-
- /* Catch keyboard interrupts so we can put tty back in a sane state. */
- signal(SIGINT, die);
- signal(SIGTERM, die);
- signal(SIGHUP, die);
- signal(SIGWINCH, winch_handler);
-
- /* Set up tty for curses use. */
- curses_started = 1;
- initscr();
- nonl();
- noecho();
- cbreak();
-
- for(;;)
- {
- time_t t = time(NULL);
- char *ts = ctime(&t);
- int tsl = strlen(ts);
- char *header;
- FILE *p;
- int x, y;
- int oldeolseen = 1;
-
- if (screen_size_changed)
- {
- get_terminal_size();
- resizeterm(height, width);
- clear();
- /* redrawwin(stdscr); */
- screen_size_changed = 0;
- first_screen = 1;
+
+ if (option_version) {
+ fprintf(stderr, "%s\n", VERSION);
+ if (!option_help)
+ exit(0);
+ }
+
+ if (option_help) {
+ fprintf(stderr, usage, progname);
+ fputs
+ (" -d, --differences[=cumulative]\thighlight changes between updates\n",
+ stderr);
+ fputs("\t\t(cumulative means highlighting is cumulative)\n",
+ stderr);
+ fputs(" -h, --help\t\t\t\tprint a summary of the options\n",
+ stderr);
+ fputs
+ (" -n, --interval=<seconds>\t\tseconds to wait between updates\n",
+ stderr);
+ fputs(" -v, --version\t\t\t\tprint the version number\n",
+ stderr);
+ exit(0);
}
- /* left justify interval and command, right justify time, clipping all
- to fit window width */
- asprintf(&header, "Every %ds: %.*s",
- interval, min(width-1, command_length), command);
- mvaddstr(0, 0, header);
- if (strlen(header) > (size_t)(width - tsl - 1))
- mvaddstr(0, width - tsl - 4, "... ");
- mvaddstr(0, width - tsl + 1, ts);
- free(header);
-
- if (!(p = popen(command, "r")))
- {
- perror("popen");
- do_exit(2);
+ if (optind >= argc)
+ do_usage();
+
+ command = strdup(argv[optind++]);
+ command_length = strlen(command);
+ for (; optind < argc; optind++) {
+ char *endp;
+ int s = strlen(argv[optind]);
+ command = realloc(command, command_length + s + 2); /* space and \0 */
+ endp = command + command_length;
+ *endp = ' ';
+ memcpy(endp + 1, argv[optind], s);
+ command_length += 1 + s; /* space then string length */
+ command[command_length] = '\0';
}
- for (y=2; y<height; y++)
- {
- int eolseen = 0, tabpending = 0;
- for (x=0; x<width; x++)
- {
- int c = ' ';
- int attr = 0;
-
- if (!eolseen)
- {
- /* if there is a tab pending, just spit spaces until the
- next stop instead of reading characters */
- if (!tabpending)
- do
- c = getc(p);
- while (c != EOF && !isprint(c) && c != '\n' && c != '\t');
- if (c == '\n')
- if (!oldeolseen && x == 0) {
- x=-1;
- continue;
- } else
- eolseen = 1;
- else if (c == '\t')
- tabpending = 1;
- if (c == EOF || c == '\n' || c == '\t')
- c = ' ';
- if (tabpending && (((x + 1) % 8) == 0))
- tabpending = 0;
+ get_terminal_size();
+
+ /* Catch keyboard interrupts so we can put tty back in a sane state. */
+ signal(SIGINT, die);
+ signal(SIGTERM, die);
+ signal(SIGHUP, die);
+ signal(SIGWINCH, winch_handler);
+
+ /* Set up tty for curses use. */
+ curses_started = 1;
+ initscr();
+ nonl();
+ noecho();
+ cbreak();
+
+ for (;;) {
+ time_t t = time(NULL);
+ char *ts = ctime(&t);
+ int tsl = strlen(ts);
+ char *header;
+ FILE *p;
+ int x, y;
+ int oldeolseen = 1;
+
+ if (screen_size_changed) {
+ get_terminal_size();
+ resizeterm(height, width);
+ clear();
+ /* redrawwin(stdscr); */
+ screen_size_changed = 0;
+ first_screen = 1;
}
- move(y, x);
- if (option_differences)
- {
- int oldch = inch();
- char oldc = oldch & A_CHARTEXT;
- attr = !first_screen
- && (c != oldc
- || (option_differences_cumulative
- && (oldch & A_ATTRIBUTES)));
+
+ /* left justify interval and command, right justify time, clipping all
+ to fit window width */
+ asprintf(&header, "Every %ds: %.*s",
+ interval, min(width - 1, command_length), command);
+ mvaddstr(0, 0, header);
+ if (strlen(header) > (size_t) (width - tsl - 1))
+ mvaddstr(0, width - tsl - 4, "... ");
+ mvaddstr(0, width - tsl + 1, ts);
+ free(header);
+
+ if (!(p = popen(command, "r"))) {
+ perror("popen");
+ do_exit(2);
}
- if (attr)
- standout();
- addch(c);
- if (attr)
- standend();
- }
- oldeolseen = eolseen;
- }
- pclose(p);
+ for (y = 2; y < height; y++) {
+ int eolseen = 0, tabpending = 0;
+ for (x = 0; x < width; x++) {
+ int c = ' ';
+ int attr = 0;
+
+ if (!eolseen) {
+ /* if there is a tab pending, just spit spaces until the
+ next stop instead of reading characters */
+ if (!tabpending)
+ do
+ c = getc(p);
+ while (c != EOF && !isprint(c)
+ && c != '\n'
+ && c != '\t');
+ if (c == '\n')
+ if (!oldeolseen && x == 0) {
+ x = -1;
+ continue;
+ } else
+ eolseen = 1;
+ else if (c == '\t')
+ tabpending = 1;
+ if (c == EOF || c == '\n' || c == '\t')
+ c = ' ';
+ if (tabpending && (((x + 1) % 8) == 0))
+ tabpending = 0;
+ }
+ move(y, x);
+ if (option_differences) {
+ int oldch = inch();
+ char oldc = oldch & A_CHARTEXT;
+ attr = !first_screen
+ && (c != oldc
+ ||
+ (option_differences_cumulative
+ && (oldch & A_ATTRIBUTES)));
+ }
+ if (attr)
+ standout();
+ addch(c);
+ if (attr)
+ standend();
+ }
+ oldeolseen = eolseen;
+ }
- first_screen = 0;
- refresh();
- sleep(interval);
- }
+ pclose(p);
+
+ first_screen = 0;
+ refresh();
+ sleep(interval);
+ }
- endwin();
+ endwin();
- return 0;
+ return 0;
}