]> granicus.if.org Git - procps-ng/commitdiff
top: provides a new user 'message log' display ability
authorJim Warner <james.warner@comcast.net>
Thu, 2 Jun 2022 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Sun, 5 Jun 2022 11:11:38 +0000 (21:11 +1000)
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>
top/top.c
top/top.h
top/top_nls.c
top/top_nls.h

index 56d785be6f1c8ec9ea1f9723a444f819e2a4ba67..3ec422f48a71fb64d296bfc3e11cd633581e51df 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -105,14 +105,17 @@ static int   Screen_cols, Screen_rows, Max_lines;
         /* These 'SCREEN_ROWS', 'BOT_ and 'Bot_' guys are used
            in managing the special separate bottom 'window' ... */
 #define      SCREEN_ROWS ( Screen_rows - Bot_rsvd )
-#define      BOT_MAXIMUM  10           // Bot_item array's max size
-#define      BOT_DELIMIT  -1           // fencepost with item array
+#define      BOT_ITEMMAX  10           // Bot_item array's max size
+#define      BOT_MSGSMAX  10           // total entries for Msg_tab
 #define      BOT_UNFOCUS  -1           // tab focus not established
-        // a negative 'item' won't be seen by build_headers() ...
+        // negative 'item' values won't be seen by build_headers() ...
+#define      BOT_DELIMIT  -1           // fencepost with item array
 #define      BOT_ITEM_NS  -2           // data for namespaces req'd
+#define      BOT_MSG_LOG  -3           // show the most recent msgs
         // next 4 are used when toggling window contents
 #define      BOT_SEP_CMA  ','
 #define      BOT_SEP_SLS  '/'
+#define      BOT_SEP_SMI  ';'
 #define      BOT_SEP_SPC  ' '
         // 1 for horizontal separator
 #define      BOT_RSVD  1
@@ -125,7 +128,7 @@ static int   Bot_task,
              Bot_what,
              Bot_rsvd,
              Bot_indx = BOT_UNFOCUS,
-             Bot_item[BOT_MAXIMUM] = { BOT_DELIMIT };
+             Bot_item[BOT_ITEMMAX] = { BOT_DELIMIT };
 static char  Bot_sep,
             *Bot_head,
              Bot_buf[BOTBUFSIZ];       // the 'environ' can be huge
@@ -843,9 +846,19 @@ static void capsmk (WIN_t *q) {
 } // 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) */
 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"
       , tg2(0, Msg_row)
       , Curwin->capclr_msg
@@ -4619,6 +4632,10 @@ static void wins_stage_1 (void) {
    Winstk[GROUPSMAX - 1].next = &Winstk[0];
    Winstk[0].prev = &Winstk[GROUPSMAX - 1];
    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
 
 
@@ -4937,7 +4954,7 @@ static void bot_do (const char *str, int focus) {
          * ( returns relative # of elements printed ) | */
 static int bot_focus_str (const char *hdr, const char *str) {
  #define maxRSVD ( Screen_rows - 1 )
-   const char *end, *beg;
+   char *beg, *end;
    char tmp[BIGBUFSIZ];
    int n, x;
 
@@ -5050,9 +5067,25 @@ static struct {
 static void *bot_item_hlp (struct pids_stack *p) {
    static char buf[BIGBUFSIZ];
    char tmp[SMLBUFSIZ], *b;
+   struct msg_node *m;
    int i;
 
    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 BOT_ITEM_NS:
          *(b = &buf[0]) = '\0';
          for (i = 0; i < MAXTBL(ns_tab); i++) {
@@ -5528,6 +5561,9 @@ static void keys_global (int ch) {
          // with string vectors, the 'separator' may serve a different purpose
          bot_item_toggle(eu_CMDLINE_V, N_fmt(X_BOT_cmdlin_fmt), BOT_SEP_SPC);
          break;
+      case kbd_CtrlL:
+         bot_item_toggle(BOT_MSG_LOG, N_txt(X_BOT_msglog_txt), BOT_SEP_SMI);
+         break;
       case kbd_CtrlN:
          // with string vectors, the 'separator' may serve a different purpose
          bot_item_toggle(eu_ENVIRON_V, N_fmt(X_BOT_envirn_fmt), BOT_SEP_SPC);
@@ -6412,7 +6448,7 @@ static void do_key (int ch) {
       { keys_global,
          { '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
          , '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_CtrlR, kbd_CtrlU
          , kbd_ENTER, kbd_SPACE, kbd_BTAB, '\0' } },
       { keys_summary,
index ef0ce188a3d74ce4cfc861b3f4c952657090879d..78ecdac041341c306ba714f254fa36a5bcf0271b 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -180,6 +180,7 @@ char *strcasestr(const char *haystack, const char *needle);
 #define kbd_CtrlG  '\007'
 #define kbd_CtrlI  '\011'
 #define kbd_CtrlK  '\013'
+#define kbd_CtrlL  '\014'
 #define kbd_CtrlN  '\016'
 #define kbd_CtrlO  '\017'
 #define kbd_CtrlP  '\020'
index 668836aa0083904d444308aa1ecfeef9907e2cbd..e539c5c03f06a67abc38ea9fc2d4f13c6620905d 100644 (file)
@@ -596,6 +596,7 @@ static void build_norm_nlstab (void) {
    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_supgrp_fmt] = _("supplementary groups for pid %d, %s");
+   Norm_nlstab[X_BOT_msglog_txt] = _("message log, last 10 messages:");
 }
 
 
index 73e6c71607ab1e3ca8f217069a9a10e84d632bf1..6a116ccb0d4287d184bcc511d2964109dce7d97c 100644 (file)
@@ -85,8 +85,9 @@ enum norm_nls {
    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_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_supgrp_fmt, X_RESTRICTED_txt, X_SEMAPHORES_fmt, X_THREADINGS_fmt,
+   X_BOT_cmdlin_fmt, X_BOT_ctlgrp_fmt, X_BOT_envirn_fmt, X_BOT_msglog_txt,
+   X_BOT_namesp_fmt, X_BOT_supgrp_fmt, X_RESTRICTED_txt, X_SEMAPHORES_fmt,
+   X_THREADINGS_fmt,
    YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
    YINSP_deqtyp_txt, YINSP_dstory_txt,
    YINSP_failed_fmt, YINSP_noent1_txt, YINSP_noent2_txt, YINSP_pidbad_fmt,