]> granicus.if.org Git - procps-ng/commitdiff
top: exploit enhanced library memory allocation provisions
authorJim Warner <james.warner@comcast.net>
Mon, 21 Nov 2011 19:43:17 +0000 (13:43 -0600)
committerCraig Small <csmall@enc.com.au>
Sun, 11 Dec 2011 11:27:27 +0000 (22:27 +1100)
Now that the library allows for customizing the response to
memory allocation errors, it is no longer necessary for top
to provide its own.

This library extension was necessary since top modifies the
termios structure and there would otherwise be no way to
restore the users tty.

top.c
top.h

diff --git a/top.c b/top.c
index cfd0655dae51dcf7f4a47e1cd4dc9987db31f478..0bea0e36e73042ae9b9abd0577962df6d742643a 100644 (file)
--- a/top.c
+++ b/top.c
@@ -39,6 +39,7 @@
 #include <unistd.h>
 #include <values.h>
 
+#include "proc/alloc.h"
 #include "proc/devname.h"
 #include "proc/procps.h"
 #include "proc/readproc.h"
@@ -82,10 +83,6 @@ static const char *Cpu_States_fmts = STATES_line2x4;
 static pid_t Monpids [MONPIDMAX] = { 0 };
 static int   Monpidsidx = 0;
 
-        /* A postponed error message */
-static char Msg_delayed [MEDBUFSIZ];
-static int  Msg_awaiting = 0;
-
         /* Current screen dimensions.
            note: the number of processes displayed is tracked on a per window
                  basis (see the WIN_t).  Max_lines is the total number of
@@ -285,9 +282,9 @@ static inline char *scat (char *dst, const char *src) {
 } // end: scat
 
 
+#ifdef TERMIOS_ONLY
         /*
-         * Trim the rc file lines and any 'open_psdb_message' which arrives
-         * with an inappropriate newline (thanks to 'sysmap_mmap') */
+         * Trim line oriented input */
 static char *strim (char *str) {
    static const char ws[] = "\b\f\n\r\t\v\x1b\x9b";  // 0x1b + 0x9b are escape
    char *p;
@@ -295,6 +292,7 @@ static char *strim (char *str) {
    if ((p = strpbrk(str, ws))) *p = '\0';
    return str;
 } // end: strim
+#endif
 
 
         /*
@@ -489,6 +487,21 @@ static void error_exit (const char *str) {
 } // end: error_exit
 
 
+        /*
+         * Handle library memory errors ourselves rather than accept a default
+         * fprintf to stderr (since we've mucked with the termios struct) */
+static void library_err (const char *fmts, ...) NORETURN;
+static void library_err (const char *fmts, ...) {
+   static char tmp[MEDBUFSIZ];
+   va_list va;
+
+   va_start(va, fmts);
+   vsnprintf(tmp, sizeof(tmp), fmts, va);
+   va_end(va);
+   error_exit(tmp);
+} // end: library_err
+
+
         /*
          * Called in response to Frames_paused (tku: sig_paused) */
 static void pause_pgm (void) {
@@ -631,25 +644,6 @@ static void capsmk (WIN_t *q) {
 } // end: capsmk
 
 
-        /*
-         * Show an error, but not right now.
-         * Due to the postponed opening of ksym, using open_psdb_message,
-         * if P_WCH had been selected and the program is restarted, the
-         * message would otherwise be displayed prematurely. */
-static void msg_save (const char *fmts, ...) __attribute__((format(printf,1,2)));
-static void msg_save (const char *fmts, ...) {
-   char tmp[MEDBUFSIZ];
-   va_list va;
-
-   va_start(va, fmts);
-   vsnprintf(tmp, sizeof(tmp), fmts, va);
-   va_end(va);
-   // we'll add some extra attention grabbers to whatever this is
-   snprintf(Msg_delayed, sizeof(Msg_delayed), "***  %s  ***", strim(tmp));
-   Msg_awaiting = 1;
-} // end: msg_save
-
-
         /*
          * Show an error message (caller may include '\a' for sound) */
 static void show_msg (const char *str) {
@@ -662,7 +656,6 @@ static void show_msg (const char *str) {
       , Cap_clr_eol);
    fflush(stdout);
    usleep(MSG_USLEEP);
-   Msg_awaiting = 0;
 } // end: show_msg
 
 
@@ -797,33 +790,7 @@ static void show_special (int interact, const char *glob) {
    if (*glob) PUTT("%.*s", Screen_cols -1, glob);
 } // end: show_special
 \f
-/*######  Low Level Memory/Keyboard support  #############################*/
-
-        /*
-         * Handle our own memory stuff without the risk of leaving the
-         * user's terminal in an ugly state should things go sour. */
-
-static void *alloc_c (size_t num) MALLOC;
-static void *alloc_c (size_t num) {
-   void *pv;
-
-   if (!num) ++num;
-   if (!(pv = calloc(1, num)))
-      error_exit("failed memory allocate");
-   return pv;
-} // end: alloc_c
-
-
-static void *alloc_r (void *ptr, size_t num) MALLOC;
-static void *alloc_r (void *ptr, size_t num) {
-   void *pv;
-
-   if (!num) ++num;
-   if (!(pv = realloc(ptr, num)))
-      error_exit("failed memory re-allocate");
-   return pv;
-} // end: alloc_r
-
+/*######  Low Level Keyboard support  ####################################*/
 
         /*
          * This routine isolates ALL user INPUT and ensures that we
@@ -1352,7 +1319,7 @@ static void adj_geometry (void) {
    // we'll only grow our Pseudo_screen, never shrink it
    if (pseudo_max < Pseudo_size) {
       pseudo_max = Pseudo_size;
-      Pseudo_screen = alloc_r(Pseudo_screen, pseudo_max);
+      Pseudo_screen = xrealloc(Pseudo_screen, pseudo_max);
    }
    PSU_CLREOS(0);
    if (Frames_resize) putp(Cap_clr_scr);
@@ -1520,7 +1487,7 @@ static void calibrate_fields (void) {
    if (needpsdb) {
       if (-1 == No_ksyms) {
          No_ksyms = 0;
-         if (open_psdb_message(NULL, msg_save))
+         if (open_psdb_message(NULL, library_err))
             No_ksyms = 1;
          else
             PSDBopen = 1;
@@ -1802,7 +1769,7 @@ static CPU_t *cpus_refresh (CPU_t *cpus) {
       /* note: we allocate one more CPU_t than Cpu_tot so that the last slot
                can hold tics representing the /proc/stat cpu summary (the first
                line read) -- that slot supports our View_CPUSUM toggle */
-      cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t));
+      cpus = xcalloc((1 + Cpu_tot) * sizeof(CPU_t));
    }
    rewind(fp);
    fflush(fp);
@@ -1953,8 +1920,8 @@ static void prochlp (proc_t *this) {
 
    if (Frame_maxtask+1 >= HHist_siz) {
       HHist_siz = HHist_siz * 5 / 4 + 100;
-      PHist_sav = alloc_r(PHist_sav, sizeof(HST_t) * HHist_siz);
-      PHist_new = alloc_r(PHist_new, sizeof(HST_t) * HHist_siz);
+      PHist_sav = xrealloc(PHist_sav, sizeof(HST_t) * HHist_siz);
+      PHist_new = xrealloc(PHist_new, sizeof(HST_t) * HHist_siz);
    }
 
    /* calculate time in this process; the sum of user time (utime) and
@@ -2068,9 +2035,10 @@ static void before (char *me) {
    struct sigaction sa;
    int i;
 
-   // setup our program name -- big!
+   // setup our program name and library error message handler -- big!
    Myname = strrchr(me, '/');
    if (Myname) ++Myname; else Myname = me;
+   xalloc_err_handler = library_err;
 
    // establish cpu particulars -- even bigger!
 #ifdef PRETEND4CPUS
@@ -3133,7 +3101,7 @@ static void forest_create (WIN_t *q) {
       qsort(Seed_ppt, Frame_maxtask, sizeof(proc_t*), Fieldstab[P_PPD].sort);
       if (hwmsav < Frame_maxtask) {         // grow, but never shrink
          hwmsav = Frame_maxtask;
-         Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav);
+         Tree_ppt = xrealloc(Tree_ppt, sizeof(proc_t*) * hwmsav);
       }
       while (0 == Seed_ppt[i]->ppid)        // identify trees (expect 2)
          forest_add(i++, 1);                // add parent plus children
@@ -3722,7 +3690,6 @@ int main (int dont_care_argc, char **argv) {
 
       frame_make();
 
-      if (Msg_awaiting) show_msg(Msg_delayed);
       if (0 < Loops) --Loops;
       if (!Loops) bye_bye(NULL);
 
diff --git a/top.h b/top.h
index a409c61a3d44e2571f04131c2439c173f64d07b6..9dd133aa5b70ee38070bdd7d14ebcae919938cac 100644 (file)
--- a/top.h
+++ b/top.h
@@ -375,6 +375,7 @@ typedef struct WIN_t {
       return Frame_srtflg * ( (*Q)->n - (*P)->n ); }
 #define SCB_STRS(f,s) \
    static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
+      if (!(*P)->s || !(*Q)->s) return SORT_eq; \
       return Frame_srtflg * STRSORTCMP((*Q)->s, (*P)->s); }
 #define SCB_STRV(f,b,v,s) \
    static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
@@ -385,6 +386,7 @@ typedef struct WIN_t {
 #define SCB_STRX(f,s) \
    int strverscmp(const char *s1, const char *s2); \
    static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
+      if (!(*P)->s || !(*Q)->s) return SORT_eq; \
       return Frame_srtflg * strverscmp((*Q)->s, (*P)->s); }
 
 /*
@@ -618,11 +620,14 @@ typedef struct WIN_t {
 /*------  Tiny useful routine(s)  ----------------------------------------*/
 //atic const char   *fmtmk (const char *fmts, ...);
 //atic inline char  *scat (char *dst, const char *src);
+#ifdef TERMIOS_ONLY
 //atic char         *strim (char *str);
+#endif
 //atic const char   *tg2 (int x, int y);
 /*------  Exit/Interrput routines  ---------------------------------------*/
 //atic void          bye_bye (const char *str);
 //atic void          error_exit (const char *str);
+//atic void          library_err (const char *fmts, ...);
 //atic void          pause_pgm (void);
 //atic void          sig_abexit (int sig);
 //atic void          sig_endpgm (int dont_care_sig);
@@ -630,14 +635,11 @@ typedef struct WIN_t {
 //atic void          sig_resize (int dont_care_sig);
 /*------  Misc Color/Display support  ------------------------------------*/
 //atic void          capsmk (WIN_t *q);
-//atic void          msg_save (const char *fmts, ...);
 //atic void          show_msg (const char *str);
 //atic int           show_pmt (const char *str);
 //atic inline void   show_scroll (void);
 //atic void          show_special (int interact, const char *glob);
-/*------  Low Level Memory/Keyboard support  -----------------------------*/
-//atic void         *alloc_c (size_t num);
-//atic void         *alloc_r (void *ptr, size_t num);
+/*------  Low Level Keyboard support  ------------------------------------*/
 //atic int           chin (int ech, char *buf, unsigned cnt);
 //atic int           keyin (int init);
 //atic char         *linein (const char *prompt);