top: provides a new user 'message log' display ability <=== port of newlib 3901dcb9
______________________________ original newlib message Messages issued by top will be displayed for only 1.25 seconds. And while this length of time would appear to be acceptable (given the absence of complaints), there will be times when a specific message might be missed. So, this commit offers users the opportunity to recall up to 10 of the most recent messages that were issued. [ we'll just exploit top's new bottom window feature ] Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
53e72ccef0
commit
da4dc7665b
47
top/top.c
47
top/top.c
@ -115,10 +115,14 @@ static int Screen_cols, Screen_rows, Max_lines;
|
|||||||
/* These 'SCREEN_ROWS', 'BOT_ and 'Bot_' guys are used
|
/* These 'SCREEN_ROWS', 'BOT_ and 'Bot_' guys are used
|
||||||
in managing the special separate bottom 'window' ... */
|
in managing the special separate bottom 'window' ... */
|
||||||
#define SCREEN_ROWS ( Screen_rows - Bot_rsvd )
|
#define SCREEN_ROWS ( Screen_rows - Bot_rsvd )
|
||||||
|
#define BOT_MSGSMAX 10 // total entries for Msg_tab
|
||||||
#define BOT_UNFOCUS -1 // tab focus not established
|
#define BOT_UNFOCUS -1 // tab focus not established
|
||||||
|
// negative 'item' values won't be seen by build_headers() ...
|
||||||
|
#define BOT_MSG_LOG -3 // show the most recent msgs
|
||||||
// next 4 are used when toggling window contents
|
// next 4 are used when toggling window contents
|
||||||
#define BOT_SEP_CMA ','
|
#define BOT_SEP_CMA ','
|
||||||
#define BOT_SEP_SLS '/'
|
#define BOT_SEP_SLS '/'
|
||||||
|
#define BOT_SEP_SMI ';'
|
||||||
#define BOT_SEP_SPC ' '
|
#define BOT_SEP_SPC ' '
|
||||||
// 1 for horizontal separator
|
// 1 for horizontal separator
|
||||||
#define BOT_RSVD 1
|
#define BOT_RSVD 1
|
||||||
@ -921,9 +925,19 @@ static void capsmk (WIN_t *q) {
|
|||||||
} // end: capsmk
|
} // end: capsmk
|
||||||
|
|
||||||
|
|
||||||
|
static struct msg_node {
|
||||||
|
char msg[SMLBUFSIZ];
|
||||||
|
struct msg_node *prev;
|
||||||
|
} Msg_tab[BOT_MSGSMAX];
|
||||||
|
|
||||||
|
static struct msg_node *Msg_this = Msg_tab;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show an error message (caller may include '\a' for sound) */
|
* Show an error message (caller may include '\a' for sound) */
|
||||||
static void show_msg (const char *str) {
|
static void show_msg (const char *str) {
|
||||||
|
STRLCPY(Msg_this->msg, str);
|
||||||
|
if (++Msg_this > &Msg_tab[BOT_MSGSMAX - 1]) Msg_this = Msg_tab;
|
||||||
|
|
||||||
PUTT("%s%s %.*s %s%s%s"
|
PUTT("%s%s %.*s %s%s%s"
|
||||||
, tg2(0, Msg_row)
|
, tg2(0, Msg_row)
|
||||||
, Curwin->capclr_msg
|
, Curwin->capclr_msg
|
||||||
@ -2156,13 +2170,15 @@ static void build_headers (void) {
|
|||||||
// for 'U' filtering we need the other user ids too
|
// for 'U' filtering we need the other user ids too
|
||||||
if (w->usrseltyp == 'U') Frames_libflags |= L_status;
|
if (w->usrseltyp == 'U') Frames_libflags |= L_status;
|
||||||
|
|
||||||
// lastly, accommodate any special non-display 'tagged' needs...
|
|
||||||
Frames_libflags |= Bot_what;
|
|
||||||
} // end: VIZISw(w)
|
} // end: VIZISw(w)
|
||||||
|
|
||||||
if (Rc.mode_altscr) w = w->next;
|
if (Rc.mode_altscr) w = w->next;
|
||||||
} while (w != Curwin);
|
} while (w != Curwin);
|
||||||
|
|
||||||
|
// lastly, accommodate any special bottom window needs...
|
||||||
|
if (Bot_what > 0)
|
||||||
|
Frames_libflags |= Bot_what;
|
||||||
|
|
||||||
#ifdef EQUCOLHDRYES
|
#ifdef EQUCOLHDRYES
|
||||||
/* now we can finally even out column header lengths
|
/* now we can finally even out column header lengths
|
||||||
(we're assuming entire columnhdr was memset to '\0') */
|
(we're assuming entire columnhdr was memset to '\0') */
|
||||||
@ -4807,6 +4823,10 @@ static void wins_stage_1 (void) {
|
|||||||
Winstk[GROUPSMAX - 1].next = &Winstk[0];
|
Winstk[GROUPSMAX - 1].next = &Winstk[0];
|
||||||
Winstk[0].prev = &Winstk[GROUPSMAX - 1];
|
Winstk[0].prev = &Winstk[GROUPSMAX - 1];
|
||||||
Curwin = Winstk;
|
Curwin = Winstk;
|
||||||
|
|
||||||
|
for (i = 1; i < BOT_MSGSMAX; i++)
|
||||||
|
Msg_tab[i].prev = &Msg_tab[i - 1];
|
||||||
|
Msg_tab[0].prev = &Msg_tab[BOT_MSGSMAX -1];
|
||||||
} // end: wins_stage_1
|
} // end: wins_stage_1
|
||||||
|
|
||||||
|
|
||||||
@ -5117,7 +5137,7 @@ static void bot_do (const char *str, int focus) {
|
|||||||
* ( returns relative # of elements printed ) | */
|
* ( returns relative # of elements printed ) | */
|
||||||
static int bot_focus_str (const char *hdr, const char *str) {
|
static int bot_focus_str (const char *hdr, const char *str) {
|
||||||
#define maxRSVD ( Screen_rows - 1 )
|
#define maxRSVD ( Screen_rows - 1 )
|
||||||
const char *end, *beg;
|
char *beg, *end;
|
||||||
char tmp[BIGBUFSIZ];
|
char tmp[BIGBUFSIZ];
|
||||||
int n, x;
|
int n, x;
|
||||||
|
|
||||||
@ -5221,10 +5241,26 @@ static void *bot_item_hlp (proc_t *p) {
|
|||||||
IPCNS, MNTNS, NETNS, PIDNS, USERNS, UTSNS };
|
IPCNS, MNTNS, NETNS, PIDNS, USERNS, UTSNS };
|
||||||
static char buf[BIGBUFSIZ];
|
static char buf[BIGBUFSIZ];
|
||||||
char tmp[SMLBUFSIZ], *b;
|
char tmp[SMLBUFSIZ], *b;
|
||||||
|
struct msg_node *m;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
switch (Bot_what) {
|
switch (Bot_what) {
|
||||||
|
case BOT_MSG_LOG:
|
||||||
|
*(b = &buf[0]) = '\0';
|
||||||
|
m = Msg_this->prev;
|
||||||
|
do {
|
||||||
|
if (m->msg[0]) {
|
||||||
|
b = scat(b, m->msg);
|
||||||
|
if (m != Msg_this && m->prev->msg[0]) {
|
||||||
|
// caller itself may have used fmtmk, so we'll old school it ...
|
||||||
|
snprintf(tmp, sizeof(tmp), "%c ", BOT_SEP_SMI);
|
||||||
|
b = scat(b, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m = m->prev;
|
||||||
|
} while (m != Msg_this->prev);
|
||||||
|
return buf;
|
||||||
case (L_NS):
|
case (L_NS):
|
||||||
b = &buf[0];
|
b = &buf[0];
|
||||||
for (i = 0; i < MAXTBL(ns_tab); i++) {
|
for (i = 0; i < MAXTBL(ns_tab); i++) {
|
||||||
@ -5687,6 +5723,9 @@ static void keys_global (int ch) {
|
|||||||
// with string vectors, the 'separator' may serve a different purpose
|
// with string vectors, the 'separator' may serve a different purpose
|
||||||
bot_item_toggle(PROC_FILLARG, N_fmt(X_BOT_cmdlin_fmt), BOT_SEP_SPC);
|
bot_item_toggle(PROC_FILLARG, N_fmt(X_BOT_cmdlin_fmt), BOT_SEP_SPC);
|
||||||
break;
|
break;
|
||||||
|
case kbd_CtrlL:
|
||||||
|
bot_item_toggle(BOT_MSG_LOG, N_txt(X_BOT_msglog_txt), BOT_SEP_SMI);
|
||||||
|
break;
|
||||||
case kbd_CtrlN:
|
case kbd_CtrlN:
|
||||||
// with string vectors, the 'separator' may serve a different purpose
|
// with string vectors, the 'separator' may serve a different purpose
|
||||||
bot_item_toggle(PROC_FILLENV, N_fmt(X_BOT_envirn_fmt), BOT_SEP_SPC);
|
bot_item_toggle(PROC_FILLENV, N_fmt(X_BOT_envirn_fmt), BOT_SEP_SPC);
|
||||||
@ -6518,7 +6557,7 @@ static void do_key (int ch) {
|
|||||||
{ keys_global,
|
{ keys_global,
|
||||||
{ '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
|
{ '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
|
||||||
, 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
|
, 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
|
||||||
, kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK
|
, kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK, kbd_CtrlL
|
||||||
, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
|
, kbd_CtrlN, kbd_CtrlP, kbd_CtrlU
|
||||||
, kbd_ENTER, kbd_SPACE, kbd_BTAB, '\0' } },
|
, kbd_ENTER, kbd_SPACE, kbd_BTAB, '\0' } },
|
||||||
{ keys_summary,
|
{ keys_summary,
|
||||||
|
@ -192,6 +192,7 @@ char *strcasestr(const char *haystack, const char *needle);
|
|||||||
#define kbd_CtrlG '\007'
|
#define kbd_CtrlG '\007'
|
||||||
#define kbd_CtrlI '\011'
|
#define kbd_CtrlI '\011'
|
||||||
#define kbd_CtrlK '\013'
|
#define kbd_CtrlK '\013'
|
||||||
|
#define kbd_CtrlL '\014'
|
||||||
#define kbd_CtrlN '\016'
|
#define kbd_CtrlN '\016'
|
||||||
#define kbd_CtrlO '\017'
|
#define kbd_CtrlO '\017'
|
||||||
#define kbd_CtrlP '\020'
|
#define kbd_CtrlP '\020'
|
||||||
|
@ -529,6 +529,7 @@ static void build_norm_nlstab (void) {
|
|||||||
Norm_nlstab[X_BOT_envirn_fmt] = _("environment for pid %d, %s");
|
Norm_nlstab[X_BOT_envirn_fmt] = _("environment for pid %d, %s");
|
||||||
Norm_nlstab[X_BOT_namesp_fmt] = _("namespaces for pid %d, %s");
|
Norm_nlstab[X_BOT_namesp_fmt] = _("namespaces for pid %d, %s");
|
||||||
Norm_nlstab[X_BOT_supgrp_fmt] = _("supplementary groups for pid %d, %s");
|
Norm_nlstab[X_BOT_supgrp_fmt] = _("supplementary groups for pid %d, %s");
|
||||||
|
Norm_nlstab[X_BOT_msglog_txt] = _("message log, last 10 messages:");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,8 +84,8 @@ enum norm_nls {
|
|||||||
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
|
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
|
||||||
XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_modebad_txt, XTRA_size2up_txt,
|
XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_modebad_txt, XTRA_size2up_txt,
|
||||||
XTRA_vforest_fmt, XTRA_warncfg_txt, XTRA_warnold_txt, XTRA_winsize_txt,
|
XTRA_vforest_fmt, XTRA_warncfg_txt, XTRA_warnold_txt, XTRA_winsize_txt,
|
||||||
X_BOT_cmdlin_fmt, X_BOT_ctlgrp_fmt, X_BOT_envirn_fmt, X_BOT_namesp_fmt,
|
X_BOT_cmdlin_fmt, X_BOT_ctlgrp_fmt, X_BOT_envirn_fmt, X_BOT_msglog_txt,
|
||||||
X_BOT_supgrp_fmt,
|
X_BOT_namesp_fmt, X_BOT_supgrp_fmt,
|
||||||
YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
|
YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
|
||||||
YINSP_deqtyp_txt, YINSP_dstory_txt,
|
YINSP_deqtyp_txt, YINSP_dstory_txt,
|
||||||
YINSP_failed_fmt, YINSP_noent1_txt, YINSP_noent2_txt, YINSP_pidbad_fmt,
|
YINSP_failed_fmt, YINSP_noent1_txt, YINSP_noent2_txt, YINSP_pidbad_fmt,
|
||||||
|
Loading…
Reference in New Issue
Block a user