On Tue, Mar 13, 2007 at 06:36:32PM -0700, Jeremiah Orem wrote:
> This patch fixes the top segfault when resizing the terminal to a 
> small size. It does not reallocate memory for every resize.  Instead 
> it only allocates memory if the new window size is larger than the 
> current window size.
It failed to compile:

top.c: In function 'show_special':
top.c:682: error: incompatible type for argument 1 of 'realloc'
top.c:682: error: incompatible types in assignment
top.c:682: warning: assignment discards qualifiers from pointer target type

I'm not sure what is going on here. I'll have a dig around but you might
want to see for yourself too.

-- 
Craig Small      GnuPG:1C1B D893 1418 2AF4 45EE  95CB C76C E5AC 12CA DFA5
http://www.enc.com.au/                             csmall at : enc.com.au
http://www.debian.org/          Debian GNU/Linux, software should be Free 
#! /bin/sh /usr/share/dpatch/dpatch-run
## 20_top_c_resize.dpatch by  <[EMAIL PROTECTED]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Stop top crashing when resizing Closes: #256376

@DPATCH@
diff -urNad procps-3.2.7~/top.c procps-3.2.7/top.c
--- procps-3.2.7~/top.c 2007-05-16 23:04:12.000000000 +1000
+++ procps-3.2.7/top.c  2007-05-16 23:04:13.000000000 +1000
@@ -140,7 +140,7 @@
            are exploited in a macro and represent 90% of our optimization.
            The Stdout_buf is transparent to our code and regardless of whose
            buffer is used, stdout is flushed at frame end or if interactive. */
-static char *Pseudo_scrn;
+static PSEUDO_SCREEN_t Pseudo_scrn;
 static int   Pseudo_row, Pseudo_cols, Pseudo_size;
 #ifndef STDOUT_IOLBF
         // less than stdout's normal buffer but with luck mostly '\n' anyway
@@ -2415,7 +2415,10 @@
    Pseudo_cols = Screen_cols + CLRBUFSIZ + 1;
    if (Batch) Pseudo_size = ROWBUFSIZ + 1;
    else       Pseudo_size = Pseudo_cols * Screen_rows;
-   Pseudo_scrn = alloc_r(Pseudo_scrn, Pseudo_size);
+   if( Pseudo_scrn.buf == NULL || Pseudo_size > Pseudo_scrn.mem_size ) {
+      Pseudo_scrn.buf = alloc_r(Pseudo_scrn.buf, Pseudo_size);
+      Pseudo_scrn.mem_size = Pseudo_size;
+   }
 
    // force rebuild of column headers AND libproc/readproc requirements
    Frames_libflags = 0;
@@ -3289,7 +3292,7 @@
    //       reframewins(), who also builds each window's column headers
    if (!Frames_libflags) {
       reframewins();
-      memset(Pseudo_scrn, '\0', Pseudo_size);
+      memset(Pseudo_scrn.buf, '\0', Pseudo_size);
    }
    Pseudo_row = Msg_row = scrlins = 0;
    ppt = summary_show();
diff -urNad procps-3.2.7~/top.h procps-3.2.7/top.h
--- procps-3.2.7~/top.h 2007-05-16 23:03:55.000000000 +1000
+++ procps-3.2.7/top.h  2007-05-16 23:04:50.000000000 +1000
@@ -135,7 +135,7 @@
    int _len = 1 + snprintf(_str, sizeof(_str), fmt, ## arg);   \
    putp ( Batch ? _str :                                   \
    ({                                                 \
-      char *restrict const _pse = &Pseudo_scrn[Pseudo_row++ * Pseudo_cols];  \
+      char *restrict const _pse = &Pseudo_scrn.buf[Pseudo_row++ * 
Pseudo_cols];  \
       memcmp(_pse, _str, _len) ? memcpy(_pse, _str, _len) : "\n";  \
    })                                \
    );                   \
@@ -149,7 +149,9 @@
    int _len = 1 + snprintf(_str, sizeof(_str), fmt, ## arg);   \
    if (Batch) _ptr = _str;                                   \
    else {                                                 \
-      _ptr = &Pseudo_scrn[Pseudo_row++ * Pseudo_cols];  \
+      if (Pseudo_row * Pseudo_cols + _len > Pseudo_size) \
+         Pseudo_scrn = realloc(Pseudo_scrn,Pseudo_row * Pseudo_cols + _len); \
+      _ptr = &Pseudo_scrn.buf[Pseudo_row++ * Pseudo_cols];  \
       if (memcmp(_ptr, _str, _len)) {                \
          memcpy(_ptr, _str, _len);                \
       } else {                                 \
@@ -237,6 +239,11 @@
    RCW_t  win [4];              // a 'WIN_t.rc' for each of the 4 windows
 } RCF_t;
 
+typedef struct PSEUDO_SCREEN_t {
+   char *buf;
+   int mem_size;
+} PSEUDO_SCREEN_t;
+
 // The scaling 'type' used with scale_num() -- this is how
 // the passed number is interpreted should scaling be necessary
 enum scale_num {

Reply via email to