revert the Nov2002 c99 attempt
This commit is contained in:
parent
bc60aa667d
commit
d614bf02e6
60
top.c
60
top.c
@ -810,7 +810,7 @@ static void *alloc_r (void *q, unsigned numb)
|
|||||||
* as follows:
|
* as follows:
|
||||||
* cpus[0] thru cpus[n] == tics for each separate cpu
|
* cpus[0] thru cpus[n] == tics for each separate cpu
|
||||||
* cpus[Cpu_tot] == tics from the 1st /proc/stat line */
|
* 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;
|
static FILE *fp = NULL;
|
||||||
int i;
|
int i;
|
||||||
@ -1132,7 +1132,7 @@ static void parse_args (char **args)
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
while (*args) {
|
while (*args) {
|
||||||
char *cp = *(args++);
|
const char *cp = *(args++);
|
||||||
|
|
||||||
while (*cp) {
|
while (*cp) {
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
@ -1261,8 +1261,9 @@ static void whack_terminal (void)
|
|||||||
#define L_CMDLINE L_stat | PROC_FILLARG
|
#define L_CMDLINE L_stat | PROC_FILLARG
|
||||||
#define L_EUSER L_status | PROC_FILLUSR
|
#define L_EUSER L_status | PROC_FILLUSR
|
||||||
#define L_GROUP L_status | PROC_FILLGRP
|
#define L_GROUP L_status | PROC_FILLGRP
|
||||||
#define L_EITHER PROC_SPARE_1
|
|
||||||
#define L_NONE 0
|
#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
|
// for reframewins and summary_show 1st pass
|
||||||
#define L_DEFAULT PROC_FILLSTAT
|
#define L_DEFAULT PROC_FILLSTAT
|
||||||
|
|
||||||
@ -1287,7 +1288,7 @@ static FTAB_t Fieldstab[] = {
|
|||||||
{ "USER ", "%-8.8s ", -1, -1, _SF(P_USR), "User Name", L_EUSER },
|
{ "USER ", "%-8.8s ", -1, -1, _SF(P_USR), "User Name", L_EUSER },
|
||||||
{ "GROUP ", "%-8.8s ", -1, -1, _SF(P_GRP), "Group Name", L_GROUP },
|
{ "GROUP ", "%-8.8s ", -1, -1, _SF(P_GRP), "Group Name", L_GROUP },
|
||||||
{ "TTY ", "%-8.8s ", 8, -1, _SF(P_TTY), "Controlling Tty", L_stat },
|
{ "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 },
|
{ " NI ", "%3d ", -1, -1, _SF(P_NCE), "Nice value", L_stat },
|
||||||
{ "#C ", "%2u ", -1, -1, _SF(P_CPN), "Last used cpu (SMP)", 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 },
|
{ "%CPU ", "%#4.1f ", -1, -1, _SF(P_CPU), "CPU usage", L_stat },
|
||||||
@ -1312,7 +1313,11 @@ static FTAB_t Fieldstab[] = {
|
|||||||
{ "Command ", "%-*.*s ", -1, -1, _SF(P_CMD), "Command name/line", 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 },
|
{ "WCHAN ", "%-9.9s ", -1, -1, _SF(P_WCH), "Sleeping in Function", L_stat },
|
||||||
// next entry's special: the 0's will be replaced with '.'!
|
// 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2164,7 +2169,7 @@ static void do_key (unsigned c)
|
|||||||
* 2) modest smp boxes with room for each cpu's percentages
|
* 2) modest smp boxes with room for each cpu's percentages
|
||||||
* 3) massive smp guys leaving little or no room for process
|
* 3) massive smp guys leaving little or no room for process
|
||||||
* display and thus requiring the cpu summary toggle */
|
* 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,
|
/* we'll trim to zero if we get negative time ticks,
|
||||||
which has happened with some SMP kernels (pre-2.4?) */
|
which has happened with some SMP kernels (pre-2.4?) */
|
||||||
@ -2280,7 +2285,7 @@ static proc_t **summary_show (void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Display information for a single task row. */
|
* 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
|
/* 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 ! */
|
procs_refresh, that's the most frequent and costly part of top's job ! */
|
||||||
@ -2304,18 +2309,17 @@ static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
|
|||||||
|
|
||||||
for (x = 0; x < q->maxpflgs; x++) {
|
for (x = 0; x < q->maxpflgs; x++) {
|
||||||
char cbuf[ROWBUFSIZ], _z[ROWBUFSIZ];
|
char cbuf[ROWBUFSIZ], _z[ROWBUFSIZ];
|
||||||
PFLG_t i = q->procflags[x]; // support for our make column
|
PFLG_t i = q->procflags[x]; // support for our field/column
|
||||||
const char *restrict const f = Fieldstab[i].fmts; // macro AND sometimes
|
const char *f = Fieldstab[i].fmts; // macro AND sometimes the fmt
|
||||||
unsigned s = Fieldstab[i].scale; // fmt string must be altered !
|
unsigned s = Fieldstab[i].scale; // string must be altered !
|
||||||
unsigned w = Fieldstab[i].width;
|
unsigned w = Fieldstab[i].width;
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case P_CMD:
|
case P_CMD:
|
||||||
{ const char *restrict ret;
|
{ char *cp;
|
||||||
if (CHKw(q, Show_CMDLIN)) {
|
if (CHKw(q, Show_CMDLIN)) {
|
||||||
char tmp[ROWBUFSIZ];
|
char tmp[ROWBUFSIZ];
|
||||||
if (p->cmdline) {
|
if (p->cmdline) {
|
||||||
char *cp;
|
|
||||||
j = 0;
|
j = 0;
|
||||||
*(cp = tmp) = '\0';
|
*(cp = tmp) = '\0';
|
||||||
do {
|
do {
|
||||||
@ -2325,10 +2329,10 @@ static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
|
|||||||
strim(1, tmp);
|
strim(1, tmp);
|
||||||
} else
|
} else
|
||||||
strcpy(tmp, fmtmk(CMDLINE_FMTS, p->cmd));
|
strcpy(tmp, fmtmk(CMDLINE_FMTS, p->cmd));
|
||||||
ret = tmp;
|
cp = tmp;
|
||||||
} else
|
} else
|
||||||
ret = p->cmd;
|
cp = (char *)p->cmd;
|
||||||
MKCOL(q->maxcmdln, q->maxcmdln, ret);
|
MKCOL(q->maxcmdln, q->maxcmdln, cp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_COD:
|
case P_COD:
|
||||||
@ -2351,9 +2355,10 @@ static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
|
|||||||
break;
|
break;
|
||||||
case P_FLG:
|
case P_FLG:
|
||||||
{ char tmp[TNYBUFSIZ];
|
{ 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] = '.';
|
for (j = 0; tmp[j]; j++) if ('0' == tmp[j]) tmp[j] = '.';
|
||||||
MKCOL(tmp);
|
f = tmp;
|
||||||
|
MKCOL();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_FLT:
|
case P_FLT:
|
||||||
@ -2378,13 +2383,11 @@ static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
|
|||||||
MKCOL((unsigned)p->ppid);
|
MKCOL((unsigned)p->ppid);
|
||||||
break;
|
break;
|
||||||
case P_PRI:
|
case P_PRI:
|
||||||
{ char tmp[TNYBUFSIZ];
|
if (-99 > p->priority || +99 < p->priority) {
|
||||||
snprintf(tmp, sizeof(tmp), "%3d", (int)(p->priority));
|
f = " RT ";
|
||||||
if (-99 > p->priority || 999 < p->priority) {
|
MKCOL();
|
||||||
memcpy(tmp, " RT", 4);
|
} else
|
||||||
}
|
MKCOL((int)p->priority);
|
||||||
MKCOL(tmp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case P_RES:
|
case P_RES:
|
||||||
MKCOL(scale_num(PAGES_2K(p->resident), w, s));
|
MKCOL(scale_num(PAGES_2K(p->resident), w, s));
|
||||||
@ -2427,9 +2430,12 @@ static void task_show (const WIN_t *restrict q, const proc_t *restrict p)
|
|||||||
break;
|
break;
|
||||||
case P_WCH:
|
case P_WCH:
|
||||||
if (No_ksyms) {
|
if (No_ksyms) {
|
||||||
char tmp[TNYBUFSIZ];
|
#ifdef CASEUP_HEXES
|
||||||
snprintf(tmp, sizeof(tmp), "%08lx ", (unsigned long)p->wchan);
|
f = "%08lX ";
|
||||||
MKCOL(tmp);
|
#else
|
||||||
|
f = "%08lx ";
|
||||||
|
#endif
|
||||||
|
MKCOL((long)p->wchan);
|
||||||
} else {
|
} else {
|
||||||
MKCOL(wchan(p->wchan));
|
MKCOL(wchan(p->wchan));
|
||||||
}
|
}
|
||||||
|
60
top.h
60
top.h
@ -108,24 +108,23 @@
|
|||||||
static int sort_ ## f (const proc_t **P, const proc_t **Q) { \
|
static int sort_ ## f (const proc_t **P, const proc_t **Q) { \
|
||||||
return Frame_srtflg * strcmp((*Q)->s, (*P)->s); }
|
return Frame_srtflg * strcmp((*Q)->s, (*P)->s); }
|
||||||
|
|
||||||
/* Used in the following ways, to 'inline' those portions of the
|
/* The following two macros are used to 'inline' those portions of the
|
||||||
display requiring formatting while protecting against potential
|
* display process requiring formatting, while protecting against any
|
||||||
embedded 'millesecond delay' escape sequences.
|
* potential embedded 'millesecond delay' escape sequences. */
|
||||||
PUTT - Put to Tty
|
/** PUTT - Put to Tty (used in many places)
|
||||||
. for temporary interactive 'REPLACEMENT' output
|
. for temporary, possibly interactive, 'replacement' output
|
||||||
. may contain ANY valid terminfo escape sequences
|
. may contain ANY valid terminfo escape sequences
|
||||||
. need NOT represent an entire screen row
|
. 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 */
|
|
||||||
#define PUTT(fmt,arg...) do { \
|
#define PUTT(fmt,arg...) do { \
|
||||||
char _str[ROWBUFSIZ]; \
|
char _str[ROWBUFSIZ]; \
|
||||||
snprintf(_str, sizeof(_str), fmt, ## arg); \
|
snprintf(_str, sizeof(_str), fmt, ## arg); \
|
||||||
putp(_str); \
|
putp(_str); \
|
||||||
} while (0)
|
} 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 { \
|
#define PUFF(fmt,arg...) do { \
|
||||||
char _str[ROWBUFSIZ]; \
|
char _str[ROWBUFSIZ]; \
|
||||||
char *_ptr = &Pseudo_scrn[Pseudo_row++ * Pseudo_cols]; \
|
char *_ptr = &Pseudo_scrn[Pseudo_row++ * Pseudo_cols]; \
|
||||||
@ -189,10 +188,8 @@ typedef struct {
|
|||||||
calculations. It exists primarily for SMP support but serves
|
calculations. It exists primarily for SMP support but serves
|
||||||
all environments. */
|
all environments. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// ticks count as represented in /proc/stat
|
TICS_t u, n, s, i, w; // as represented in /proc/stat
|
||||||
TICS_t u, n, s, i, w;
|
TICS_t u_sav, s_sav, n_sav, i_sav, w_sav; // in the order of our display
|
||||||
// tics count in the order of our display
|
|
||||||
TICS_t u_sav, s_sav, n_sav, i_sav, w_sav;
|
|
||||||
} CPUS_t;
|
} CPUS_t;
|
||||||
|
|
||||||
/* The scaling 'type' used with scale_num() -- this is how
|
/* The scaling 'type' used with scale_num() -- this is how
|
||||||
@ -512,6 +509,20 @@ typedef struct win {
|
|||||||
"commands plus the 'G' sub-commands NOW. Press <Enter> to make 'Current' " \
|
"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
|
||||||
|
|
||||||
|
|
||||||
/*###### Some Prototypes (ha!) #########################################*/
|
/*###### Some Prototypes (ha!) #########################################*/
|
||||||
|
|
||||||
@ -521,9 +532,9 @@ typedef struct win {
|
|||||||
* source code navigation, which often influences the identifers. */
|
* source code navigation, which often influences the identifers. */
|
||||||
/*------ Sort callbacks ------------------------------------------------*/
|
/*------ Sort callbacks ------------------------------------------------*/
|
||||||
/* for each possible field, in the form of: */
|
/* 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) */
|
/* 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) ----------------------------------------*/
|
/*------ Tiny useful routine(s) ----------------------------------------*/
|
||||||
//atic int chin (int ech, char *buf, unsigned cnt);
|
//atic int chin (int ech, char *buf, unsigned cnt);
|
||||||
//atic const char *fmtmk (const char *fmts, ...);
|
//atic const char *fmtmk (const char *fmts, ...);
|
||||||
@ -550,7 +561,7 @@ typedef struct win {
|
|||||||
/*------ Library Alternatives ------------------------------------------*/
|
/*------ Library Alternatives ------------------------------------------*/
|
||||||
//atic void *alloc_c (unsigned numb) MALLOC;
|
//atic void *alloc_c (unsigned numb) MALLOC;
|
||||||
//atic void *alloc_r (void *q, 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 void prochlp (proc_t *this);
|
||||||
//atic proc_t **procs_refresh (proc_t **table, int flags);
|
//atic proc_t **procs_refresh (proc_t **table, int flags);
|
||||||
/*------ Startup routines ----------------------------------------------*/
|
/*------ Startup routines ----------------------------------------------*/
|
||||||
@ -559,7 +570,7 @@ typedef struct win {
|
|||||||
//atic void parse_args (char **args);
|
//atic void parse_args (char **args);
|
||||||
//atic void whack_terminal (void);
|
//atic void whack_terminal (void);
|
||||||
/*------ Field Selection/Ordering routines -----------------------------*/
|
/*------ Field Selection/Ordering routines -----------------------------*/
|
||||||
/*atic FTAB_t Fieldstab[] = { ... } */
|
/*atic FTAB_t Fieldstab[] = { ... } */
|
||||||
//atic void display_fields (const char *fields, const char *xtra);
|
//atic void display_fields (const char *fields, const char *xtra);
|
||||||
//atic void fields_reorder (void);
|
//atic void fields_reorder (void);
|
||||||
//atic void fields_sort (void);
|
//atic void fields_sort (void);
|
||||||
@ -577,19 +588,14 @@ typedef struct win {
|
|||||||
//atic void windows_stage2 (void);
|
//atic void windows_stage2 (void);
|
||||||
/*------ Main Screen routines ------------------------------------------*/
|
/*------ Main Screen routines ------------------------------------------*/
|
||||||
//atic void do_key (unsigned c);
|
//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 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);
|
//atic void window_show (proc_t **ppt, WIN_t *q, int *lscr);
|
||||||
/*------ Entry point plus two ------------------------------------------*/
|
/*------ Entry point plus two ------------------------------------------*/
|
||||||
//atic void framehlp (int wix, int max);
|
//atic void framehlp (int wix, int max);
|
||||||
//atic void frame_make (void);
|
//atic void frame_make (void);
|
||||||
// int main (int dont_care_argc, char **argv);
|
// 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 */
|
#endif /* _Itop */
|
||||||
|
|
||||||
|
422
watch.c
422
watch.c
@ -8,7 +8,6 @@
|
|||||||
* Mike Coleman <mkc@acm.org>.
|
* Mike Coleman <mkc@acm.org>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "0.2.0"
|
#define VERSION "0.2.0"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -23,263 +22,252 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
static struct option longopts[] =
|
static struct option longopts[] = {
|
||||||
{
|
{"differences", optional_argument, 0, 'd'},
|
||||||
{ "differences", optional_argument, 0, 'd' },
|
{"help", no_argument, 0, 'h'},
|
||||||
{ "help", no_argument, 0, 'h' },
|
{"interval", required_argument, 0, 'n'},
|
||||||
{ "interval", required_argument, 0, 'n' },
|
{"version", no_argument, 0, 'v'},
|
||||||
{ "version", no_argument, 0, 'v' },
|
{0, 0, 0, 0}
|
||||||
{ 0, 0, 0, 0 }
|
};
|
||||||
};
|
|
||||||
|
|
||||||
static char usage[] = "Usage: %s [-dhnv] [--differences[=cumulative]] [--help] [--interval=<n>] [--version] <command>\n";
|
|
||||||
|
|
||||||
|
static char usage[] =
|
||||||
|
"Usage: %s [-dhnv] [--differences[=cumulative]] [--help] [--interval=<n>] [--version] <command>\n";
|
||||||
|
|
||||||
static char *progname;
|
static char *progname;
|
||||||
|
|
||||||
static int curses_started = 0;
|
static int curses_started = 0;
|
||||||
static int height=24, width=80;
|
static int height = 24, width = 80;
|
||||||
static int screen_size_changed=0;
|
static int screen_size_changed = 0;
|
||||||
static int first_screen=1;
|
static int first_screen = 1;
|
||||||
|
|
||||||
|
|
||||||
#define min(x,y) ((x) > (y) ? (y) : (x))
|
#define min(x,y) ((x) > (y) ? (y) : (x))
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_usage(void)
|
do_usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, usage, progname);
|
fprintf(stderr, usage, progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_exit(int status) {
|
do_exit(int status)
|
||||||
if (curses_started)
|
{
|
||||||
endwin();
|
if (curses_started)
|
||||||
exit(status);
|
endwin();
|
||||||
|
exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* signal handler */
|
/* signal handler */
|
||||||
static void
|
static void
|
||||||
die(int notused)
|
die(int notused)
|
||||||
{
|
{
|
||||||
(void)notused;
|
(void) notused;
|
||||||
do_exit(0);
|
do_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
winch_handler(int notused)
|
winch_handler(int notused)
|
||||||
{
|
{
|
||||||
(void)notused;
|
(void) notused;
|
||||||
screen_size_changed = 1;
|
screen_size_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_terminal_size(void)
|
get_terminal_size(void)
|
||||||
{
|
{
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
if (ioctl(2, TIOCGWINSZ, &w) == 0)
|
if (ioctl(2, TIOCGWINSZ, &w) == 0) {
|
||||||
{
|
if (w.ws_row > 0)
|
||||||
if (w.ws_row > 0)
|
height = w.ws_row;
|
||||||
height = w.ws_row;
|
if (w.ws_col > 0)
|
||||||
if (w.ws_col > 0)
|
width = w.ws_col;
|
||||||
width = w.ws_col;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int optc;
|
int optc;
|
||||||
int option_differences=0,
|
int option_differences = 0,
|
||||||
option_differences_cumulative=0,
|
option_differences_cumulative = 0,
|
||||||
option_help=0,
|
option_help = 0, option_version = 0;
|
||||||
option_version=0;
|
int interval = 2;
|
||||||
int interval=2;
|
char *command;
|
||||||
char *command;
|
int command_length = 0; /* not including final \0 */
|
||||||
int command_length=0; /* not including final \0 */
|
|
||||||
|
|
||||||
setlocale(LC_ALL,"");
|
setlocale(LC_ALL, "");
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
|
|
||||||
while ((optc = getopt_long(argc, argv, "+d::hn:v", longopts, (int *) 0))
|
while ((optc = getopt_long(argc, argv, "+d::hn:v", longopts, (int *) 0))
|
||||||
!= EOF)
|
!= EOF) {
|
||||||
{
|
switch (optc) {
|
||||||
switch (optc)
|
case 'd':
|
||||||
{
|
option_differences = 1;
|
||||||
case 'd':
|
if (optarg)
|
||||||
option_differences = 1;
|
option_differences_cumulative = 1;
|
||||||
if (optarg)
|
break;
|
||||||
option_differences_cumulative = 1;
|
case 'h':
|
||||||
break;
|
option_help = 1;
|
||||||
case 'h':
|
break;
|
||||||
option_help = 1;
|
case 'n':
|
||||||
break;
|
{
|
||||||
case 'n':
|
char *str;
|
||||||
{
|
interval = strtol(optarg, &str, 10);
|
||||||
char *str;
|
if (!*optarg || *str)
|
||||||
interval = strtol(optarg, &str, 10);
|
do_usage();
|
||||||
if (!*optarg || *str)
|
}
|
||||||
do_usage();
|
break;
|
||||||
}
|
case 'v':
|
||||||
break;
|
option_version = 1;
|
||||||
case 'v':
|
break;
|
||||||
option_version = 1;
|
default:
|
||||||
break;
|
do_usage();
|
||||||
default:
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pclose(p);
|
if (option_version) {
|
||||||
|
fprintf(stderr, "%s\n", VERSION);
|
||||||
|
if (!option_help)
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
first_screen = 0;
|
if (option_help) {
|
||||||
refresh();
|
fprintf(stderr, usage, progname);
|
||||||
sleep(interval);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
endwin();
|
if (optind >= argc)
|
||||||
|
do_usage();
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(p);
|
||||||
|
|
||||||
|
first_screen = 0;
|
||||||
|
refresh();
|
||||||
|
sleep(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user