View | Details | Raw Unified | Return to bug 225232 | Differences between
and this patch

Collapse All | Expand All

(-)sysutils/htop/Makefile (-1 / +3 lines)
Lines 3-8 Link Here
3
3
4
PORTNAME=	htop
4
PORTNAME=	htop
5
PORTVERSION=	2.0.2
5
PORTVERSION=	2.0.2
6
PORTREVISION=	1
6
CATEGORIES=	sysutils
7
CATEGORIES=	sysutils
7
8
8
MAINTAINER=	gaod@hychen.org
9
MAINTAINER=	gaod@hychen.org
Lines 15-23 Link Here
15
LIBS+=		-lexecinfo
16
LIBS+=		-lexecinfo
16
17
17
CONFIGURE_ARGS=	--enable-unicode
18
CONFIGURE_ARGS=	--enable-unicode
18
USES=		autoreconf libtool ncurses
19
USES=		autoreconf libtool ncurses python:2.7,build shebangfix
19
USE_GITHUB=	yes
20
USE_GITHUB=	yes
20
GH_ACCOUNT=	hishamhm
21
GH_ACCOUNT=	hishamhm
22
SHEBANG_FILES=	scripts/MakeHeader.py
21
PLIST_FILES=	bin/htop \
23
PLIST_FILES=	bin/htop \
22
		man/man1/htop.1.gz \
24
		man/man1/htop.1.gz \
23
		share/applications/htop.desktop \
25
		share/applications/htop.desktop \
(-)sysutils/htop/files/patch-Action.c (+43 lines)
Line 0 Link Here
1
--- Action.c.orig	2018-01-17 02:13:00.581511000 +0800
2
+++ Action.c	2018-01-17 03:18:10.503362000 +0800
3
@@ -142,7 +142,7 @@
4
    pid_t ppid = parent->pid;
5
    for (int i = 0; i < Panel_size(panel); i++) {
6
       Process* p = (Process*) Panel_get(panel, i);
7
-      if (!p->tag && p->ppid == ppid) {
8
+      if (!p->tag && Process_isChildOf(p, ppid)) {
9
          tagAllChildren(panel, p);
10
       }
11
    }
12
@@ -381,7 +381,7 @@
13
    return HTOP_REFRESH | HTOP_REDRAW_BAR;
14
 }
15
 
16
-static struct { const char* key; const char* info; } helpLeft[] = {
17
+static const struct { const char* key; const char* info; } helpLeft[] = {
18
    { .key = " Arrows: ", .info = "scroll process list" },
19
    { .key = " Digits: ", .info = "incremental PID search" },
20
    { .key = "   F3 /: ", .info = "incremental name search" },
21
@@ -395,11 +395,11 @@
22
    { .key = " F6 + -: ", .info = "expand/collapse tree" },
23
    { .key = "  P M T: ", .info = "sort by CPU%, MEM% or TIME" },
24
    { .key = "      I: ", .info = "invert sort order" },
25
-   { .key = "   F6 >: ", .info = "select sort column" },
26
+   { .key = " F6 > .: ", .info = "select sort column" },
27
    { .key = NULL, .info = NULL }
28
 };
29
 
30
-static struct { const char* key; const char* info; } helpRight[] = {
31
+static const struct { const char* key; const char* info; } helpRight[] = {
32
    { .key = "  Space: ", .info = "tag process" },
33
    { .key = "      c: ", .info = "tag process and its children" },
34
    { .key = "      U: ", .info = "untag all processes" },
35
@@ -414,7 +414,7 @@
36
    { .key = "      l: ", .info = "list open files with lsof" },
37
    { .key = "      s: ", .info = "trace syscalls with strace" },
38
    { .key = "         ", .info = "" },
39
-   { .key = "   F2 S: ", .info = "setup" },
40
+   { .key = " F2 C S: ", .info = "setup" },
41
    { .key = "   F1 h: ", .info = "show this help screen" },
42
    { .key = "  F10 q: ", .info = "quit" },
43
    { .key = NULL, .info = NULL }
(-)sysutils/htop/files/patch-AffinityPanel.c (+11 lines)
Line 0 Link Here
1
--- AffinityPanel.c.orig	2018-01-17 02:53:40.133350000 +0800
2
+++ AffinityPanel.c	2018-01-17 02:53:51.453663000 +0800
3
@@ -52,7 +52,7 @@
4
    int curCpu = 0;
5
    for (int i = 0; i < pl->cpuCount; i++) {
6
       char number[10];
7
-      snprintf(number, 9, "%d", Settings_cpuId(pl->settings, i));
8
+      xSnprintf(number, 9, "%d", Settings_cpuId(pl->settings, i));
9
       bool mode;
10
       if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
11
          mode = true;
(-)sysutils/htop/files/patch-AvailableColumnsPanel.c (+20 lines)
Line 0 Link Here
1
--- AvailableColumnsPanel.c.orig	2018-01-17 02:27:39.324359000 +0800
2
+++ AvailableColumnsPanel.c	2018-01-17 02:54:25.008472000 +0800
3
@@ -26,7 +26,7 @@
4
 
5
 }*/
6
 
7
-static const char* AvailableColumnsFunctions[] = {"      ", "      ", "      ", "      ", "Add   ", "      ", "      ", "      ", "      ", "Done  ", NULL};
8
+static const char* const AvailableColumnsFunctions[] = {"      ", "      ", "      ", "      ", "Add   ", "      ", "      ", "      ", "      ", "Done  ", NULL};
9
 
10
 static void AvailableColumnsPanel_delete(Object* object) {
11
    Panel* super = (Panel*) object;
12
@@ -81,7 +81,7 @@
13
    for (int i = 1; i < Platform_numberOfFields; i++) {
14
       if (i != COMM && Process_fields[i].description) {
15
          char description[256];
16
-         snprintf(description, sizeof(description), "%s - %s", Process_fields[i].name, Process_fields[i].description);
17
+         xSnprintf(description, sizeof(description), "%s - %s", Process_fields[i].name, Process_fields[i].description);
18
          Panel_add(super, (Object*) ListItem_new(description, i));
19
       }
20
    }
(-)sysutils/htop/files/patch-AvailableMetersPanel.c (+11 lines)
Line 0 Link Here
1
--- AvailableMetersPanel.c.orig	2018-01-17 02:54:40.714904000 +0800
2
+++ AvailableMetersPanel.c	2018-01-17 02:54:53.533751000 +0800
3
@@ -127,7 +127,7 @@
4
       Panel_add(super, (Object*) ListItem_new("CPU average", 0));
5
       for (int i = 1; i <= cpus; i++) {
6
          char buffer[50];
7
-         snprintf(buffer, 50, "%s %d", type->uiName, i);
8
+         xSnprintf(buffer, 50, "%s %d", type->uiName, i);
9
          Panel_add(super, (Object*) ListItem_new(buffer, i));
10
       }
11
    } else {
(-)sysutils/htop/files/patch-BatteryMeter.c (+26 lines)
Line 0 Link Here
1
--- BatteryMeter.c.orig	2018-01-17 02:56:48.542038000 +0800
2
+++ BatteryMeter.c	2018-01-17 02:57:28.097399000 +0800
3
@@ -40,7 +40,7 @@
4
 
5
    if (percent == -1) {
6
       this->values[0] = 0;
7
-      snprintf(buffer, len, "n/a");
8
+      xSnprintf(buffer, len, "n/a");
9
       return;
10
    }
11
 
12
@@ -58,11 +58,11 @@
13
    }
14
 
15
    if (isOnAC == AC_PRESENT) {
16
-      snprintf(buffer, len, onAcText, percent);
17
+      xSnprintf(buffer, len, onAcText, percent);
18
    } else if (isOnAC == AC_ABSENT) {
19
-      snprintf(buffer, len, onBatteryText, percent);
20
+      xSnprintf(buffer, len, onBatteryText, percent);
21
    } else {
22
-      snprintf(buffer, len, unknownText, percent);
23
+      xSnprintf(buffer, len, unknownText, percent);
24
    }
25
 
26
    return;
(-)sysutils/htop/files/patch-CPUMeter.c (+82 lines)
Line 0 Link Here
1
--- CPUMeter.c.orig	2016-07-22 04:12:45.000000000 +0800
2
+++ CPUMeter.c	2018-01-17 03:30:33.049766000 +0800
3
@@ -48,7 +48,7 @@
4
    int cpu = this->param;
5
    if (this->pl->cpuCount > 1) {
6
       char caption[10];
7
-      sprintf(caption, "%-3d", Settings_cpuId(this->pl->settings, cpu - 1));
8
+      xSnprintf(caption, sizeof(caption), "%-3d", Settings_cpuId(this->pl->settings, cpu - 1));
9
       Meter_setCaption(this, caption);
10
    }
11
    if (this->param == 0)
12
@@ -58,12 +58,12 @@
13
 static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
14
    int cpu = this->param;
15
    if (cpu > this->pl->cpuCount) {
16
-      snprintf(buffer, size, "absent");
17
+      xSnprintf(buffer, size, "absent");
18
       return;
19
    }
20
    memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT);
21
    double percent = Platform_setCPUValues(this, cpu);
22
-   snprintf(buffer, size, "%5.1f%%", percent);
23
+   xSnprintf(buffer, size, "%5.1f%%", percent);
24
 }
25
 
26
 static void CPUMeter_display(Object* cast, RichString* out) {
27
@@ -74,44 +74,44 @@
28
       RichString_append(out, CRT_colors[METER_TEXT], "absent");
29
       return;
30
    }
31
-   sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NORMAL]);
32
+   xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_NORMAL]);
33
    RichString_append(out, CRT_colors[METER_TEXT], ":");
34
    RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
35
    if (this->pl->settings->detailedCPUTime) {
36
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_KERNEL]);
37
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_KERNEL]);
38
       RichString_append(out, CRT_colors[METER_TEXT], "sy:");
39
       RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
40
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NICE]);
41
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_NICE]);
42
       RichString_append(out, CRT_colors[METER_TEXT], "ni:");
43
       RichString_append(out, CRT_colors[CPU_NICE_TEXT], buffer);
44
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IRQ]);
45
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_IRQ]);
46
       RichString_append(out, CRT_colors[METER_TEXT], "hi:");
47
       RichString_append(out, CRT_colors[CPU_IRQ], buffer);
48
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_SOFTIRQ]);
49
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_SOFTIRQ]);
50
       RichString_append(out, CRT_colors[METER_TEXT], "si:");
51
       RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer);
52
       if (this->values[CPU_METER_STEAL]) {
53
-         sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_STEAL]);
54
+	 xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_STEAL]);
55
          RichString_append(out, CRT_colors[METER_TEXT], "st:");
56
          RichString_append(out, CRT_colors[CPU_STEAL], buffer);
57
       }
58
       if (this->values[CPU_METER_GUEST]) {
59
-         sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_GUEST]);
60
+	 xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_GUEST]);
61
          RichString_append(out, CRT_colors[METER_TEXT], "gu:");
62
          RichString_append(out, CRT_colors[CPU_GUEST], buffer);
63
       }
64
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IOWAIT]);
65
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_IOWAIT]);
66
       RichString_append(out, CRT_colors[METER_TEXT], "wa:");
67
       RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
68
    } else {
69
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_KERNEL]);
70
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_KERNEL]);
71
       RichString_append(out, CRT_colors[METER_TEXT], "sys:");
72
       RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
73
-      sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NICE]);
74
+      xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_NICE]);
75
       RichString_append(out, CRT_colors[METER_TEXT], "low:");
76
       RichString_append(out, CRT_colors[CPU_NICE_TEXT], buffer);
77
       if (this->values[CPU_METER_IRQ]) {
78
-         sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IRQ]);
79
+         xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_IRQ]);
80
          RichString_append(out, CRT_colors[METER_TEXT], "vir:");
81
          RichString_append(out, CRT_colors[CPU_GUEST], buffer);
82
       }
(-)sysutils/htop/files/patch-CRT.c (+154 lines)
Line 0 Link Here
1
--- CRT.c.orig	2018-01-17 02:18:48.395218000 +0800
2
+++ CRT.c	2018-01-17 02:43:53.562847000 +0800
3
@@ -5,6 +5,7 @@
4
 in the source distribution for its full text.
5
 */
6
 
7
+#include "config.h"
8
 #include "CRT.h"
9
 
10
 #include "StringUtils.h"
11
@@ -17,8 +18,14 @@
12
 #include <string.h>
13
 #include <locale.h>
14
 #include <langinfo.h>
15
+#if HAVE_SETUID_ENABLED
16
+#include <unistd.h>
17
+#include <sys/types.h>
18
+#endif
19
+
20
+#define ColorIndex(i,j) ((7-i)*8+j)
21
 
22
-#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
23
+#define ColorPair(i,j) COLOR_PAIR(ColorIndex(i,j))
24
 
25
 #define Black COLOR_BLACK
26
 #define Red COLOR_RED
27
@@ -29,6 +36,8 @@
28
 #define Cyan COLOR_CYAN
29
 #define White COLOR_WHITE
30
 
31
+#define ColorPairGrayBlack ColorPair(Magenta,Magenta)
32
+
33
 #define KEY_WHEELUP KEY_F(20)
34
 #define KEY_WHEELDOWN KEY_F(21)
35
 #define KEY_RECLICK KEY_F(22)
36
@@ -183,7 +192,7 @@
37
       [LED_COLOR] = ColorPair(Green,Black),
38
       [TASKS_RUNNING] = A_BOLD | ColorPair(Green,Black),
39
       [PROCESS] = A_NORMAL,
40
-      [PROCESS_SHADOW] = A_BOLD | ColorPair(Black,Black),
41
+      [PROCESS_SHADOW] = A_BOLD | ColorPairGrayBlack,
42
       [PROCESS_TAG] = A_BOLD | ColorPair(Yellow,Black),
43
       [PROCESS_MEGABYTES] = ColorPair(Cyan,Black),
44
       [PROCESS_BASENAME] = A_BOLD | ColorPair(Cyan,Black),
45
@@ -195,7 +204,7 @@
46
       [PROCESS_THREAD] = ColorPair(Green,Black),
47
       [PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Black),
48
       [BAR_BORDER] = A_BOLD,
49
-      [BAR_SHADOW] = A_BOLD | ColorPair(Black,Black),
50
+      [BAR_SHADOW] = A_BOLD | ColorPairGrayBlack,
51
       [SWAP] = ColorPair(Red,Black),
52
       [GRAPH_1] = A_BOLD | ColorPair(Cyan,Black),
53
       [GRAPH_2] = ColorPair(Cyan,Black),
54
@@ -301,7 +310,7 @@
55
       [LED_COLOR] = ColorPair(Green,White),
56
       [TASKS_RUNNING] = ColorPair(Green,White),
57
       [PROCESS] = ColorPair(Black,White),
58
-      [PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White),
59
+      [PROCESS_SHADOW] = A_BOLD | ColorPairGrayBlack,
60
       [PROCESS_TAG] = ColorPair(White,Blue),
61
       [PROCESS_MEGABYTES] = ColorPair(Blue,White),
62
       [PROCESS_BASENAME] = ColorPair(Blue,White),
63
@@ -541,6 +550,48 @@
64
    exit(0);
65
 }
66
 
67
+#if HAVE_SETUID_ENABLED
68
+
69
+static int CRT_euid = -1;
70
+
71
+static int CRT_egid = -1;
72
+
73
+#define DIE(msg) do { CRT_done(); fprintf(stderr, msg); exit(1); } while(0)
74
+
75
+void CRT_dropPrivileges() {
76
+   CRT_egid = getegid();
77
+   CRT_euid = geteuid();
78
+   if (setegid(getgid()) == -1) {
79
+      DIE("Fatal error: failed dropping group privileges.\n");
80
+   }
81
+   if (seteuid(getuid()) == -1) {
82
+      DIE("Fatal error: failed dropping user privileges.\n");
83
+  }
84
+}
85
+
86
+void CRT_restorePrivileges() {
87
+   if (CRT_egid == -1 || CRT_euid == -1) {
88
+      DIE("Fatal error: internal inconsistency.\n");
89
+   }
90
+   if (setegid(CRT_egid) == -1) {
91
+      DIE("Fatal error: failed restoring group privileges.\n");
92
+   }
93
+   if (seteuid(CRT_euid) == -1) {
94
+      DIE("Fatal error: failed restoring user privileges.\n");
95
+   }
96
+}
97
+
98
+#else
99
+
100
+/* Turn setuid operations into NOPs */
101
+
102
+#ifndef CRT_dropPrivileges
103
+#define CRT_dropPrivileges()
104
+#define CRT_restorePrivileges()
105
+#endif
106
+
107
+#endif
108
+
109
 // TODO: pass an instance of Settings instead.
110
 
111
 void CRT_init(int delay, int colorScheme) {
112
@@ -555,7 +606,7 @@
113
    
114
    for (int i = 0; i < LAST_COLORELEMENT; i++) {
115
       unsigned int color = CRT_colorSchemes[COLORSCHEME_DEFAULT][i];
116
-      CRT_colorSchemes[COLORSCHEME_BROKENGRAY][i] = color == (A_BOLD | ColorPair(Black,Black)) ? ColorPair(White,Black) : color;
117
+      CRT_colorSchemes[COLORSCHEME_BROKENGRAY][i] = color == (A_BOLD | ColorPairGrayBlack) ? ColorPair(White,Black) : color;
118
    }
119
    
120
    halfdelay(CRT_delay);
121
@@ -575,7 +626,7 @@
122
       CRT_scrollHAmount = 20;
123
    else
124
       CRT_scrollHAmount = 5;
125
-   if (String_eq(CRT_termType, "xterm") || String_eq(CRT_termType, "xterm-color") || String_eq(CRT_termType, "vt220")) {
126
+   if (String_startsWith(CRT_termType, "xterm") || String_eq(CRT_termType, "vt220")) {
127
       define_key("\033[H", KEY_HOME);
128
       define_key("\033[F", KEY_END);
129
       define_key("\033[7~", KEY_HOME);
130
@@ -664,12 +715,20 @@
131
    CRT_colorScheme = colorScheme;
132
    if (colorScheme == COLORSCHEME_BLACKNIGHT) {
133
       for (int i = 0; i < 8; i++)
134
-         for (int j = 0; j < 8; j++)
135
-            init_pair((7-i)*8+j, i, j);
136
+         for (int j = 0; j < 8; j++) {
137
+            if (ColorIndex(i,j) != ColorIndex(Magenta,Magenta)) {
138
+               init_pair(ColorIndex(i,j), i, j);
139
+            }
140
+         }
141
+      init_pair(ColorIndex(Magenta,Magenta), 8, 0);
142
    } else {
143
       for (int i = 0; i < 8; i++) 
144
-         for (int j = 0; j < 8; j++)
145
-            init_pair((7-i)*8+j, i, (j==0?-1:j));
146
+         for (int j = 0; j < 8; j++) {
147
+            if (ColorIndex(i,j) != ColorIndex(Magenta,Magenta)) {
148
+               init_pair(ColorIndex(i,j), i, (j==0?-1:j));
149
+            }
150
+         }
151
+      init_pair(ColorIndex(Magenta,Magenta), 8, -1);
152
    }
153
    CRT_colors = CRT_colorSchemes[colorScheme];
154
 }
(-)sysutils/htop/files/patch-CRT.h (+51 lines)
Line 0 Link Here
1
--- CRT.h.orig	2018-01-17 02:23:30.145464000 +0800
2
+++ CRT.h	2018-01-17 02:45:07.234215000 +0800
3
@@ -9,7 +9,12 @@
4
 in the source distribution for its full text.
5
 */
6
 
7
-#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
8
+#if HAVE_SETUID_ENABLED
9
+#endif
10
+
11
+#define ColorIndex(i,j) ((7-i)*8+j)
12
+
13
+#define ColorPair(i,j) COLOR_PAIR(ColorIndex(i,j))
14
 
15
 #define Black COLOR_BLACK
16
 #define Red COLOR_RED
17
@@ -20,6 +25,8 @@
18
 #define Cyan COLOR_CYAN
19
 #define White COLOR_WHITE
20
 
21
+#define ColorPairGrayBlack ColorPair(Magenta,Magenta)
22
+
23
 #define KEY_WHEELUP KEY_F(20)
24
 #define KEY_WHEELDOWN KEY_F(21)
25
 #define KEY_RECLICK KEY_F(22)
26
@@ -150,6 +157,25 @@
27
 
28
 void *backtraceArray[128];
29
 
30
+#if HAVE_SETUID_ENABLED
31
+
32
+#define DIE(msg) do { CRT_done(); fprintf(stderr, msg); exit(1); } while(0)
33
+
34
+void CRT_dropPrivileges();
35
+
36
+void CRT_restorePrivileges();
37
+
38
+#else
39
+
40
+/* Turn setuid operations into NOPs */
41
+
42
+#ifndef CRT_dropPrivileges
43
+#define CRT_dropPrivileges()
44
+#define CRT_restorePrivileges()
45
+#endif
46
+
47
+#endif
48
+
49
 // TODO: pass an instance of Settings instead.
50
 
51
 void CRT_init(int delay, int colorScheme);
(-)sysutils/htop/files/patch-CategoriesPanel.c (+11 lines)
Line 0 Link Here
1
--- CategoriesPanel.c.orig	2018-01-17 02:28:08.116398000 +0800
2
+++ CategoriesPanel.c	2018-01-17 02:28:31.736158000 +0800
3
@@ -34,7 +34,7 @@
4
 
5
 }*/
6
 
7
-static const char* CategoriesFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
8
+static const char* const CategoriesFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
9
 
10
 static void CategoriesPanel_delete(Object* object) {
11
    Panel* super = (Panel*) object;
(-)sysutils/htop/files/patch-ColorsPanel.c (+14 lines)
Line 0 Link Here
1
--- ColorsPanel.c.orig	2018-01-17 02:28:47.009382000 +0800
2
+++ ColorsPanel.c	2018-01-17 02:29:08.185956000 +0800
3
@@ -34,9 +34,9 @@
4
 
5
 }*/
6
 
7
-static const char* ColorsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
8
+static const char* const ColorsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
9
 
10
-static const char* ColorSchemeNames[] = {
11
+static const char* const ColorSchemeNames[] = {
12
    "Default",
13
    "Monochromatic",
14
    "Black on White",
(-)sysutils/htop/files/patch-ColumnsPanel.c (+11 lines)
Line 0 Link Here
1
--- ColumnsPanel.c.orig	2018-01-17 02:29:30.687821000 +0800
2
+++ ColumnsPanel.c	2018-01-17 02:29:43.683563000 +0800
3
@@ -29,7 +29,7 @@
4
 
5
 }*/
6
 
7
-static const char* ColumnsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "MoveUp", "MoveDn", "Remove", "Done  ", NULL};
8
+static const char* const ColumnsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "MoveUp", "MoveDn", "Remove", "Done  ", NULL};
9
 
10
 static void ColumnsPanel_delete(Object* object) {
11
    Panel* super = (Panel*) object;
(-)sysutils/htop/files/patch-DisplayOptionsPanel.c (+11 lines)
Line 0 Link Here
1
--- DisplayOptionsPanel.c.orig	2018-01-17 02:29:58.241502000 +0800
2
+++ DisplayOptionsPanel.c	2018-01-17 02:30:12.751443000 +0800
3
@@ -28,7 +28,7 @@
4
 
5
 }*/
6
 
7
-static const char* DisplayOptionsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
8
+static const char* const DisplayOptionsFunctions[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "Done  ", NULL};
9
 
10
 static void DisplayOptionsPanel_delete(Object* object) {
11
    Panel* super = (Panel*) object;
(-)sysutils/htop/files/patch-EnvScreen.c (+16 lines)
Line 0 Link Here
1
--- EnvScreen.c.orig	2018-01-17 02:45:20.824325000 +0800
2
+++ EnvScreen.c	2018-01-17 02:45:44.349693000 +0800
3
@@ -48,10 +48,9 @@
4
 
5
    Panel_prune(panel);
6
 
7
-   uid_t euid = geteuid();
8
-   (void) seteuid(getuid());
9
-   char *env = Platform_getProcessEnv(this->process->pid);
10
-   (void) seteuid(euid);
11
+   CRT_dropPrivileges();
12
+   char* env = Platform_getProcessEnv(this->process->pid);
13
+   CRT_restorePrivileges();
14
    if (env) {
15
       for (char *p = env; *p; p = strrchr(p, 0)+1)
16
          InfoScreen_addLine(this, p);
(-)sysutils/htop/files/patch-FunctionBar.c (+29 lines)
Line 0 Link Here
1
--- FunctionBar.c.orig	2018-01-17 02:30:28.427114000 +0800
2
+++ FunctionBar.c	2018-01-17 02:31:19.521679000 +0800
3
@@ -28,21 +28,21 @@
4
 
5
 }*/
6
 
7
-static const char* FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL};
8
+static const char* const FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL};
9
 
10
-static const char* FunctionBar_FLabels[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", NULL};
11
+static const char* const FunctionBar_FLabels[] = {"      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", "      ", NULL};
12
 
13
 static int FunctionBar_FEvents[] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)};
14
 
15
-static const char* FunctionBar_EnterEscKeys[] = {"Enter", "Esc", NULL};
16
-static int FunctionBar_EnterEscEvents[] = {13, 27};
17
+static const char* const FunctionBar_EnterEscKeys[] = {"Enter", "Esc", NULL};
18
+static const int FunctionBar_EnterEscEvents[] = {13, 27};
19
 
20
 FunctionBar* FunctionBar_newEnterEsc(const char* enter, const char* esc) {
21
    const char* functions[] = {enter, esc, NULL};
22
    return FunctionBar_new(functions, FunctionBar_EnterEscKeys, FunctionBar_EnterEscEvents);
23
 }
24
 
25
-FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events) {
26
+FunctionBar* FunctionBar_new(const char* const* functions, const char* const* keys, const int* events) {
27
    FunctionBar* this = xCalloc(1, sizeof(FunctionBar));
28
    this->functions = xCalloc(16, sizeof(char*));
29
    if (!functions) {
(-)sysutils/htop/files/patch-FunctionBar.h (+11 lines)
Line 0 Link Here
1
--- FunctionBar.h.orig	2018-01-17 02:31:36.029675000 +0800
2
+++ FunctionBar.h	2018-01-17 02:31:48.125791000 +0800
3
@@ -24,7 +24,7 @@
4
 
5
 FunctionBar* FunctionBar_newEnterEsc(const char* enter, const char* esc);
6
 
7
-FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events);
8
+FunctionBar* FunctionBar_new(const char* const* functions, const char* const* keys, const int* events);
9
 
10
 void FunctionBar_delete(FunctionBar* this);
11
 
(-)sysutils/htop/files/patch-Header.c (+23 lines)
Line 0 Link Here
1
--- Header.c.orig	2018-01-17 02:59:49.751817000 +0800
2
+++ Header.c	2018-01-17 03:00:08.421250000 +0800
3
@@ -91,9 +91,9 @@
4
          Meter* meter = (Meter*) Vector_get(vec, i);
5
          char* name = xCalloc(64, sizeof(char));
6
          if (meter->param) {
7
-            snprintf(name, 63, "%s(%d)", As_Meter(meter)->name, meter->param);
8
+            xSnprintf(name, 63, "%s(%d)", As_Meter(meter)->name, meter->param);
9
          } else {
10
-            snprintf(name, 63, "%s", As_Meter(meter)->name);
11
+            xSnprintf(name, 63, "%s", As_Meter(meter)->name);
12
          }
13
          colSettings->names[i] = name;
14
          colSettings->modes[i] = meter->mode;
15
@@ -155,7 +155,7 @@
16
    strncpy(name, Meter_name(meter), nameLen);
17
    name[nameLen] = '\0';
18
    if (meter->param)
19
-      snprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
20
+      xSnprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
21
 
22
    return name;
23
 }
(-)sysutils/htop/files/patch-IncSet.c (+24 lines)
Line 0 Link Here
1
--- IncSet.c.orig	2018-01-17 02:32:09.268551000 +0800
2
+++ IncSet.c	2018-01-17 02:32:49.080123000 +0800
3
@@ -52,8 +52,8 @@
4
    mode->buffer[0] = 0;
5
 }
6
 
7
-static const char* searchFunctions[] = {"Next  ", "Cancel ", " Search: ", NULL};
8
-static const char* searchKeys[] = {"F3", "Esc", "  "};
9
+static const char* const searchFunctions[] = {"Next  ", "Cancel ", " Search: ", NULL};
10
+static const char* const searchKeys[] = {"F3", "Esc", "  "};
11
 static int searchEvents[] = {KEY_F(3), 27, ERR};
12
 
13
 static inline void IncMode_initSearch(IncMode* search) {
14
@@ -62,8 +62,8 @@
15
    search->isFilter = false;
16
 }
17
 
18
-static const char* filterFunctions[] = {"Done  ", "Clear ", " Filter: ", NULL};
19
-static const char* filterKeys[] = {"Enter", "Esc", "  "};
20
+static const char* const filterFunctions[] = {"Done  ", "Clear ", " Filter: ", NULL};
21
+static const char* const filterKeys[] = {"Enter", "Esc", "  "};
22
 static int filterEvents[] = {13, 27, ERR};
23
 
24
 static inline void IncMode_initFilter(IncMode* filter) {
(-)sysutils/htop/files/patch-InfoScreen.c (+14 lines)
Line 0 Link Here
1
--- InfoScreen.c.orig	2018-01-17 02:33:04.195280000 +0800
2
+++ InfoScreen.c	2018-01-17 02:33:21.833122000 +0800
3
@@ -50,9 +50,9 @@
4
 };
5
 }*/
6
 
7
-static const char* InfoScreenFunctions[] = {"Search ", "Filter ", "Refresh", "Done   ", NULL};
8
+static const char* const InfoScreenFunctions[] = {"Search ", "Filter ", "Refresh", "Done   ", NULL};
9
 
10
-static const char* InfoScreenKeys[] = {"F3", "F4", "F5", "Esc"};
11
+static const char* const InfoScreenKeys[] = {"F3", "F4", "F5", "Esc"};
12
 
13
 static int InfoScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
14
 
(-)sysutils/htop/files/patch-ListItem.c (+11 lines)
Line 0 Link Here
1
--- ListItem.c.orig	2018-01-17 03:00:25.275893000 +0800
2
+++ ListItem.c	2018-01-17 03:00:36.630201000 +0800
3
@@ -39,7 +39,7 @@
4
    /*
5
    int len = strlen(this->value)+1;
6
    char buffer[len+1];
7
-   snprintf(buffer, len, "%s", this->value);
8
+   xSnprintf(buffer, len, "%s", this->value);
9
    */
10
    if (this->moving) {
11
       RichString_write(out, CRT_colors[DEFAULT_COLOR],
(-)sysutils/htop/files/patch-LoadAverageMeter.c (+40 lines)
Line 0 Link Here
1
--- LoadAverageMeter.c.orig	2018-01-17 02:05:11.807928000 +0800
2
+++ LoadAverageMeter.c	2018-01-17 03:01:05.674938000 +0800
3
@@ -22,17 +22,17 @@
4
 
5
 static void LoadAverageMeter_updateValues(Meter* this, char* buffer, int size) {
6
    Platform_getLoadAverage(&this->values[0], &this->values[1], &this->values[2]);
7
-   snprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]);
8
+   xSnprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]);
9
 }
10
 
11
 static void LoadAverageMeter_display(Object* cast, RichString* out) {
12
    Meter* this = (Meter*)cast;
13
    char buffer[20];
14
-   sprintf(buffer, "%.2f ", this->values[0]);
15
+   xSnprintf(buffer, sizeof(buffer), "%.2f ", this->values[0]);
16
    RichString_write(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
17
-   sprintf(buffer, "%.2f ", this->values[1]);
18
+   xSnprintf(buffer, sizeof(buffer), "%.2f ", this->values[1]);
19
    RichString_append(out, CRT_colors[LOAD_AVERAGE_FIVE], buffer);
20
-   sprintf(buffer, "%.2f ", this->values[2]);
21
+   xSnprintf(buffer, sizeof(buffer), "%.2f ", this->values[2]);
22
    RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
23
 }
24
 
25
@@ -42,13 +42,13 @@
26
    if (this->values[0] > this->total) {
27
       this->total = this->values[0];
28
    }
29
-   snprintf(buffer, size, "%.2f", this->values[0]);
30
+   xSnprintf(buffer, size, "%.2f", this->values[0]);
31
 }
32
 
33
 static void LoadMeter_display(Object* cast, RichString* out) {
34
    Meter* this = (Meter*)cast;
35
    char buffer[20];
36
-   sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
37
+   xSnprintf(buffer, sizeof(buffer), "%.2f ", ((Meter*)this)->values[0]);
38
    RichString_write(out, CRT_colors[LOAD], buffer);
39
 }
40
 
(-)sysutils/htop/files/patch-MainPanel.c (+30 lines)
Line 0 Link Here
1
--- MainPanel.c.orig	2018-01-17 01:45:07.719577000 +0800
2
+++ MainPanel.c	2018-01-17 02:34:00.711369000 +0800
3
@@ -31,7 +31,7 @@
4
 
5
 }*/
6
 
7
-static const char* MainFunctions[]  = {"Help  ", "Setup ", "Search", "Filter", "Tree  ", "SortBy", "Nice -", "Nice +", "Kill  ", "Quit  ", NULL};
8
+static const char* const MainFunctions[]  = {"Help  ", "Setup ", "Search", "Filter", "Tree  ", "SortBy", "Nice -", "Nice +", "Kill  ", "Quit  ", NULL};
9
 
10
 void MainPanel_updateTreeFunctions(MainPanel* this, bool mode) {
11
    FunctionBar* bar = MainPanel_getFunctionBar(this);
12
@@ -83,14 +83,14 @@
13
       result = HANDLED;
14
    } else if (ch != ERR && this->inc->active) {
15
       bool filterChanged = IncSet_handleKey(this->inc, ch, super, (IncMode_GetPanelValue) MainPanel_getValue, NULL);
16
-      if (this->inc->found) {
17
-         reaction |= Action_follow(this->state);
18
-      }
19
       if (filterChanged) {
20
          this->state->pl->incFilter = IncSet_filter(this->inc);
21
          reaction = HTOP_REFRESH | HTOP_REDRAW_BAR;
22
       }
23
-      reaction |= HTOP_KEEP_FOLLOWING;
24
+      if (this->inc->found) {
25
+	 reaction |= Action_follow(this->state);
26
+	 reaction |= HTOP_KEEP_FOLLOWING;
27
+      }
28
       result = HANDLED;
29
    } else if (ch == 27) {
30
       return HANDLED;
(-)sysutils/htop/files/patch-Meter.c (+103 lines)
Line 0 Link Here
1
--- Meter.c.orig	2018-01-17 01:44:17.289511000 +0800
2
+++ Meter.c	2018-01-17 03:01:47.930033000 +0800
3
@@ -225,16 +225,16 @@
4
 ListItem* Meter_toListItem(Meter* this, bool moving) {
5
    char mode[21];
6
    if (this->mode)
7
-      snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
8
+      xSnprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
9
    else
10
       mode[0] = '\0';
11
    char number[11];
12
    if (this->param > 0)
13
-      snprintf(number, 10, " %d", this->param);
14
+      xSnprintf(number, 10, " %d", this->param);
15
    else
16
       number[0] = '\0';
17
    char buffer[51];
18
-   snprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
19
+   xSnprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
20
    ListItem* li = ListItem_new(buffer, 0);
21
    li->moving = moving;
22
    return li;
23
@@ -260,7 +260,7 @@
24
 
25
 /* ---------- BarMeterMode ---------- */
26
 
27
-static char BarMeterMode_characters[] = "|#*@$%&.";
28
+static const char BarMeterMode_characters[] = "|#*@$%&.";
29
 
30
 static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
31
    char buffer[METER_BUFFER_LEN];
32
@@ -287,7 +287,7 @@
33
    
34
    int blockSizes[10];
35
 
36
-   snprintf(bar, w + 1, "%*s", w, buffer);
37
+   xSnprintf(bar, w + 1, "%*s", w, buffer);
38
 
39
    // First draw in the bar[] buffer...
40
    int offset = 0;
41
@@ -336,7 +336,7 @@
42
 #ifdef HAVE_LIBNCURSESW
43
 
44
 #define PIXPERROW_UTF8 4
45
-static const char* GraphMeterMode_dotsUtf8[] = {
46
+static const char* const GraphMeterMode_dotsUtf8[] = {
47
    /*00*/" ", /*01*/"⢀", /*02*/"⢠", /*03*/"⢰", /*04*/ "⢸",
48
    /*10*/"⡀", /*11*/"⣀", /*12*/"⣠", /*13*/"⣰", /*14*/ "⣸",
49
    /*20*/"⡄", /*21*/"⣄", /*22*/"⣤", /*23*/"⣴", /*24*/ "⣼",
50
@@ -347,13 +347,13 @@
51
 #endif
52
 
53
 #define PIXPERROW_ASCII 2
54
-static const char* GraphMeterMode_dotsAscii[] = {
55
+static const char* const GraphMeterMode_dotsAscii[] = {
56
    /*00*/" ", /*01*/".", /*02*/":",
57
    /*10*/".", /*11*/".", /*12*/":",
58
    /*20*/":", /*21*/":", /*22*/":"
59
 };
60
 
61
-static const char** GraphMeterMode_dots;
62
+static const char* const* GraphMeterMode_dots;
63
 static int GraphMeterMode_pixPerRow;
64
 
65
 static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
66
@@ -406,8 +406,8 @@
67
    }
68
    for (; i < nValues; i+=2, k++) {
69
       int pix = GraphMeterMode_pixPerRow * GRAPH_HEIGHT;
70
-      int v1 = CLAMP(data->values[i] * pix, 1, pix);
71
-      int v2 = CLAMP(data->values[i+1] * pix, 1, pix);
72
+      int v1 = CLAMP((int) lround(data->values[i] * pix), 1, pix);
73
+      int v2 = CLAMP((int) lround(data->values[i+1] * pix), 1, pix);
74
 
75
       int colorIdx = GRAPH_1;
76
       for (int line = 0; line < GRAPH_HEIGHT; line++) {
77
@@ -424,7 +424,7 @@
78
 
79
 /* ---------- LEDMeterMode ---------- */
80
 
81
-static const char* LEDMeterMode_digitsAscii[] = {
82
+static const char* const LEDMeterMode_digitsAscii[] = {
83
    " __ ","    "," __ "," __ ","    "," __ "," __ "," __ "," __ "," __ ",
84
    "|  |","   |"," __|"," __|","|__|","|__ ","|__ ","   |","|__|","|__|",
85
    "|__|","   |","|__ "," __|","   |"," __|","|__|","   |","|__|"," __|"
86
@@ -432,7 +432,7 @@
87
 
88
 #ifdef HAVE_LIBNCURSESW
89
 
90
-static const char* LEDMeterMode_digitsUtf8[] = {
91
+static const char* const LEDMeterMode_digitsUtf8[] = {
92
    "┌──┐","  ┐ ","╶──┐","╶──┐","╷  ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐",
93
    "│  │","  │ ","┌──┘"," ──┤","└──┤","└──┐","├──┐","   │","├──┤","└──┤",
94
    "└──┘","  ╵ ","└──╴","╶──┘","   ╵","╶──┘","└──┘","   ╵","└──┘"," ──┘"
95
@@ -440,7 +440,7 @@
96
 
97
 #endif
98
 
99
-static const char** LEDMeterMode_digits;
100
+static const char* const* LEDMeterMode_digits;
101
 
102
 static void LEDMeterMode_drawDigit(int x, int y, int n) {
103
    for (int i = 0; i < 3; i++)
(-)sysutils/htop/files/patch-MetersPanel.c (+29 lines)
Line 0 Link Here
1
--- MetersPanel.c.orig	2018-01-17 02:16:54.622267000 +0800
2
+++ MetersPanel.c	2018-01-17 02:36:57.554597000 +0800
3
@@ -31,13 +31,19 @@
4
 
5
 }*/
6
 
7
-static const char* MetersFunctions[] = {"Type  ", "Move  ", "Delete", "Done  ", NULL};
8
-static const char* MetersKeys[] = {"Space", "Enter", "Del", "Esc"};
9
-static int MetersEvents[] = {' ', 13, KEY_DC, 27};
10
-
11
-static const char* MetersMovingFunctions[] = {"Up    ", "Down  ", "Left  ", "Right ",  "Confirm", "Delete", "Done  ", NULL};
12
-static const char* MetersMovingKeys[] = {"Up", "Dn", "Lt", "Rt", "Enter", "Del", "Esc"};
13
-static int MetersMovingEvents[] = {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, 13, KEY_DC, 27};
14
+// Note: In code the meters are known to have bar/text/graph "Modes", but in UI
15
+// we call them "Styles".
16
+static const char* const MetersFunctions[] = {"Style ", "Move  ", "                                       ", "Delete", "Done  ", NULL};
17
+static const char* const MetersKeys[] = {"Space", "Enter", "  ", "Del", "F10"};
18
+static int MetersEvents[] = {' ', 13, ERR, KEY_DC, KEY_F(10)};
19
+
20
+// We avoid UTF-8 arrows ← → here as they might display full-width on Chinese
21
+// terminals, breaking our aligning.
22
+// In <http://unicode.org/reports/tr11/>, arrows (U+2019..U+2199) are
23
+// considered "Ambiguous characters".
24
+static const char* const MetersMovingFunctions[] = {"Style ", "Lock  ", "Up    ", "Down  ", "Left  ", "Right ", "       ", "Delete", "Done  ", NULL};
25
+static const char* const MetersMovingKeys[] = {"Space", "Enter", "Up", "Dn", "<-", "->", "  ", "Del", "F10"};
26
+static int MetersMovingEvents[] = {' ', 13, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, ERR, KEY_DC, KEY_F(10)};
27
 static FunctionBar* Meters_movingBar = NULL;
28
 
29
 static void MetersPanel_delete(Object* object) {
(-)sysutils/htop/files/patch-MetersPanel.h (+16 lines)
Line 0 Link Here
1
--- MetersPanel.h.orig	2018-01-17 02:17:50.701053000 +0800
2
+++ MetersPanel.h	2018-01-17 02:18:20.683585000 +0800
3
@@ -26,7 +26,12 @@
4
    bool moving;
5
 };
6
 
7
-
8
+// Note: In code the meters are known to have bar/text/graph "Modes", but in UI
9
+// we call them "Styles".
10
+// We avoid UTF-8 arrows ← → here as they might display full-width on Chinese
11
+// terminals, breaking our aligning.
12
+// In <http://unicode.org/reports/tr11/>, arrows (U+2019..U+2199) are
13
+// considered "Ambiguous characters".
14
 
15
 void MetersPanel_setMoving(MetersPanel* this, bool moving);
16
 
(-)sysutils/htop/files/patch-OpenFilesScreen.c (+28 lines)
Line 0 Link Here
1
--- OpenFilesScreen.c.orig	2018-01-17 01:59:26.253093000 +0800
2
+++ OpenFilesScreen.c	2018-01-17 03:02:15.808338000 +0800
3
@@ -77,7 +77,7 @@
4
 
5
 static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
6
    char command[1025];
7
-   snprintf(command, 1024, "lsof -P -p %d -F 2> /dev/null", pid);
8
+   xSnprintf(command, 1024, "lsof -P -p %d -F 2> /dev/null", pid);
9
    FILE* fd = popen(command, "r");
10
    OpenFiles_ProcessData* pdata = xCalloc(1, sizeof(OpenFiles_ProcessData));
11
    OpenFiles_FileData* fdata = NULL;
12
@@ -102,7 +102,6 @@
13
          fdata = nextFile;
14
          item = &(fdata->data);
15
       }
16
-      assert(cmd >= 0 && cmd <= 0xff);
17
       item->data[cmd] = xStrdup(line + 1);
18
       free(line);
19
    }
20
@@ -132,7 +131,7 @@
21
          int lenN = data['n'] ? strlen(data['n']) : 0;
22
          int sizeEntry = 5 + 7 + 10 + 10 + 10 + lenN + 5 /*spaces*/ + 1 /*null*/;
23
          char* entry = xMalloc(sizeEntry);
24
-         snprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s",
25
+         xSnprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s",
26
             data['f'] ? data['f'] : "",
27
             data['t'] ? data['t'] : "",
28
             data['D'] ? data['D'] : "",
(-)sysutils/htop/files/patch-Panel.c (+18 lines)
Line 0 Link Here
1
--- Panel.c.orig	2018-01-17 01:46:17.219692000 +0800
2
+++ Panel.c	2018-01-17 01:46:55.968163000 +0800
3
@@ -407,12 +407,13 @@
4
       break;
5
    case KEY_PPAGE:
6
       this->selected -= (this->h - 1);
7
-      this->scrollV -= (this->h - 1);
8
+      this->scrollV = MAX(0, this->scrollV - this->h + 1);
9
       this->needsRedraw = true;
10
       break;
11
    case KEY_NPAGE:
12
       this->selected += (this->h - 1);
13
-      this->scrollV = MIN(MAX(0, Vector_size(this->items) - this->h), this->selected - this->h);
14
+      this->scrollV = MAX(0, MIN(Vector_size(this->items) - this->h,
15
+			         this->scrollV + this->h - 1));
16
       this->needsRedraw = true;
17
       break;
18
    case KEY_WHEELUP:
(-)sysutils/htop/files/patch-Process.c (+207 lines)
Line 0 Link Here
1
--- Process.c.orig	2018-01-17 01:54:30.580537000 +0800
2
+++ Process.c	2018-01-17 03:18:28.502348000 +0800
3
@@ -18,6 +18,7 @@
4
 #include <sys/resource.h>
5
 #include <sys/param.h>
6
 #include <sys/stat.h>
7
+#include <sys/types.h>
8
 #include <unistd.h>
9
 #include <stdlib.h>
10
 #include <signal.h>
11
@@ -171,6 +172,7 @@
12
 
13
 #define As_Process(this_)              ((ProcessClass*)((this_)->super.klass))
14
 
15
+#define Process_isChildOf(process_, pid_) (process_->tgid == pid_ || (process_->tgid == process_->pid && process_->ppid == pid_))
16
 }*/
17
 
18
 static int Process_getuid = -1;
19
@@ -194,10 +196,10 @@
20
    assert(digits < 20);
21
    for (int i = 0; Process_pidColumns[i].label; i++) {
22
       assert(i < 20);
23
-      snprintf(Process_titleBuffer[i], 20, "%*s ", digits, Process_pidColumns[i].label);
24
+      xSnprintf(Process_titleBuffer[i], 20, "%*s ", digits, Process_pidColumns[i].label);
25
       Process_fields[Process_pidColumns[i].id].title = Process_titleBuffer[i];
26
    }
27
-   sprintf(Process_pidFormat, "%%%dd ", digits);
28
+   xSnprintf(Process_pidFormat, sizeof(Process_pidFormat), "%%%dd ", digits);
29
 }
30
 
31
 void Process_humanNumber(RichString* str, unsigned long number, bool coloring) {
32
@@ -261,13 +263,16 @@
33
       processShadowColor = CRT_colors[PROCESS];
34
    }
35
 
36
-   if (number > 10000000000) {
37
-      snprintf(buffer, 13, "%11lld ", number / 1000);
38
+   if ((long long) number == -1LL) {
39
+      int len = snprintf(buffer, 13, "    no perm ");
40
+      RichString_appendn(str, CRT_colors[PROCESS_SHADOW], buffer, len);
41
+   } else if (number > 10000000000) {
42
+      xSnprintf(buffer, 13, "%11lld ", number / 1000);
43
       RichString_appendn(str, largeNumberColor, buffer, 5);
44
       RichString_appendn(str, processMegabytesColor, buffer+5, 3);
45
       RichString_appendn(str, processColor, buffer+8, 4);
46
    } else {
47
-      snprintf(buffer, 13, "%11llu ", number);
48
+      xSnprintf(buffer, 13, "%11llu ", number);
49
       RichString_appendn(str, largeNumberColor, buffer, 2);
50
       RichString_appendn(str, processMegabytesColor, buffer+2, 3);
51
       RichString_appendn(str, processColor, buffer+5, 3);
52
@@ -284,15 +289,15 @@
53
    int hundredths = totalHundredths - (totalSeconds * 100);
54
    char buffer[11];
55
    if (hours >= 100) {
56
-      snprintf(buffer, 10, "%7lluh ", hours);
57
+      xSnprintf(buffer, 10, "%7lluh ", hours);
58
       RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
59
    } else {
60
       if (hours) {
61
-         snprintf(buffer, 10, "%2lluh", hours);
62
+         xSnprintf(buffer, 10, "%2lluh", hours);
63
          RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
64
-         snprintf(buffer, 10, "%02d:%02d ", minutes, seconds);
65
+         xSnprintf(buffer, 10, "%02d:%02d ", minutes, seconds);
66
       } else {
67
-         snprintf(buffer, 10, "%2d:%02d.%02d ", minutes, seconds, hundredths);
68
+         xSnprintf(buffer, 10, "%2d:%02d.%02d ", minutes, seconds, hundredths);
69
       }
70
       RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
71
    }
72
@@ -364,19 +369,19 @@
73
    switch (field) {
74
    case PERCENT_CPU: {
75
       if (this->percent_cpu > 999.9) {
76
-         snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu); 
77
+         xSnprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu); 
78
       } else if (this->percent_cpu > 99.9) {
79
-         snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu); 
80
+         xSnprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu); 
81
       } else {
82
-         snprintf(buffer, n, "%4.1f ", this->percent_cpu);
83
+         xSnprintf(buffer, n, "%4.1f ", this->percent_cpu);
84
       }
85
       break;
86
    }
87
    case PERCENT_MEM: {
88
       if (this->percent_mem > 99.9) {
89
-         snprintf(buffer, n, "100. "); 
90
+         xSnprintf(buffer, n, "100. "); 
91
       } else {
92
-         snprintf(buffer, n, "%4.1f ", this->percent_mem);
93
+         xSnprintf(buffer, n, "%4.1f ", this->percent_mem);
94
       }
95
       break;
96
    }
97
@@ -407,7 +412,7 @@
98
             n -= written;
99
          }
100
          const char* draw = CRT_treeStr[lastItem ? (this->settings->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
101
-         snprintf(buf, n, "%s%s ", draw, this->showChildren ? CRT_treeStr[TREE_STR_SHUT] : CRT_treeStr[TREE_STR_OPEN] );
102
+         xSnprintf(buf, n, "%s%s ", draw, this->showChildren ? CRT_treeStr[TREE_STR_SHUT] : CRT_treeStr[TREE_STR_OPEN] );
103
          RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
104
          Process_writeCommand(this, attr, baseattr, str);
105
          return;
106
@@ -418,28 +423,28 @@
107
    case M_RESIDENT: Process_humanNumber(str, this->m_resident * PAGE_SIZE_KB, coloring); return;
108
    case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
109
    case NICE: {
110
-      snprintf(buffer, n, "%3ld ", this->nice);
111
+      xSnprintf(buffer, n, "%3ld ", this->nice);
112
       attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
113
            : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
114
            : attr;
115
       break;
116
    }
117
-   case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
118
-   case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
119
-   case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
120
-   case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
121
+   case NLWP: xSnprintf(buffer, n, "%4ld ", this->nlwp); break;
122
+   case PGRP: xSnprintf(buffer, n, Process_pidFormat, this->pgrp); break;
123
+   case PID: xSnprintf(buffer, n, Process_pidFormat, this->pid); break;
124
+   case PPID: xSnprintf(buffer, n, Process_pidFormat, this->ppid); break;
125
    case PRIORITY: {
126
-      if(this->priority == -100)
127
-         snprintf(buffer, n, " RT ");
128
+      if(this->priority <= -100)
129
+         xSnprintf(buffer, n, " RT ");
130
       else
131
-         snprintf(buffer, n, "%3ld ", this->priority);
132
+         xSnprintf(buffer, n, "%3ld ", this->priority);
133
       break;
134
    }
135
-   case PROCESSOR: snprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, this->processor)); break;
136
-   case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
137
-   case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
138
+   case PROCESSOR: xSnprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, this->processor)); break;
139
+   case SESSION: xSnprintf(buffer, n, Process_pidFormat, this->session); break;
140
+   case STARTTIME: xSnprintf(buffer, n, "%s", this->starttime_show); break;
141
    case STATE: {
142
-      snprintf(buffer, n, "%c ", this->state);
143
+      xSnprintf(buffer, n, "%c ", this->state);
144
       switch(this->state) {
145
           case 'R':
146
               attr = CRT_colors[PROCESS_R_STATE];
147
@@ -450,18 +455,18 @@
148
       }
149
       break;
150
    }
151
-   case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
152
+   case ST_UID: xSnprintf(buffer, n, "%4d ", this->st_uid); break;
153
    case TIME: Process_printTime(str, this->time); return;
154
-   case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
155
-   case TPGID: snprintf(buffer, n, Process_pidFormat, this->tpgid); break;
156
-   case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
157
+   case TGID: xSnprintf(buffer, n, Process_pidFormat, this->tgid); break;
158
+   case TPGID: xSnprintf(buffer, n, Process_pidFormat, this->tpgid); break;
159
+   case TTY_NR: xSnprintf(buffer, n, "%3u:%3u ", major(this->tty_nr), minor(this->tty_nr)); break;
160
    case USER: {
161
       if (Process_getuid != (int) this->st_uid)
162
          attr = CRT_colors[PROCESS_SHADOW];
163
       if (this->user) {
164
-         snprintf(buffer, n, "%-9s ", this->user);
165
+         xSnprintf(buffer, n, "%-9s ", this->user);
166
       } else {
167
-         snprintf(buffer, n, "%-9d ", this->st_uid);
168
+         xSnprintf(buffer, n, "%-9d ", this->st_uid);
169
       }
170
       if (buffer[9] != '\0') {
171
          buffer[9] = ' ';
172
@@ -470,7 +475,7 @@
173
       break;
174
    }
175
    default:
176
-      snprintf(buffer, n, "- ");
177
+      xSnprintf(buffer, n, "- ");
178
    }
179
    RichString_append(str, attr, buffer);
180
 }
181
@@ -518,11 +523,10 @@
182
 }
183
 
184
 bool Process_setPriority(Process* this, int priority) {
185
-   uid_t euid = geteuid();
186
-   (void) seteuid(getuid());
187
+   CRT_dropPrivileges();
188
    int old_prio = getpriority(PRIO_PROCESS, this->pid);
189
    int err = setpriority(PRIO_PROCESS, this->pid, priority);
190
-   (void) seteuid(euid);
191
+   CRT_restorePrivileges();
192
    if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
193
       this->nice = priority;
194
    }
195
@@ -534,10 +538,9 @@
196
 }
197
 
198
 void Process_sendSignal(Process* this, size_t sgn) {
199
-   uid_t euid = geteuid();
200
-   (void) seteuid(getuid());
201
+   CRT_dropPrivileges();
202
    kill(this->pid, (int) sgn);
203
-   (void) seteuid(euid);
204
+   CRT_restorePrivileges();
205
 }
206
 
207
 long Process_pidCompare(const void* v1, const void* v2) {
(-)sysutils/htop/files/patch-Process.h (+10 lines)
Line 0 Link Here
1
--- Process.h.orig	2018-01-17 03:18:43.594910000 +0800
2
+++ Process.h	2018-01-17 03:18:57.241872000 +0800
3
@@ -151,6 +151,7 @@
4
 
5
 #define As_Process(this_)              ((ProcessClass*)((this_)->super.klass))
6
 
7
+#define Process_isChildOf(process_, pid_) (process_->tgid == pid_ || (process_->tgid == process_->pid && process_->ppid == pid_))
8
 
9
 #define ONE_K 1024L
10
 #define ONE_M (ONE_K * ONE_K)
(-)sysutils/htop/files/patch-ProcessList.c (+74 lines)
Line 0 Link Here
1
--- ProcessList.c.orig	2018-01-17 03:14:56.195331000 +0800
2
+++ ProcessList.c	2018-01-17 03:19:21.422680000 +0800
3
@@ -173,7 +173,7 @@
4
 
5
    for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
6
       Process* process = (Process*) (Vector_get(this->processes, i));
7
-      if (process->show && (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid))) {
8
+      if (process->show && Process_isChildOf(process, pid)) {
9
          process = (Process*) (Vector_take(this->processes, i));
10
          Vector_add(children, process);
11
       }
12
@@ -213,23 +213,46 @@
13
       // Restore settings
14
       this->settings->sortKey = sortKey;
15
       this->settings->direction = direction;
16
-      // Take PID 1 as root and add to the new listing
17
       int vsize = Vector_size(this->processes);
18
-      Process* init = (Process*) (Vector_take(this->processes, 0));
19
-      if (!init) return;
20
-      // This assertion crashes on hardened kernels.
21
-      // I wonder how well tree view works on those systems.
22
-      // assert(init->pid == 1);
23
-      init->indent = 0;
24
-      Vector_add(this->processes2, init);
25
-      // Recursively empty list
26
-      ProcessList_buildTree(this, init->pid, 0, 0, direction, true);
27
-      // Add leftovers
28
-      while (Vector_size(this->processes)) {
29
-         Process* p = (Process*) (Vector_take(this->processes, 0));
30
-         p->indent = 0;
31
-         Vector_add(this->processes2, p);
32
-         ProcessList_buildTree(this, p->pid, 0, 0, direction, p->showChildren);
33
+      // Find all processes whose parent is not visible
34
+      int size;
35
+      while ((size = Vector_size(this->processes))) {
36
+         int i;
37
+         for (i = 0; i < size; i++) {
38
+            Process* process = (Process*)(Vector_get(this->processes, i));
39
+            // Immediately consume not shown processes
40
+            if (!process->show) {
41
+               process = (Process*)(Vector_take(this->processes, i));
42
+               process->indent = 0;
43
+               Vector_add(this->processes2, process);
44
+               ProcessList_buildTree(this, process->pid, 0, 0, direction, false);
45
+               break;
46
+            }
47
+            pid_t ppid = process->tgid == process->pid ? process->ppid : process->tgid;
48
+            // Bisect the process vector to find parent
49
+            int l = 0, r = size;
50
+            while (l < r) {
51
+               int c = (l + r) / 2;
52
+               pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;
53
+               if (ppid == pid) {
54
+                  break;
55
+	       } else if (ppid < pid) {
56
+                  r = c;
57
+	       } else {
58
+                  l = c + 1;
59
+	       }
60
+            }
61
+            // If parent not found, then construct the tree with this root
62
+            if (l >= r) {
63
+               process = (Process*)(Vector_take(this->processes, i));
64
+               process->indent = 0;
65
+               Vector_add(this->processes2, process);
66
+               ProcessList_buildTree(this, process->pid, 0, 0, direction, process->showChildren);
67
+               break;
68
+            }
69
+         }
70
+         // There should be no loop in the process tree
71
+         assert(i < size);
72
       }
73
       assert(Vector_size(this->processes2) == vsize); (void)vsize;
74
       assert(Vector_size(this->processes) == 0);
(-)sysutils/htop/files/patch-Settings.c (+83 lines)
Line 0 Link Here
1
--- Settings.c.orig	2018-01-17 02:38:27.802306000 +0800
2
+++ Settings.c	2018-01-17 02:49:53.114523000 +0800
3
@@ -165,11 +165,10 @@
4
 
5
 static bool Settings_read(Settings* this, const char* fileName) {
6
    FILE* fd;
7
-   uid_t euid = geteuid();
8
 
9
-   (void) seteuid(getuid());
10
+   CRT_dropPrivileges();
11
    fd = fopen(fileName, "r");
12
-   (void) seteuid(euid);
13
+   CRT_restorePrivileges();
14
    if (!fd)
15
       return false;
16
    
17
@@ -255,34 +254,40 @@
18
 
19
 static void writeFields(FILE* fd, ProcessField* fields, const char* name) {
20
    fprintf(fd, "%s=", name);
21
+   const char* sep = "";
22
    for (int i = 0; fields[i]; i++) {
23
       // This "-1" is for compatibility with the older enum format.
24
-      fprintf(fd, "%d ", (int) fields[i]-1);
25
+      fprintf(fd, "%s%d", sep, (int) fields[i]-1);
26
+      sep = " ";
27
    }
28
    fprintf(fd, "\n");
29
 }
30
 
31
 static void writeMeters(Settings* this, FILE* fd, int column) {
32
+   const char* sep = "";
33
    for (int i = 0; i < this->columns[column].len; i++) {
34
-      fprintf(fd, "%s ", this->columns[column].names[i]);
35
+      fprintf(fd, "%s%s", sep, this->columns[column].names[i]);
36
+      sep = " ";
37
    }
38
    fprintf(fd, "\n");
39
 }
40
 
41
 static void writeMeterModes(Settings* this, FILE* fd, int column) {
42
+   const char* sep = "";
43
    for (int i = 0; i < this->columns[column].len; i++) {
44
-      fprintf(fd, "%d ", this->columns[column].modes[i]);
45
+      fprintf(fd, "%s%d", sep, this->columns[column].modes[i]);
46
+      sep = " ";
47
    }
48
    fprintf(fd, "\n");
49
 }
50
 
51
 bool Settings_write(Settings* this) {
52
    FILE* fd;
53
-   uid_t euid = geteuid();
54
 
55
-   (void) seteuid(getuid());
56
+   CRT_dropPrivileges();
57
    fd = fopen(this->filename, "w");
58
-   (void) seteuid(euid);
59
+   CRT_restorePrivileges();
60
+
61
    if (fd == NULL) {
62
       return false;
63
    }
64
@@ -368,8 +373,8 @@
65
          htopDir = String_cat(home, "/.config/htop");
66
       }
67
       legacyDotfile = String_cat(home, "/.htoprc");
68
-      uid_t euid = geteuid();
69
-      (void) seteuid(getuid());
70
+
71
+      CRT_dropPrivileges();
72
       (void) mkdir(configDir, 0700);
73
       (void) mkdir(htopDir, 0700);
74
       free(htopDir);
75
@@ -382,7 +387,7 @@
76
          free(legacyDotfile);
77
          legacyDotfile = NULL;
78
       }
79
-      (void) seteuid(euid);
80
+      CRT_restorePrivileges();
81
    }
82
    this->colorScheme = 0;
83
    this->changed = false;
(-)sysutils/htop/files/patch-SignalsPanel.c (+31 lines)
Line 0 Link Here
1
--- SignalsPanel.c.orig	2018-01-17 01:55:33.869022000 +0800
2
+++ SignalsPanel.c	2018-01-17 03:06:20.265727000 +0800
3
@@ -31,13 +31,27 @@
4
    Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem), FunctionBar_newEnterEsc("Send   ", "Cancel "));
5
    const int defaultSignal = SIGTERM;
6
    int defaultPosition = 15;
7
-   for(unsigned int i = 0; i < Platform_numberOfSignals; i++) {
8
+   unsigned int i;
9
+   for(int i = 0; i < Platform_numberOfSignals; i++) {
10
       Panel_set(this, i, (Object*) ListItem_new(Platform_signals[i].name, Platform_signals[i].number));
11
       // signal 15 is not always the 15th signal in the table
12
       if (Platform_signals[i].number == defaultSignal) {
13
          defaultPosition = i;
14
       }
15
    }
16
+   #if (defined(SIGRTMIN) && defined(SIGRTMAX))
17
+   if (SIGRTMAX - SIGRTMIN <= 100) {
18
+      static char buf[15];
19
+      for (int sig = SIGRTMIN; sig <= SIGRTMAX; i++, sig++) {
20
+         int n = sig - SIGRTMIN;
21
+	 xSnprintf(buf, 15, "%2d SIGRTMIN%-+3d", sig, n);
22
+         if (n == 0) {
23
+            buf[11] = '\0';
24
+         }
25
+	 Panel_set(this, i, (Object*) ListItem_new(buf, sig));
26
+      }
27
+   }
28
+   #endif
29
    Panel_setHeader(this, "Send signal:");
30
    Panel_setSelected(this, defaultPosition);
31
    return this;
(-)sysutils/htop/files/patch-StringUtils.c (+29 lines)
Line 0 Link Here
1
--- StringUtils.c.orig	2018-01-17 01:47:39.407076000 +0800
2
+++ StringUtils.c	2018-01-17 01:51:44.982545000 +0800
3
@@ -17,10 +17,15 @@
4
 /*{
5
 #include <stdio.h>
6
 
7
-#define String_startsWith(s, match) (strstr((s), (match)) == (s))
8
+#define String_startsWith(s, match) (strncmp((s),(match),strlen(match)) == 0)
9
 #define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL)
10
 }*/
11
 
12
+/*
13
+ * String_startsWith gives better performance if strlen(match) can be computed
14
+ * at compile time (e.g. when they are immutable string literals). :)
15
+ */
16
+
17
 char* String_cat(const char* s1, const char* s2) {
18
    int l1 = strlen(s1);
19
    int l2 = strlen(s2);
20
@@ -88,6 +93,9 @@
21
 }
22
 
23
 void String_freeArray(char** s) {
24
+   if (!s) {
25
+      return;
26
+   }
27
    for (int i = 0; s[i] != NULL; i++) {
28
       free(s[i]);
29
    }
(-)sysutils/htop/files/patch-StringUtils.h (+18 lines)
Line 0 Link Here
1
--- StringUtils.h.orig	2018-01-17 01:49:03.627994000 +0800
2
+++ StringUtils.h	2018-01-17 01:49:59.251235000 +0800
3
@@ -11,9 +11,14 @@
4
 
5
 #include <stdio.h>
6
 
7
-#define String_startsWith(s, match) (strstr((s), (match)) == (s))
8
+#define String_startsWith(s, match) (strncmp((s),(match),strlen(match)) == 0)
9
 #define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL)
10
 
11
+/*
12
+ * String_startsWith gives better performance if strlen(match) can be computed
13
+ * at compile time (e.g. when they are immutable string literals). :)
14
+ */
15
+
16
 char* String_cat(const char* s1, const char* s2);
17
 
18
 char* String_trim(const char* in);
(-)sysutils/htop/files/patch-TasksMeter.c (+42 lines)
Line 0 Link Here
1
--- TasksMeter.c.orig	2018-01-17 02:06:38.125002000 +0800
2
+++ TasksMeter.c	2018-01-17 03:07:07.512269000 +0800
3
@@ -30,7 +30,7 @@
4
    if (this->pl->settings->hideKernelThreads) {
5
       this->values[0] = 0;
6
    }
7
-   snprintf(buffer, len, "%d/%d", (int) this->values[3], (int) this->total);
8
+   xSnprintf(buffer, len, "%d/%d", (int) this->values[3], (int) this->total);
9
 }
10
 
11
 static void TasksMeter_display(Object* cast, RichString* out) {
12
@@ -40,7 +40,7 @@
13
    
14
    int processes = (int) this->values[2];
15
    
16
-   sprintf(buffer, "%d", processes);
17
+   xSnprintf(buffer, sizeof(buffer), "%d", processes);
18
    RichString_write(out, CRT_colors[METER_VALUE], buffer);
19
    int threadValueColor = CRT_colors[METER_VALUE];
20
    int threadCaptionColor = CRT_colors[METER_TEXT];
21
@@ -50,18 +50,18 @@
22
    }
23
    if (!settings->hideUserlandThreads) {
24
       RichString_append(out, CRT_colors[METER_TEXT], ", ");
25
-      sprintf(buffer, "%d", (int)this->values[1]);
26
+      xSnprintf(buffer, sizeof(buffer), "%d", (int)this->values[1]);
27
       RichString_append(out, threadValueColor, buffer);
28
       RichString_append(out, threadCaptionColor, " thr");
29
    }
30
    if (!settings->hideKernelThreads) {
31
       RichString_append(out, CRT_colors[METER_TEXT], ", ");
32
-      sprintf(buffer, "%d", (int)this->values[0]);
33
+      xSnprintf(buffer, sizeof(buffer), "%d", (int)this->values[0]);
34
       RichString_append(out, threadValueColor, buffer);
35
       RichString_append(out, threadCaptionColor, " kthr");
36
    }
37
    RichString_append(out, CRT_colors[METER_TEXT], "; ");
38
-   sprintf(buffer, "%d", (int)this->values[3]);
39
+   xSnprintf(buffer, sizeof(buffer), "%d", (int)this->values[3]);
40
    RichString_append(out, CRT_colors[TASKS_RUNNING], buffer);
41
    RichString_append(out, CRT_colors[METER_TEXT], " running");
42
 }
(-)sysutils/htop/files/patch-TraceScreen.c (+43 lines)
Line 0 Link Here
1
--- TraceScreen.c.orig	2018-01-17 02:07:43.495613000 +0800
2
+++ TraceScreen.c	2018-01-17 03:08:08.481397000 +0800
3
@@ -22,6 +22,7 @@
4
 #include <stdbool.h>
5
 #include <unistd.h>
6
 #include <fcntl.h>
7
+#include <sys/time.h>
8
 #include <sys/types.h>
9
 #include <sys/wait.h>
10
 #include <signal.h>
11
@@ -42,9 +43,9 @@
12
 
13
 }*/
14
 
15
-static const char* TraceScreenFunctions[] = {"Search ", "Filter ", "AutoScroll ", "Stop Tracing   ", "Done   ", NULL};
16
+static const char* const TraceScreenFunctions[] = {"Search ", "Filter ", "AutoScroll ", "Stop Tracing   ", "Done   ", NULL};
17
 
18
-static const char* TraceScreenKeys[] = {"F3", "F4", "F8", "F9", "Esc"};
19
+static const char* const TraceScreenKeys[] = {"F3", "F4", "F8", "F9", "Esc"};
20
 
21
 static int TraceScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(8), KEY_F(9), 27};
22
 
23
@@ -90,16 +91,16 @@
24
 
25
 bool TraceScreen_forkTracer(TraceScreen* this) {
26
    char buffer[1001];
27
-   int err = pipe(this->fdpair);
28
-   if (err == -1) return false;
29
+   int error = pipe(this->fdpair);
30
+   if (error == -1) return false;
31
    this->child = fork();
32
    if (this->child == -1) return false;
33
    if (this->child == 0) {
34
-      (void) seteuid(getuid());
35
+      CRT_dropPrivileges();
36
       dup2(this->fdpair[1], STDERR_FILENO);
37
       int ok = fcntl(this->fdpair[1], F_SETFL, O_NONBLOCK);
38
       if (ok != -1) {
39
-         sprintf(buffer, "%d", this->super.process->pid);
40
+         xSnprintf(buffer, sizeof(buffer), "%d", this->super.process->pid);
41
          execlp("strace", "strace", "-p", buffer, NULL);
42
       }
43
       const char* message = "Could not execute 'strace'. Please make sure it is available in your $PATH.";
(-)sysutils/htop/files/patch-UptimeMeter.c (+34 lines)
Line 0 Link Here
1
--- UptimeMeter.c.orig	2018-01-17 02:08:11.372761000 +0800
2
+++ UptimeMeter.c	2018-01-17 03:08:58.209514000 +0800
3
@@ -20,7 +20,7 @@
4
 static void UptimeMeter_updateValues(Meter* this, char* buffer, int len) {
5
    int totalseconds = Platform_getUptime();
6
    if (totalseconds == -1) {
7
-      snprintf(buffer, len, "(unknown)");
8
+      xSnprintf(buffer, len, "(unknown)");
9
       return;
10
    }
11
    int seconds = totalseconds % 60;
12
@@ -31,17 +31,17 @@
13
    if (days > this->total) {
14
       this->total = days;
15
    }
16
-   char daysbuf[15];
17
+   char daysbuf[32];
18
    if (days > 100) {
19
-      sprintf(daysbuf, "%d days(!), ", days);
20
+      xSnprintf(daysbuf, sizeof(daysbuf), "%d days(!), ", days);
21
    } else if (days > 1) {
22
-      sprintf(daysbuf, "%d days, ", days);
23
+      xSnprintf(daysbuf, sizeof(daysbuf), "%d days, ", days);
24
    } else if (days == 1) {
25
-      sprintf(daysbuf, "1 day, ");
26
+      xSnprintf(daysbuf, sizeof(daysbuf), "1 day, ");
27
    } else {
28
       daysbuf[0] = '\0';
29
    }
30
-   snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds);
31
+   xSnprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds);
32
 }
33
 
34
 MeterClass UptimeMeter_class = {
(-)sysutils/htop/files/patch-XAlloc.c (+24 lines)
Line 0 Link Here
1
--- XAlloc.c.orig	2018-01-17 03:09:14.682069000 +0800
2
+++ XAlloc.c	2018-01-17 03:09:45.561807000 +0800
3
@@ -5,11 +5,11 @@
4
 #ifndef _GNU_SOURCE
5
 #define _GNU_SOURCE
6
 #endif
7
-#include <err.h>
8
 #include <stdlib.h>
9
 #include <string.h>
10
 
11
 /*{
12
+#include <err.h>
13
 #include <assert.h>
14
 #include <stdlib.h>
15
 }*/
16
@@ -44,6 +44,8 @@
17
    return data;
18
 }
19
 
20
+#define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0)
21
+
22
 #undef xStrdup
23
 #undef xStrdup_
24
 #ifdef NDEBUG
(-)sysutils/htop/files/patch-XAlloc.h (+19 lines)
Line 0 Link Here
1
--- XAlloc.h.orig	2018-01-17 03:09:59.837795000 +0800
2
+++ XAlloc.h	2018-01-17 03:10:32.180486000 +0800
3
@@ -7,6 +7,7 @@
4
 #define _GNU_SOURCE
5
 #endif
6
 
7
+#include <err.h>
8
 #include <assert.h>
9
 #include <stdlib.h>
10
 
11
@@ -16,6 +17,8 @@
12
 
13
 void* xRealloc(void* ptr, size_t size);
14
 
15
+#define xSnprintf(fmt, len, ...) do { int _l=len; int _n=snprintf(fmt, _l, __VA_ARGS__); if (!(_n > -1 && _n < _l)) { curs_set(1); endwin(); err(1, NULL); } } while(0)
16
+
17
 #undef xStrdup
18
 #undef xStrdup_
19
 #ifdef NDEBUG
(-)sysutils/htop/files/patch-configure.ac (+32 lines)
Line 0 Link Here
1
--- configure.ac.orig	2018-01-17 02:50:30.919198000 +0800
2
+++ configure.ac	2018-01-17 03:20:06.328268000 +0800
3
@@ -2,7 +2,6 @@
4
 # Process this file with autoconf to produce a configure script.
5
 
6
 AC_PREREQ(2.65)
7
-LT_PREREQ([2.4.2])
8
 AC_INIT([htop],[2.0.2],[hisham@gobolinux.org])
9
 
10
 SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(date +%s)}"
11
@@ -26,8 +25,6 @@
12
 # Required by hwloc scripts
13
 AC_USE_SYSTEM_EXTENSIONS
14
 
15
-LT_INIT([disable-shared static])
16
-
17
 # Checks for platform.
18
 # ----------------------------------------------------------------------
19
 case "$target_os" in
20
@@ -249,6 +246,12 @@
21
    AC_CHECK_HEADERS([hwloc.h],[:], [missing_headers="$missing_headers $ac_header"])
22
 fi
23
 
24
+AC_ARG_ENABLE(setuid, [AS_HELP_STRING([--enable-setuid], [enable setuid support for platforms that need it])],, enable_setuid="no")
25
+if test "x$enable_setuid" = xyes
26
+then
27
+   AC_DEFINE(HAVE_SETUID_ENABLED, 1, [Define if setuid support should be enabled.])
28
+fi
29
+
30
 # Bail out on errors.
31
 # ----------------------------------------------------------------------
32
 if test ! -z "$missing_libraries"; then
(-)sysutils/htop/files/patch-freebsd__FreeBSDCRT.c (+32 lines)
Line 0 Link Here
1
--- freebsd/FreeBSDCRT.c.orig	2018-01-17 03:34:43.741989000 +0800
2
+++ freebsd/FreeBSDCRT.c	2018-01-17 03:35:31.892102000 +0800
3
@@ -9,13 +9,26 @@
4
 #include "CRT.h"
5
 #include <stdio.h>
6
 #include <stdlib.h>
7
+#ifdef HAVE_EXECINFO_H
8
+#include <execinfo.h>
9
+#endif
10
 
11
 void CRT_handleSIGSEGV(int sgn) {
12
    (void) sgn;
13
    CRT_done();
14
-   fprintf(stderr, "\n\nhtop " VERSION " aborting.\n");
15
-   fprintf(stderr, "\nUnfortunately, you seem to be using an unsupported platform!");
16
-   fprintf(stderr, "\nPlease contact your platform package maintainer!\n\n");
17
+   fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n");
18
+   #ifdef HAVE_EXECINFO_H
19
+   size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
20
+   fprintf(stderr, "\n Please include in your report the following backtrace: \n");
21
+   backtrace_symbols_fd(backtraceArray, size, 2);
22
+   fprintf(stderr, "\nAdditionally, in order to make the above backtrace useful,");
23
+   fprintf(stderr, "\nplease also run the following command to generate a disassembly of your binary:");
24
+   fprintf(stderr, "\n\n   objdump -d `which htop` > ~/htop.objdump");
25
+   fprintf(stderr, "\n\nand then attach the file ~/htop.objdump to your bug report.");
26
+   fprintf(stderr, "\n\nThank you for helping to improve htop!\n\n");
27
+   #else
28
+   fprintf(stderr, "\nPlease contact FreeBSD package maintainer!\n\n");
29
+   #endif
30
    abort();
31
 }
32
 
(-)sysutils/htop/files/patch-freebsd__FreeBSDCRT.h (+12 lines)
Line 0 Link Here
1
--- freebsd/FreeBSDCRT.h.orig	2018-01-17 03:35:55.489304000 +0800
2
+++ freebsd/FreeBSDCRT.h	2018-01-17 03:36:12.385351000 +0800
3
@@ -9,6 +9,9 @@
4
 in the source distribution for its full text.
5
 */
6
 
7
+#ifdef HAVE_EXECINFO_H
8
+#endif
9
+
10
 void CRT_handleSIGSEGV(int sgn);
11
 
12
 
(-)sysutils/htop/files/patch-freebsd__FreeBSDProcess.c (+34 lines)
Line 0 Link Here
1
--- freebsd/FreeBSDProcess.c.orig	2018-01-17 02:01:23.746071000 +0800
2
+++ freebsd/FreeBSDProcess.c	2018-01-17 03:11:22.464126000 +0800
3
@@ -61,8 +61,8 @@
4
    [STATE] = { .name = "STATE", .title = "S ", .description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)", .flags = 0, },
5
    [PPID] = { .name = "PPID", .title = "   PPID ", .description = "Parent process ID", .flags = 0, },
6
    [PGRP] = { .name = "PGRP", .title = "   PGRP ", .description = "Process group ID", .flags = 0, },
7
-   [SESSION] = { .name = "SESSION", .title = "   SESN ", .description = "Process's session ID", .flags = 0, },
8
-   [TTY_NR] = { .name = "TTY_NR", .title = "  TTY ", .description = "Controlling terminal", .flags = 0, },
9
+   [SESSION] = { .name = "SESSION", .title = "    SID ", .description = "Process's session ID", .flags = 0, },
10
+   [TTY_NR] = { .name = "TTY_NR", .title = "    TTY ", .description = "Controlling terminal", .flags = 0, },
11
    [TPGID] = { .name = "TPGID", .title = "  TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
12
    [MINFLT] = { .name = "MINFLT", .title = "     MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
13
    [MAJFLT] = { .name = "MAJFLT", .title = "     MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
14
@@ -92,7 +92,7 @@
15
    { .id = TPGID, .label = "TPGID" },
16
    { .id = TGID, .label = "TGID" },
17
    { .id = PGRP, .label = "PGRP" },
18
-   { .id = SESSION, .label = "SESN" },
19
+   { .id = SESSION, .label = "SID" },
20
    { .id = 0, .label = NULL },
21
 };
22
 
23
@@ -117,9 +117,9 @@
24
    int n = sizeof(buffer) - 1;
25
    switch ((int) field) {
26
    // add FreeBSD-specific fields here
27
-   case JID: snprintf(buffer, n, Process_pidFormat, fp->jid); break;
28
+   case JID: xSnprintf(buffer, n, Process_pidFormat, fp->jid); break;
29
    case JAIL:{
30
-      snprintf(buffer, n, "%-11s ", fp->jname); break;
31
+      xSnprintf(buffer, n, "%-11s ", fp->jname); break;
32
       if (buffer[11] != '\0') {
33
          buffer[11] = ' ';
34
          buffer[12] = '\0';
(-)sysutils/htop/files/patch-freebsd__FreeBSDProcessList.c (+19 lines)
Line 0 Link Here
1
--- freebsd/FreeBSDProcessList.c.orig	2016-07-22 04:12:45.000000000 +0800
2
+++ freebsd/FreeBSDProcessList.c	2018-01-17 03:32:10.420406000 +0800
3
@@ -398,7 +398,7 @@
4
       jid = jail_get(jiov, 6, 0);
5
       if (jid < 0) {
6
          if (!jail_errmsg[0])
7
-            snprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
8
+            xSnprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
9
             return NULL;
10
       } else if (jid == kproc->ki_jid) {
11
          jname = xStrdup(jnamebuf);
12
@@ -482,7 +482,6 @@
13
       // from FreeBSD source /src/usr.bin/top/machine.c
14
       proc->m_size = kproc->ki_size / 1024 / pageSizeKb;
15
       proc->m_resident = kproc->ki_rssize;
16
-      proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
17
       proc->nlwp = kproc->ki_numthreads;
18
       proc->time = (kproc->ki_runtime + 5000) / 10000;
19
 
(-)sysutils/htop/files/patch-freebsd__Platform.c (+20 lines)
Line 0 Link Here
1
--- freebsd/Platform.c.orig	2018-01-17 01:52:20.062230000 +0800
2
+++ freebsd/Platform.c	2018-01-17 01:52:49.637588000 +0800
3
@@ -43,7 +43,7 @@
4
 
5
 int Platform_numberOfFields = LAST_PROCESSFIELD;
6
 
7
-SignalItem Platform_signals[] = {
8
+const SignalItem Platform_signals[] = {
9
    { .name = " 0 Cancel",    .number =  0 },
10
    { .name = " 1 SIGHUP",    .number =  1 },
11
    { .name = " 2 SIGINT",    .number =  2 },
12
@@ -80,7 +80,7 @@
13
    { .name = "33 SIGLIBRT",  .number = 33 },
14
 };
15
 
16
-unsigned int Platform_numberOfSignals = sizeof(Platform_signals)/sizeof(SignalItem);
17
+const unsigned int Platform_numberOfSignals = sizeof(Platform_signals)/sizeof(SignalItem);
18
 
19
 void Platform_setBindings(Htop_Action* keys) {
20
    (void) keys;
(-)sysutils/htop/files/patch-freebsd__Platform.h (+14 lines)
Line 0 Link Here
1
--- freebsd/Platform.h.orig	2018-01-17 01:53:07.196304000 +0800
2
+++ freebsd/Platform.h	2018-01-17 01:53:29.415835000 +0800
3
@@ -24,9 +24,9 @@
4
 
5
 extern int Platform_numberOfFields;
6
 
7
-extern SignalItem Platform_signals[];
8
+const extern SignalItem Platform_signals[];
9
 
10
-extern unsigned int Platform_numberOfSignals;
11
+const extern unsigned int Platform_numberOfSignals;
12
 
13
 void Platform_setBindings(Htop_Action* keys);
14
 
(-)sysutils/htop/files/patch-htop.1.in (+11 lines)
Line 0 Link Here
1
--- htop.1.in.orig	2018-01-17 02:10:17.117935000 +0800
2
+++ htop.1.in	2018-01-17 02:10:26.605171000 +0800
3
@@ -217,7 +217,7 @@
4
 .B PGRP
5
 The process's group ID.
6
 .TP
7
-.B SESSION (SESN)
8
+.B SESSION (SID)
9
 The process's session ID.
10
 .TP 
11
 .B TTY_NR (TTY)
(-)sysutils/htop/files/patch-scripts__MakeHeader.py (+115 lines)
Line 0 Link Here
1
--- scripts/MakeHeader.py.orig	2018-01-17 03:13:36.980691000 +0800
2
+++ scripts/MakeHeader.py	2018-01-17 03:13:41.657914000 +0800
3
@@ -1,6 +1,12 @@
4
 #!/usr/bin/env python
5
-
6
 import os, sys, string
7
+try:
8
+   from cStringIO import StringIO
9
+except ImportError:
10
+   try:
11
+      from StringIO import StringIO
12
+   except ImportError:
13
+      from io import StringIO
14
 
15
 ANY=1
16
 COPY=2
17
@@ -13,23 +19,15 @@
18
 file = open(sys.argv[1])
19
 name = sys.argv[1][:-2]
20
 
21
-out = open(name + ".h", "w")
22
-class writer:
23
-   def __init__(self, file):
24
-      self.file = file
25
-   def write(self, text):
26
-      self.file.write(text + "\n")
27
-out = writer(out)
28
-
29
-print("Generating "+name+".h")
30
+out = StringIO()
31
 
32
 selfheader = '#include "' + name + '.h"'
33
 
34
-out.write( "/* Do not edit this file. It was automatically generated. */" )
35
-out.write( "" )
36
+out.write( "/* Do not edit this file. It was automatically generated. */\n" )
37
+out.write( "\n" )
38
 
39
-out.write( "#ifndef HEADER_" + os.path.basename(name) )
40
-out.write( "#define HEADER_" + os.path.basename(name) )
41
+out.write( "#ifndef HEADER_" + os.path.basename(name) + "\n")
42
+out.write( "#define HEADER_" + os.path.basename(name) + "\n")
43
 is_blank = False
44
 for line in file.readlines():
45
    line = line[:-1]
46
@@ -41,7 +39,7 @@
47
       elif line.find("#include") == 0:
48
          pass
49
       elif line.find("htop - ") == 0 and line[-2:] == ".c":
50
-         out.write(line[:-2] + ".h")
51
+         out.write(line[:-2] + ".h\n")
52
       elif line.find("static ") != -1:
53
          if line[-1] == "{":
54
             state = SKIP
55
@@ -52,31 +50,31 @@
56
          static = 0
57
          equals = line.find(" = ")
58
          if line[-3:] == "= {":
59
-            out.write( "extern " + line[:-4] + ";" )
60
+            out.write( "extern " + line[:-4] + ";\n" )
61
             state = SKIP
62
          elif equals != -1:
63
-            out.write("extern " + line[:equals] + ";" )
64
+            out.write("extern " + line[:equals] + ";\n" )
65
          elif line.startswith("typedef struct"):
66
             state = SKIP
67
          elif line[-1] == "{":
68
-            out.write( line[:-2].replace("inline", "extern") + ";" )
69
+            out.write( line[:-2].replace("inline", "extern") + ";\n" )
70
             state = SKIP
71
          else:
72
-            out.write( line )
73
+            out.write( line + "\n")
74
          is_blank = False
75
       elif line == "":
76
          if not is_blank:
77
-            out.write( line )
78
+            out.write( line + "\n")
79
          is_blank = True
80
       else:
81
-         out.write( line )
82
+         out.write( line  + "\n")
83
          is_blank = False
84
    elif state == COPY:
85
       is_blank = False
86
       if line == "}*/":
87
          state = ANY
88
       else:
89
-         out.write( line )
90
+         out.write( line + "\n")
91
    elif state == SKIP:
92
       is_blank = False
93
       if len(line) >= 1 and line[0] == "}":
94
@@ -89,5 +87,19 @@
95
       is_blank = False
96
       state = ANY
97
 
98
-out.write( "" )
99
-out.write( "#endif" )
100
+out.write( "\n" )
101
+out.write( "#endif\n" )
102
+
103
+# only write a new .h file if something changed.
104
+# This prevents a lot of recompilation during development
105
+out.seek(0)
106
+try:
107
+   with open(name + ".h", "r") as orig:
108
+      origcontents = orig.readlines()
109
+except:
110
+   origcontents = ""
111
+if origcontents != out.readlines():
112
+   with open(name + ".h", "w") as new:
113
+      print("Writing "+name+".h")
114
+      new.write(out.getvalue())
115
+out.close()

Return to bug 225232