From 05f5deb97c454b3558892ff4266efc81547f88d5 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Tue, 20 Dec 2011 08:23:37 -0600 Subject: [PATCH] top: with lib xalloc changes, restored prior memory logic With the privatization of the library xalloc functions, this patch restores top's previous internal memory logic. This puts us back on a 3.3.1 (and earlier) footing wherein memory allocation errors carry these implications: . if top detected, the terminal will be restored prior to an abnormal exit and message . if library detected, the terminal will become corrupted following the message To my knowledge, neither type of memory error has ever occurred during the nine years since top was rewritten. So the issue of restoring the termios structure is probably moot. --- top.c | 47 ++++++++++++++++++++++++++++++++++++----------- top.h | 4 +++- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/top.c b/top.c index 1ccb7a19..76ef9e18 100644 --- a/top.c +++ b/top.c @@ -487,7 +487,7 @@ static void error_exit (const char *str) { /* - * Handle library memory errors ourselves rather than accept a default + * Handle library 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, ...) { @@ -789,7 +789,33 @@ static void show_special (int interact, const char *glob) { if (*glob) PUTT("%.*s", Screen_cols -1, glob); } // end: show_special -/*###### Low Level Keyboard support ####################################*/ +/*###### 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 + /* * This routine isolates ALL user INPUT and ensures that we @@ -1318,7 +1344,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 = realloc(Pseudo_screen, pseudo_max); + Pseudo_screen = alloc_r(Pseudo_screen, pseudo_max); } PSU_CLREOS(0); if (Frames_resize) putp(Cap_clr_scr); @@ -1768,8 +1794,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 */ - if ((cpus = calloc((1 + Cpu_tot),sizeof(CPU_t)))==NULL) - error_exit(fmtmk("failed to allocate memory for CPU_t")); + cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t)); } rewind(fp); fflush(fp); @@ -1920,8 +1945,8 @@ static void prochlp (proc_t *this) { if (Frame_maxtask+1 >= HHist_siz) { HHist_siz = HHist_siz * 5 / 4 + 100; - PHist_sav = realloc(PHist_sav, sizeof(HST_t) * HHist_siz); - PHist_new = realloc(PHist_new, sizeof(HST_t) * HHist_siz); + PHist_sav = alloc_r(PHist_sav, sizeof(HST_t) * HHist_siz); + PHist_new = alloc_r(PHist_new, sizeof(HST_t) * HHist_siz); } /* calculate time in this process; the sum of user time (utime) and @@ -1971,7 +1996,7 @@ static void procs_refresh (void) { for (;;) { if (n_used == n_alloc) { n_alloc = 10 + ((n_alloc * 5) / 4); // grow by over 25% - private_ppt = realloc(private_ppt, sizeof(proc_t*) * n_alloc); + private_ppt = alloc_r(private_ppt, sizeof(proc_t*) * n_alloc); // ensure NULL pointers for the additional memory just acquired memset(private_ppt + n_used, 0, sizeof(proc_t*) * (n_alloc - n_used)); } @@ -1990,7 +2015,7 @@ static void procs_refresh (void) { else { n_saved = n_alloc; for (i = 0; i < GROUPSMAX; i++) { - Winstk[i].ppt = realloc(Winstk[i].ppt, sizeof(proc_t*) * n_alloc); + Winstk[i].ppt = alloc_r(Winstk[i].ppt, sizeof(proc_t*) * n_alloc); memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t*) * n_used); } } @@ -2035,7 +2060,7 @@ static void before (char *me) { struct sigaction sa; int i; - // setup our program name and library error message handler -- big! + // setup our program name -- big! Myname = strrchr(me, '/'); if (Myname) ++Myname; else Myname = me; @@ -3152,7 +3177,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 = realloc(Tree_ppt, sizeof(proc_t*) * hwmsav); + Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav); } while (0 == Seed_ppt[i]->ppid) // identify trees (expect 2) forest_add(i++, 1); // add parent plus children diff --git a/top.h b/top.h index a79286c0..7c649d08 100644 --- a/top.h +++ b/top.h @@ -641,7 +641,9 @@ typedef struct WIN_t { //atic int show_pmt (const char *str); //atic inline void show_scroll (void); //atic void show_special (int interact, const char *glob); -/*------ Low Level Keyboard support ------------------------------------*/ +/*------ Low Level Memory/Keyboard support -----------------------------*/ +//atic void *alloc_c (size_t num); +//atic void *alloc_r (void *ptr, size_t num); //atic int chin (int ech, char *buf, unsigned cnt); //atic int keyin (int init); //atic char *linein (const char *prompt);