mirror of https://github.com/xzeldon/htop.git
Resolve merge conflicts, merge #298 "Macro cleanup" from @BenBE
This commit is contained in:
commit
bb908f3dc4
73
Action.c
73
Action.c
|
@ -66,13 +66,13 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess)
|
||||||
Process* selected = (Process*)Panel_getSelected(panel);
|
Process* selected = (Process*)Panel_getSelected(panel);
|
||||||
if (selected && selected->pid == pid)
|
if (selected && selected->pid == pid)
|
||||||
return Panel_getSelected(list);
|
return Panel_getSelected(list);
|
||||||
else
|
|
||||||
beep();
|
beep();
|
||||||
} else {
|
} else {
|
||||||
return Panel_getSelected(list);
|
return Panel_getSelected(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,14 +129,18 @@ static void tagAllChildren(Panel* panel, Process* parent) {
|
||||||
|
|
||||||
static bool expandCollapse(Panel* panel) {
|
static bool expandCollapse(Panel* panel) {
|
||||||
Process* p = (Process*) Panel_getSelected(panel);
|
Process* p = (Process*) Panel_getSelected(panel);
|
||||||
if (!p) return false;
|
if (!p)
|
||||||
|
return false;
|
||||||
|
|
||||||
p->showChildren = !p->showChildren;
|
p->showChildren = !p->showChildren;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool collapseIntoParent(Panel* panel) {
|
static bool collapseIntoParent(Panel* panel) {
|
||||||
Process* p = (Process*) Panel_getSelected(panel);
|
Process* p = (Process*) Panel_getSelected(panel);
|
||||||
if (!p) return false;
|
if (!p)
|
||||||
|
return false;
|
||||||
|
|
||||||
pid_t ppid = Process_getParentPid(p);
|
pid_t ppid = Process_getParentPid(p);
|
||||||
for (int i = 0; i < Panel_size(panel); i++) {
|
for (int i = 0; i < Panel_size(panel); i++) {
|
||||||
Process* q = (Process*) Panel_get(panel, i);
|
Process* q = (Process*) Panel_get(panel, i);
|
||||||
|
@ -166,6 +170,7 @@ static Htop_Reaction sortBy(State* st) {
|
||||||
Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i]));
|
Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i]));
|
||||||
if (fields[i] == st->settings->sortKey)
|
if (fields[i] == st->settings->sortKey)
|
||||||
Panel_setSelected(sortPanel, i);
|
Panel_setSelected(sortPanel, i);
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
ListItem* field = (ListItem*) Action_pickFromVector(st, sortPanel, 15, false);
|
ListItem* field = (ListItem*) Action_pickFromVector(st, sortPanel, 15, false);
|
||||||
|
@ -173,8 +178,10 @@ static Htop_Reaction sortBy(State* st) {
|
||||||
reaction |= Action_setSortKey(st->settings, field->key);
|
reaction |= Action_setSortKey(st->settings, field->key);
|
||||||
}
|
}
|
||||||
Object_delete(sortPanel);
|
Object_delete(sortPanel);
|
||||||
|
|
||||||
if (st->pauseProcessUpdate)
|
if (st->pauseProcessUpdate)
|
||||||
ProcessList_sort(st->pl);
|
ProcessList_sort(st->pl);
|
||||||
|
|
||||||
return reaction | HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
return reaction | HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +223,10 @@ static Htop_Reaction actionToggleProgramPath(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionToggleTreeView(State* st) {
|
static Htop_Reaction actionToggleTreeView(State* st) {
|
||||||
st->settings->treeView = !st->settings->treeView;
|
st->settings->treeView = !st->settings->treeView;
|
||||||
if (st->settings->treeView) st->settings->direction = 1;
|
if (st->settings->treeView) {
|
||||||
|
st->settings->direction = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ProcessList_expandTree(st->pl);
|
ProcessList_expandTree(st->pl);
|
||||||
return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
||||||
}
|
}
|
||||||
|
@ -287,13 +297,18 @@ static Htop_Reaction actionQuit(ATTR_UNUSED State* st) {
|
||||||
static Htop_Reaction actionSetAffinity(State* st) {
|
static Htop_Reaction actionSetAffinity(State* st) {
|
||||||
if (st->pl->cpuCount == 1)
|
if (st->pl->cpuCount == 1)
|
||||||
return HTOP_OK;
|
return HTOP_OK;
|
||||||
|
|
||||||
#if (defined(HAVE_LIBHWLOC) || defined(HAVE_LINUX_AFFINITY))
|
#if (defined(HAVE_LIBHWLOC) || defined(HAVE_LINUX_AFFINITY))
|
||||||
Panel* panel = st->panel;
|
Panel* panel = st->panel;
|
||||||
|
|
||||||
Process* p = (Process*) Panel_getSelected(panel);
|
Process* p = (Process*) Panel_getSelected(panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
Affinity* affinity1 = Affinity_get(p, st->pl);
|
Affinity* affinity1 = Affinity_get(p, st->pl);
|
||||||
if (!affinity1) return HTOP_OK;
|
if (!affinity1)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width);
|
Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width);
|
||||||
width += 1; /* we add a gap between the panels */
|
width += 1; /* we add a gap between the panels */
|
||||||
|
@ -303,7 +318,8 @@ static Htop_Reaction actionSetAffinity(State* st) {
|
||||||
if (set) {
|
if (set) {
|
||||||
Affinity* affinity2 = AffinityPanel_getAffinity(affinityPanel, st->pl);
|
Affinity* affinity2 = AffinityPanel_getAffinity(affinityPanel, st->pl);
|
||||||
bool ok = MainPanel_foreachProcess((MainPanel*)panel, Affinity_set, (Arg) { .v = affinity2 }, NULL);
|
bool ok = MainPanel_foreachProcess((MainPanel*)panel, Affinity_set, (Arg) { .v = affinity2 }, NULL);
|
||||||
if (!ok) beep();
|
if (!ok)
|
||||||
|
beep();
|
||||||
Affinity_delete(affinity2);
|
Affinity_delete(affinity2);
|
||||||
}
|
}
|
||||||
Object_delete(affinityPanel);
|
Object_delete(affinityPanel);
|
||||||
|
@ -363,7 +379,9 @@ static Htop_Reaction actionSetup(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionLsof(State* st) {
|
static Htop_Reaction actionLsof(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
OpenFilesScreen* ofs = OpenFilesScreen_new(p);
|
OpenFilesScreen* ofs = OpenFilesScreen_new(p);
|
||||||
InfoScreen_run((InfoScreen*)ofs);
|
InfoScreen_run((InfoScreen*)ofs);
|
||||||
OpenFilesScreen_delete((Object*)ofs);
|
OpenFilesScreen_delete((Object*)ofs);
|
||||||
|
@ -385,7 +403,9 @@ static Htop_Reaction actionShowLocks(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionStrace(State* st) {
|
static Htop_Reaction actionStrace(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
TraceScreen* ts = TraceScreen_new(p);
|
TraceScreen* ts = TraceScreen_new(p);
|
||||||
bool ok = TraceScreen_forkTracer(ts);
|
bool ok = TraceScreen_forkTracer(ts);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
@ -399,7 +419,9 @@ static Htop_Reaction actionStrace(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionTag(State* st) {
|
static Htop_Reaction actionTag(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
Process_toggleTag(p);
|
Process_toggleTag(p);
|
||||||
Panel_onKey(st->panel, KEY_DOWN);
|
Panel_onKey(st->panel, KEY_DOWN);
|
||||||
return HTOP_OK;
|
return HTOP_OK;
|
||||||
|
@ -415,7 +437,10 @@ static Htop_Reaction actionTogglePauseProcessUpdate(State *st) {
|
||||||
return HTOP_REFRESH | HTOP_REDRAW_BAR;
|
return HTOP_REFRESH | HTOP_REDRAW_BAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct { const char* key; const char* info; } helpLeft[] = {
|
static const struct {
|
||||||
|
const char* key;
|
||||||
|
const char* info;
|
||||||
|
} helpLeft[] = {
|
||||||
{ .key = " Arrows: ", .info = "scroll process list" },
|
{ .key = " Arrows: ", .info = "scroll process list" },
|
||||||
{ .key = " Digits: ", .info = "incremental PID search" },
|
{ .key = " Digits: ", .info = "incremental PID search" },
|
||||||
{ .key = " F3 /: ", .info = "incremental name search" },
|
{ .key = " F3 /: ", .info = "incremental name search" },
|
||||||
|
@ -434,7 +459,10 @@ static const struct { const char* key; const char* info; } helpLeft[] = {
|
||||||
{ .key = NULL, .info = NULL }
|
{ .key = NULL, .info = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct { const char* key; const char* info; } helpRight[] = {
|
static const struct {
|
||||||
|
const char* key;
|
||||||
|
const char* info;
|
||||||
|
} helpRight[] = {
|
||||||
{ .key = " Space: ", .info = "tag process" },
|
{ .key = " Space: ", .info = "tag process" },
|
||||||
{ .key = " c: ", .info = "tag process and its children" },
|
{ .key = " c: ", .info = "tag process and its children" },
|
||||||
{ .key = " U: ", .info = "untag all processes" },
|
{ .key = " U: ", .info = "untag all processes" },
|
||||||
|
@ -456,6 +484,11 @@ static const struct { const char* key; const char* info; } helpRight[] = {
|
||||||
{ .key = NULL, .info = NULL }
|
{ .key = NULL, .info = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void addattrstr( int attr, const char* str) {
|
||||||
|
attrset(attr);
|
||||||
|
addstr(str);
|
||||||
|
}
|
||||||
|
|
||||||
static Htop_Reaction actionHelp(State* st) {
|
static Htop_Reaction actionHelp(State* st) {
|
||||||
Settings* settings = st->settings;
|
Settings* settings = st->settings;
|
||||||
|
|
||||||
|
@ -473,7 +506,7 @@ static Htop_Reaction actionHelp(State* st) {
|
||||||
attrset(CRT_colors[DEFAULT_COLOR]);
|
attrset(CRT_colors[DEFAULT_COLOR]);
|
||||||
line++;
|
line++;
|
||||||
mvaddstr(line++, 0, "CPU usage bar: ");
|
mvaddstr(line++, 0, "CPU usage bar: ");
|
||||||
#define addattrstr(a,s) attrset(a);addstr(s)
|
|
||||||
addattrstr(CRT_colors[BAR_BORDER], "[");
|
addattrstr(CRT_colors[BAR_BORDER], "[");
|
||||||
if (settings->detailedCPUTime) {
|
if (settings->detailedCPUTime) {
|
||||||
addattrstr(CRT_colors[CPU_NICE_TEXT], "low"); addstr("/");
|
addattrstr(CRT_colors[CPU_NICE_TEXT], "low"); addstr("/");
|
||||||
|
@ -563,14 +596,18 @@ static Htop_Reaction actionUntagAll(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionTagAllChildren(State* st) {
|
static Htop_Reaction actionTagAllChildren(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
tagAllChildren(st->panel, p);
|
tagAllChildren(st->panel, p);
|
||||||
return HTOP_OK;
|
return HTOP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Htop_Reaction actionShowEnvScreen(State* st) {
|
static Htop_Reaction actionShowEnvScreen(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
EnvScreen* es = EnvScreen_new(p);
|
EnvScreen* es = EnvScreen_new(p);
|
||||||
InfoScreen_run((InfoScreen*)es);
|
InfoScreen_run((InfoScreen*)es);
|
||||||
EnvScreen_delete((Object*)es);
|
EnvScreen_delete((Object*)es);
|
||||||
|
@ -581,7 +618,9 @@ static Htop_Reaction actionShowEnvScreen(State* st) {
|
||||||
|
|
||||||
static Htop_Reaction actionShowCommandScreen(State* st) {
|
static Htop_Reaction actionShowCommandScreen(State* st) {
|
||||||
Process* p = (Process*) Panel_getSelected(st->panel);
|
Process* p = (Process*) Panel_getSelected(st->panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
CommandScreen* cmdScr = CommandScreen_new(p);
|
CommandScreen* cmdScr = CommandScreen_new(p);
|
||||||
InfoScreen_run((InfoScreen*)cmdScr);
|
InfoScreen_run((InfoScreen*)cmdScr);
|
||||||
CommandScreen_delete((Object*)cmdScr);
|
CommandScreen_delete((Object*)cmdScr);
|
||||||
|
|
|
@ -89,12 +89,15 @@ bool Affinity_set(Process* proc, Arg arg) {
|
||||||
Affinity* Affinity_get(Process* proc, ProcessList* pl) {
|
Affinity* Affinity_get(Process* proc, ProcessList* pl) {
|
||||||
cpu_set_t cpuset;
|
cpu_set_t cpuset;
|
||||||
bool ok = (sched_getaffinity(proc->pid, sizeof(cpu_set_t), &cpuset) == 0);
|
bool ok = (sched_getaffinity(proc->pid, sizeof(cpu_set_t), &cpuset) == 0);
|
||||||
if (!ok) return NULL;
|
if (!ok)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Affinity* affinity = Affinity_new(pl);
|
Affinity* affinity = Affinity_new(pl);
|
||||||
for (int i = 0; i < pl->cpuCount; i++) {
|
for (int i = 0; i < pl->cpuCount; i++) {
|
||||||
if (CPU_ISSET(i, &cpuset))
|
if (CPU_ISSET(i, &cpuset)) {
|
||||||
Affinity_add(affinity, i);
|
Affinity_add(affinity, i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return affinity;
|
return affinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,13 @@ static void MaskItem_display(const Object* cast, RichString* out) {
|
||||||
const MaskItem* this = (const MaskItem*)cast;
|
const MaskItem* this = (const MaskItem*)cast;
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
RichString_append(out, CRT_colors[CHECK_BOX], "[");
|
RichString_append(out, CRT_colors[CHECK_BOX], "[");
|
||||||
if (this->value == 2)
|
if (this->value == 2) {
|
||||||
RichString_append(out, CRT_colors[CHECK_MARK], "x");
|
RichString_append(out, CRT_colors[CHECK_MARK], "x");
|
||||||
else if (this->value == 1)
|
} else if (this->value == 1) {
|
||||||
RichString_append(out, CRT_colors[CHECK_MARK], "o");
|
RichString_append(out, CRT_colors[CHECK_MARK], "o");
|
||||||
else
|
} else {
|
||||||
RichString_append(out, CRT_colors[CHECK_MARK], " ");
|
RichString_append(out, CRT_colors[CHECK_MARK], " ");
|
||||||
|
}
|
||||||
RichString_append(out, CRT_colors[CHECK_BOX], "]");
|
RichString_append(out, CRT_colors[CHECK_BOX], "]");
|
||||||
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
|
RichString_append(out, CRT_colors[CHECK_TEXT], " ");
|
||||||
if (this->indent) {
|
if (this->indent) {
|
||||||
|
@ -178,12 +179,13 @@ static void AffinityPanel_update(AffinityPanel* this, bool keepSelected) {
|
||||||
Panel_prune(super);
|
Panel_prune(super);
|
||||||
|
|
||||||
#ifdef HAVE_LIBHWLOC
|
#ifdef HAVE_LIBHWLOC
|
||||||
if (this->topoView)
|
if (this->topoView) {
|
||||||
AffinityPanel_updateTopo(this, this->topoRoot);
|
AffinityPanel_updateTopo(this, this->topoRoot);
|
||||||
else {
|
} else {
|
||||||
for (int i = 0; i < Vector_size(this->cpuids); i++)
|
for (int i = 0; i < Vector_size(this->cpuids); i++) {
|
||||||
AffinityPanel_updateItem(this, (MaskItem*) Vector_get(this->cpuids, i));
|
AffinityPanel_updateItem(this, (MaskItem*) Vector_get(this->cpuids, i));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
Panel_splice(super, this->cpuids);
|
Panel_splice(super, this->cpuids);
|
||||||
#endif
|
#endif
|
||||||
|
@ -304,14 +306,16 @@ static MaskItem *AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, u
|
||||||
hwloc_bitmap_and(result, obj->complete_cpuset, this->workCpuset);
|
hwloc_bitmap_and(result, obj->complete_cpuset, this->workCpuset);
|
||||||
int weight = hwloc_bitmap_weight(result);
|
int weight = hwloc_bitmap_weight(result);
|
||||||
hwloc_bitmap_free(result);
|
hwloc_bitmap_free(result);
|
||||||
if (weight == 0 || weight == (hwloc_bitmap_weight(this->workCpuset) + hwloc_bitmap_weight(obj->complete_cpuset)))
|
if (weight == 0 || weight == (hwloc_bitmap_weight(this->workCpuset) + hwloc_bitmap_weight(obj->complete_cpuset))) {
|
||||||
item->sub_tree = 2;
|
item->sub_tree = 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* "[x] " + "|- " * depth + ("- ")?(if root node) + name */
|
/* "[x] " + "|- " * depth + ("- ")?(if root node) + name */
|
||||||
unsigned width = 4 + 3 * depth + (2 * !depth) + strlen(buf);
|
unsigned width = 4 + 3 * depth + (2 * !depth) + strlen(buf);
|
||||||
if (width > this->width)
|
if (width > this->width) {
|
||||||
this->width = width;
|
this->width = width;
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -323,8 +327,10 @@ static MaskItem *AffinityPanel_buildTopology(AffinityPanel* this, hwloc_obj_t ob
|
||||||
} else {
|
} else {
|
||||||
indent &= ~(1u << obj->depth);
|
indent &= ~(1u << obj->depth);
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < obj->arity; i++)
|
|
||||||
|
for (unsigned i = 0; i < obj->arity; i++) {
|
||||||
AffinityPanel_buildTopology(this, obj->children[i], indent, item);
|
AffinityPanel_buildTopology(this, obj->children[i], indent, item);
|
||||||
|
}
|
||||||
|
|
||||||
return parent == NULL ? item : NULL;
|
return parent == NULL ? item : NULL;
|
||||||
}
|
}
|
||||||
|
@ -382,8 +388,9 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width) {
|
||||||
char number[16];
|
char number[16];
|
||||||
xSnprintf(number, 9, "CPU %d", Settings_cpuId(pl->settings, i));
|
xSnprintf(number, 9, "CPU %d", Settings_cpuId(pl->settings, i));
|
||||||
unsigned cpu_width = 4 + strlen(number);
|
unsigned cpu_width = 4 + strlen(number);
|
||||||
if (cpu_width > this->width)
|
if (cpu_width > this->width) {
|
||||||
this->width = cpu_width;
|
this->width = cpu_width;
|
||||||
|
}
|
||||||
|
|
||||||
bool isSet = false;
|
bool isSet = false;
|
||||||
if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
|
if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
|
||||||
|
@ -402,8 +409,9 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity, int* width) {
|
||||||
this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(pl->topology), 0, NULL);
|
this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(pl->topology), 0, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (width)
|
if (width) {
|
||||||
*width = this->width;
|
*width = this->width;
|
||||||
|
}
|
||||||
|
|
||||||
AffinityPanel_update(this, false);
|
AffinityPanel_update(this, false);
|
||||||
|
|
||||||
|
@ -422,9 +430,10 @@ Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl) {
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < this->pl->cpuCount; i++) {
|
for (int i = 0; i < this->pl->cpuCount; i++) {
|
||||||
MaskItem* item = (MaskItem*)Vector_get(this->cpuids, i);
|
MaskItem* item = (MaskItem*)Vector_get(this->cpuids, i);
|
||||||
if (item->value)
|
if (item->value) {
|
||||||
Affinity_add(affinity, item->cpu);
|
Affinity_add(affinity, item->cpu);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return affinity;
|
return affinity;
|
||||||
|
|
|
@ -163,10 +163,13 @@ static void CPUMeterCommonInit(Meter *this, int ncol) {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (!meters[i])
|
if (!meters[i])
|
||||||
meters[i] = Meter_new(this->pl, start + i + 1, (const MeterClass*) Class(CPUMeter));
|
meters[i] = Meter_new(this->pl, start + i + 1, (const MeterClass*) Class(CPUMeter));
|
||||||
|
|
||||||
Meter_init(meters[i]);
|
Meter_init(meters[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->mode == 0)
|
if (this->mode == 0)
|
||||||
this->mode = BAR_METERMODE;
|
this->mode = BAR_METERMODE;
|
||||||
|
|
||||||
int h = Meter_modes[this->mode]->h;
|
int h = Meter_modes[this->mode]->h;
|
||||||
this->h = h * ((count + ncol - 1) / ncol);
|
this->h = h * ((count + ncol - 1) / ncol);
|
||||||
}
|
}
|
||||||
|
|
16
CRT.c
16
CRT.c
|
@ -619,13 +619,18 @@ void CRT_init(int delay, int colorScheme, bool allowUnicode) {
|
||||||
keypad(stdscr, true);
|
keypad(stdscr, true);
|
||||||
mouseinterval(0);
|
mouseinterval(0);
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
if (has_colors())
|
|
||||||
|
if (has_colors()) {
|
||||||
start_color();
|
start_color();
|
||||||
|
}
|
||||||
|
|
||||||
CRT_termType = getenv("TERM");
|
CRT_termType = getenv("TERM");
|
||||||
if (String_eq(CRT_termType, "linux"))
|
if (String_eq(CRT_termType, "linux")) {
|
||||||
CRT_scrollHAmount = 20;
|
CRT_scrollHAmount = 20;
|
||||||
else
|
} else {
|
||||||
CRT_scrollHAmount = 5;
|
CRT_scrollHAmount = 5;
|
||||||
|
}
|
||||||
|
|
||||||
if (String_startsWith(CRT_termType, "xterm") || String_eq(CRT_termType, "vt220")) {
|
if (String_startsWith(CRT_termType, "xterm") || String_eq(CRT_termType, "vt220")) {
|
||||||
define_key("\033[H", KEY_HOME);
|
define_key("\033[H", KEY_HOME);
|
||||||
define_key("\033[F", KEY_END);
|
define_key("\033[F", KEY_END);
|
||||||
|
@ -670,10 +675,11 @@ void CRT_init(int delay, int colorScheme, bool allowUnicode) {
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
#ifdef HAVE_LIBNCURSESW
|
#ifdef HAVE_LIBNCURSESW
|
||||||
if (allowUnicode && String_eq(nl_langinfo(CODESET), "UTF-8"))
|
if (allowUnicode && String_eq(nl_langinfo(CODESET), "UTF-8")) {
|
||||||
CRT_utf8 = true;
|
CRT_utf8 = true;
|
||||||
else
|
} else {
|
||||||
CRT_utf8 = false;
|
CRT_utf8 = false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
(void) allowUnicode;
|
(void) allowUnicode;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -97,6 +97,7 @@ static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
|
||||||
int size = ScreenManager_size(this->scr);
|
int size = ScreenManager_size(this->scr);
|
||||||
for (int i = 1; i < size; i++)
|
for (int i = 1; i < size; i++)
|
||||||
ScreenManager_remove(this->scr, 1);
|
ScreenManager_remove(this->scr, 1);
|
||||||
|
|
||||||
switch (selected) {
|
switch (selected) {
|
||||||
case 0:
|
case 0:
|
||||||
CategoriesPanel_makeMetersPage(this);
|
CategoriesPanel_makeMetersPage(this);
|
||||||
|
|
15
CheckItem.c
15
CheckItem.c
|
@ -26,10 +26,11 @@ static void CheckItem_display(const Object* cast, RichString* out) {
|
||||||
const CheckItem* this = (const CheckItem*)cast;
|
const CheckItem* this = (const CheckItem*)cast;
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
RichString_write(out, CRT_colors[CHECK_BOX], "[");
|
RichString_write(out, CRT_colors[CHECK_BOX], "[");
|
||||||
if (CheckItem_get(this))
|
if (CheckItem_get(this)) {
|
||||||
RichString_append(out, CRT_colors[CHECK_MARK], "x");
|
RichString_append(out, CRT_colors[CHECK_MARK], "x");
|
||||||
else
|
} else {
|
||||||
RichString_append(out, CRT_colors[CHECK_MARK], " ");
|
RichString_append(out, CRT_colors[CHECK_MARK], " ");
|
||||||
|
}
|
||||||
RichString_append(out, CRT_colors[CHECK_BOX], "] ");
|
RichString_append(out, CRT_colors[CHECK_BOX], "] ");
|
||||||
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
|
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
|
||||||
}
|
}
|
||||||
|
@ -56,15 +57,17 @@ CheckItem* CheckItem_newByVal(char* text, bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckItem_set(CheckItem* this, bool value) {
|
void CheckItem_set(CheckItem* this, bool value) {
|
||||||
if (this->ref)
|
if (this->ref) {
|
||||||
*(this->ref) = value;
|
*(this->ref) = value;
|
||||||
else
|
} else {
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckItem_get(const CheckItem* this) {
|
bool CheckItem_get(const CheckItem* this) {
|
||||||
if (this->ref)
|
if (this->ref) {
|
||||||
return *(this->ref);
|
return *(this->ref);
|
||||||
else
|
} else {
|
||||||
return this->value;
|
return this->value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
|
||||||
for (int i = 0; ColorSchemeNames[i] != NULL; i++)
|
for (int i = 0; ColorSchemeNames[i] != NULL; i++)
|
||||||
CheckItem_set((CheckItem*)Panel_get(super, i), false);
|
CheckItem_set((CheckItem*)Panel_get(super, i), false);
|
||||||
CheckItem_set((CheckItem*)Panel_get(super, mark), true);
|
CheckItem_set((CheckItem*)Panel_get(super, mark), true);
|
||||||
|
|
||||||
this->settings->colorScheme = mark;
|
this->settings->colorScheme = mark;
|
||||||
result = HANDLED;
|
result = HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ static void CommandScreen_scan(InfoScreen* this) {
|
||||||
int line_offset = 0, last_spc = -1, len;
|
int line_offset = 0, last_spc = -1, len;
|
||||||
for (; *p != '\0'; p++, line_offset++) {
|
for (; *p != '\0'; p++, line_offset++) {
|
||||||
line[line_offset] = *p;
|
line[line_offset] = *p;
|
||||||
if (*p == ' ') last_spc = line_offset;
|
if (*p == ' ') {
|
||||||
|
last_spc = line_offset;
|
||||||
|
}
|
||||||
|
|
||||||
if (line_offset == COLS) {
|
if (line_offset == COLS) {
|
||||||
len = (last_spc == -1) ? line_offset : last_spc;
|
len = (last_spc == -1) ? line_offset : last_spc;
|
||||||
|
|
|
@ -106,10 +106,11 @@ void FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
if (attr == -1)
|
if (attr == -1) {
|
||||||
attrset(CRT_colors[FUNCTION_BAR]);
|
attrset(CRT_colors[FUNCTION_BAR]);
|
||||||
else
|
} else {
|
||||||
attrset(attr);
|
attrset(attr);
|
||||||
|
}
|
||||||
mvaddstr(LINES - 1, x, buffer);
|
mvaddstr(LINES - 1, x, buffer);
|
||||||
attrset(CRT_colors[RESET_COLOR]);
|
attrset(CRT_colors[RESET_COLOR]);
|
||||||
x += strlen(buffer);
|
x += strlen(buffer);
|
||||||
|
@ -126,10 +127,11 @@ void FunctionBar_drawExtra(const FunctionBar* this, const char* buffer, int attr
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionBar_append(const char* buffer, int attr) {
|
void FunctionBar_append(const char* buffer, int attr) {
|
||||||
if (attr == -1)
|
if (attr == -1) {
|
||||||
attrset(CRT_colors[FUNCTION_BAR]);
|
attrset(CRT_colors[FUNCTION_BAR]);
|
||||||
else
|
} else {
|
||||||
attrset(attr);
|
attrset(attr);
|
||||||
|
}
|
||||||
mvaddstr(LINES - 1, currentLen, buffer);
|
mvaddstr(LINES - 1, currentLen, buffer);
|
||||||
attrset(CRT_colors[RESET_COLOR]);
|
attrset(CRT_colors[RESET_COLOR]);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ void Hashtable_delete(Hashtable* this) {
|
||||||
while (walk != NULL) {
|
while (walk != NULL) {
|
||||||
if (this->owner)
|
if (this->owner)
|
||||||
free(walk->value);
|
free(walk->value);
|
||||||
|
|
||||||
HashtableItem* savedWalk = walk;
|
HashtableItem* savedWalk = walk;
|
||||||
walk = savedWalk->next;
|
walk = savedWalk->next;
|
||||||
free(savedWalk);
|
free(savedWalk);
|
||||||
|
@ -90,10 +91,13 @@ void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
|
||||||
} else if ((*bucketPtr)->key == key) {
|
} else if ((*bucketPtr)->key == key) {
|
||||||
if (this->owner && (*bucketPtr)->value != value)
|
if (this->owner && (*bucketPtr)->value != value)
|
||||||
free((*bucketPtr)->value);
|
free((*bucketPtr)->value);
|
||||||
|
|
||||||
(*bucketPtr)->value = value;
|
(*bucketPtr)->value = value;
|
||||||
break;
|
break;
|
||||||
} else
|
} else {
|
||||||
bucketPtr = &((*bucketPtr)->next);
|
bucketPtr = &((*bucketPtr)->next);
|
||||||
|
}
|
||||||
|
|
||||||
assert(Hashtable_isConsistent(this));
|
assert(Hashtable_isConsistent(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,10 +138,11 @@ void* Hashtable_get(Hashtable* this, unsigned int key) {
|
||||||
} else if (bucketPtr->key == key) {
|
} else if (bucketPtr->key == key) {
|
||||||
assert(Hashtable_isConsistent(this));
|
assert(Hashtable_isConsistent(this));
|
||||||
return bucketPtr->value;
|
return bucketPtr->value;
|
||||||
} else
|
} else {
|
||||||
bucketPtr = bucketPtr->next;
|
bucketPtr = bucketPtr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
|
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
|
||||||
assert(Hashtable_isConsistent(this));
|
assert(Hashtable_isConsistent(this));
|
||||||
|
|
9
Header.c
9
Header.c
|
@ -88,7 +88,8 @@ MeterModeId Header_addMeterByName(Header* this, char* name, int column) {
|
||||||
int param = 0;
|
int param = 0;
|
||||||
if (paren) {
|
if (paren) {
|
||||||
int ok = sscanf(paren, "(%10d)", ¶m);
|
int ok = sscanf(paren, "(%10d)", ¶m);
|
||||||
if (!ok) param = 0;
|
if (!ok)
|
||||||
|
param = 0;
|
||||||
*paren = '\0';
|
*paren = '\0';
|
||||||
}
|
}
|
||||||
MeterModeId mode = TEXT_METERMODE;
|
MeterModeId mode = TEXT_METERMODE;
|
||||||
|
@ -100,8 +101,10 @@ MeterModeId Header_addMeterByName(Header* this, char* name, int column) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paren)
|
if (paren)
|
||||||
*paren = '(';
|
*paren = '(';
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +113,7 @@ void Header_setMode(Header* this, int i, MeterModeId mode, int column) {
|
||||||
|
|
||||||
if (i >= Vector_size(meters))
|
if (i >= Vector_size(meters))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Meter* meter = (Meter*) Vector_get(meters, i);
|
Meter* meter = (Meter*) Vector_get(meters, i);
|
||||||
Meter_setMode(meter, mode);
|
Meter_setMode(meter, mode);
|
||||||
}
|
}
|
||||||
|
@ -153,11 +157,12 @@ void Header_reinit(Header* this) {
|
||||||
Header_forEachColumn(this, col) {
|
Header_forEachColumn(this, col) {
|
||||||
for (int i = 0; i < Vector_size(this->columns[col]); i++) {
|
for (int i = 0; i < Vector_size(this->columns[col]); i++) {
|
||||||
Meter* meter = (Meter*) Vector_get(this->columns[col], i);
|
Meter* meter = (Meter*) Vector_get(this->columns[col], i);
|
||||||
if (Meter_initFn(meter))
|
if (Meter_initFn(meter)) {
|
||||||
Meter_init(meter);
|
Meter_init(meter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Header_draw(const Header* this) {
|
void Header_draw(const Header* this) {
|
||||||
int height = this->height;
|
int height = this->height;
|
||||||
|
|
35
IncSet.c
35
IncSet.c
|
@ -79,7 +79,10 @@ static void updateWeakPanel(IncSet* this, Panel* panel, Vector* lines) {
|
||||||
ListItem* line = (ListItem*)Vector_get(lines, i);
|
ListItem* line = (ListItem*)Vector_get(lines, i);
|
||||||
if (String_contains_i(line->value, incFilter)) {
|
if (String_contains_i(line->value, incFilter)) {
|
||||||
Panel_add(panel, (Object*)line);
|
Panel_add(panel, (Object*)line);
|
||||||
if (selected == (Object*)line) Panel_setSelected(panel, n);
|
if (selected == (Object*)line) {
|
||||||
|
Panel_setSelected(panel, n);
|
||||||
|
}
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +90,9 @@ static void updateWeakPanel(IncSet* this, Panel* panel, Vector* lines) {
|
||||||
for (int i = 0; i < Vector_size(lines); i++) {
|
for (int i = 0; i < Vector_size(lines); i++) {
|
||||||
Object* line = Vector_get(lines, i);
|
Object* line = Vector_get(lines, i);
|
||||||
Panel_add(panel, line);
|
Panel_add(panel, line);
|
||||||
if (selected == line) Panel_setSelected(panel, i);
|
if (selected == line) {
|
||||||
|
Panel_setSelected(panel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,9 +121,16 @@ static bool IncMode_find(IncMode* mode, Panel* panel, IncMode_GetPanelValue getP
|
||||||
int i = here;
|
int i = here;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
i += step;
|
i += step;
|
||||||
if (i == size) i = 0;
|
if (i == size) {
|
||||||
if (i == -1) i = size - 1;
|
i = 0;
|
||||||
if (i == here) return false;
|
}
|
||||||
|
if (i == -1) {
|
||||||
|
i = size - 1;
|
||||||
|
}
|
||||||
|
if (i == here) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
||||||
Panel_setSelected(panel, i);
|
Panel_setSelected(panel, i);
|
||||||
return true;
|
return true;
|
||||||
|
@ -137,12 +149,15 @@ bool IncSet_prev(IncSet* this, IncType type, Panel* panel, IncMode_GetPanelValue
|
||||||
bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
|
bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
|
||||||
if (ch == ERR)
|
if (ch == ERR)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
IncMode* mode = this->active;
|
IncMode* mode = this->active;
|
||||||
int size = Panel_size(panel);
|
int size = Panel_size(panel);
|
||||||
bool filterChanged = false;
|
bool filterChanged = false;
|
||||||
bool doSearch = true;
|
bool doSearch = true;
|
||||||
if (ch == KEY_F(3)) {
|
if (ch == KEY_F(3)) {
|
||||||
if (size == 0) return true;
|
if (size == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
IncMode_find(mode, panel, getPanelValue, 1);
|
IncMode_find(mode, panel, getPanelValue, 1);
|
||||||
doSearch = false;
|
doSearch = false;
|
||||||
} else if (0 < ch && ch < 255 && isprint((unsigned char)ch)) {
|
} else if (0 < ch && ch < 255 && isprint((unsigned char)ch)) {
|
||||||
|
@ -152,7 +167,9 @@ bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue
|
||||||
mode->buffer[mode->index] = 0;
|
mode->buffer[mode->index] = 0;
|
||||||
if (mode->isFilter) {
|
if (mode->isFilter) {
|
||||||
filterChanged = true;
|
filterChanged = true;
|
||||||
if (mode->index == 1) this->filtering = true;
|
if (mode->index == 1) {
|
||||||
|
this->filtering = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((ch == KEY_BACKSPACE || ch == 127)) {
|
} else if ((ch == KEY_BACKSPACE || ch == 127)) {
|
||||||
|
@ -199,9 +216,7 @@ bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue
|
||||||
|
|
||||||
const char* IncSet_getListItemValue(Panel* panel, int i) {
|
const char* IncSet_getListItemValue(Panel* panel, int i) {
|
||||||
ListItem* l = (ListItem*) Panel_get(panel, i);
|
ListItem* l = (ListItem*) Panel_get(panel, i);
|
||||||
if (l)
|
return l ? l->value : "";
|
||||||
return l->value;
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
|
||||||
|
|
18
InfoScreen.c
18
InfoScreen.c
|
@ -64,22 +64,26 @@ void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
|
||||||
void InfoScreen_addLine(InfoScreen* this, const char* line) {
|
void InfoScreen_addLine(InfoScreen* this, const char* line) {
|
||||||
Vector_add(this->lines, (Object*) ListItem_new(line, 0));
|
Vector_add(this->lines, (Object*) ListItem_new(line, 0));
|
||||||
const char* incFilter = IncSet_filter(this->inc);
|
const char* incFilter = IncSet_filter(this->inc);
|
||||||
if (!incFilter || String_contains_i(line, incFilter))
|
if (!incFilter || String_contains_i(line, incFilter)) {
|
||||||
Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
|
Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InfoScreen_appendLine(InfoScreen* this, const char* line) {
|
void InfoScreen_appendLine(InfoScreen* this, const char* line) {
|
||||||
ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
|
ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
|
||||||
ListItem_append(last, line);
|
ListItem_append(last, line);
|
||||||
const char* incFilter = IncSet_filter(this->inc);
|
const char* incFilter = IncSet_filter(this->inc);
|
||||||
if (incFilter && Panel_get(this->display, Panel_size(this->display)-1) != (Object*)last && String_contains_i(line, incFilter))
|
if (incFilter && Panel_get(this->display, Panel_size(this->display) - 1) != (Object*)last && String_contains_i(line, incFilter)) {
|
||||||
Panel_add(this->display, (Object*)last);
|
Panel_add(this->display, (Object*)last);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InfoScreen_run(InfoScreen* this) {
|
void InfoScreen_run(InfoScreen* this) {
|
||||||
Panel* panel = this->display;
|
Panel* panel = this->display;
|
||||||
|
|
||||||
if (As_InfoScreen(this)->scan) InfoScreen_scan(this);
|
if (As_InfoScreen(this)->scan)
|
||||||
|
InfoScreen_scan(this);
|
||||||
|
|
||||||
InfoScreen_draw(this);
|
InfoScreen_draw(this);
|
||||||
|
|
||||||
bool looping = true;
|
bool looping = true;
|
||||||
|
@ -131,7 +135,9 @@ void InfoScreen_run(InfoScreen* this) {
|
||||||
break;
|
break;
|
||||||
case KEY_F(5):
|
case KEY_F(5):
|
||||||
clear();
|
clear();
|
||||||
if (As_InfoScreen(this)->scan) InfoScreen_scan(this);
|
if (As_InfoScreen(this)->scan)
|
||||||
|
InfoScreen_scan(this);
|
||||||
|
|
||||||
InfoScreen_draw(this);
|
InfoScreen_draw(this);
|
||||||
break;
|
break;
|
||||||
case '\014': // Ctrl+L
|
case '\014': // Ctrl+L
|
||||||
|
@ -145,7 +151,9 @@ void InfoScreen_run(InfoScreen* this) {
|
||||||
break;
|
break;
|
||||||
case KEY_RESIZE:
|
case KEY_RESIZE:
|
||||||
Panel_resize(panel, COLS, LINES - 2);
|
Panel_resize(panel, COLS, LINES - 2);
|
||||||
if (As_InfoScreen(this)->scan) InfoScreen_scan(this);
|
if (As_InfoScreen(this)->scan)
|
||||||
|
InfoScreen_scan(this);
|
||||||
|
|
||||||
InfoScreen_draw(this);
|
InfoScreen_draw(this);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
13
MainPanel.c
13
MainPanel.c
|
@ -100,9 +100,10 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
|
||||||
if (reaction & HTOP_REDRAW_BAR) {
|
if (reaction & HTOP_REDRAW_BAR) {
|
||||||
MainPanel_updateTreeFunctions(this, this->state->settings->treeView);
|
MainPanel_updateTreeFunctions(this, this->state->settings->treeView);
|
||||||
IncSet_drawBar(this->inc);
|
IncSet_drawBar(this->inc);
|
||||||
if (this->state->pauseProcessUpdate)
|
if (this->state->pauseProcessUpdate) {
|
||||||
FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
|
FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (reaction & HTOP_UPDATE_PANELHDR) {
|
if (reaction & HTOP_UPDATE_PANELHDR) {
|
||||||
ProcessList_printHeader(this->state->pl, Panel_getHeader(super));
|
ProcessList_printHeader(this->state->pl, Panel_getHeader(super));
|
||||||
}
|
}
|
||||||
|
@ -135,9 +136,7 @@ int MainPanel_selectedPid(MainPanel* this) {
|
||||||
|
|
||||||
const char* MainPanel_getValue(MainPanel* this, int i) {
|
const char* MainPanel_getValue(MainPanel* this, int i) {
|
||||||
Process* p = (Process*) Panel_get((Panel*)this, i);
|
Process* p = (Process*) Panel_get((Panel*)this, i);
|
||||||
if (p)
|
return p ? p->comm : "";
|
||||||
return p->comm;
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, Arg arg, bool* wasAnyTagged) {
|
bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, Arg arg, bool* wasAnyTagged) {
|
||||||
|
@ -153,10 +152,14 @@ bool MainPanel_foreachProcess(MainPanel* this, MainPanel_ForeachProcessFn fn, Ar
|
||||||
}
|
}
|
||||||
if (!anyTagged) {
|
if (!anyTagged) {
|
||||||
Process* p = (Process*) Panel_getSelected(super);
|
Process* p = (Process*) Panel_getSelected(super);
|
||||||
if (p) ok = fn(p, arg) && ok;
|
if (p) {
|
||||||
|
ok &= fn(p, arg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wasAnyTagged)
|
if (wasAnyTagged)
|
||||||
*wasAnyTagged = anyTagged;
|
*wasAnyTagged = anyTagged;
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
Meter.c
29
Meter.c
|
@ -41,8 +41,9 @@ Meter* Meter_new(const struct ProcessList_* pl, int param, const MeterClass* typ
|
||||||
this->values = type->maxItems ? xCalloc(type->maxItems, sizeof(double)) : NULL;
|
this->values = type->maxItems ? xCalloc(type->maxItems, sizeof(double)) : NULL;
|
||||||
this->total = type->total;
|
this->total = type->total;
|
||||||
this->caption = xStrdup(type->caption);
|
this->caption = xStrdup(type->caption);
|
||||||
if (Meter_initFn(this))
|
if (Meter_initFn(this)) {
|
||||||
Meter_init(this);
|
Meter_init(this);
|
||||||
|
}
|
||||||
Meter_setMode(this, type->defaultMode);
|
Meter_setMode(this, type->defaultMode);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +82,7 @@ int Meter_humanUnit(char* buffer, unsigned long int value, int size) {
|
||||||
void Meter_delete(Object* cast) {
|
void Meter_delete(Object* cast) {
|
||||||
if (!cast)
|
if (!cast)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Meter* this = (Meter*) cast;
|
Meter* this = (Meter*) cast;
|
||||||
if (Meter_doneFn(this)) {
|
if (Meter_doneFn(this)) {
|
||||||
Meter_done(this);
|
Meter_done(this);
|
||||||
|
@ -105,15 +107,20 @@ static inline void Meter_displayBuffer(const Meter* this, const char* buffer, Ri
|
||||||
}
|
}
|
||||||
|
|
||||||
void Meter_setMode(Meter* this, int modeIndex) {
|
void Meter_setMode(Meter* this, int modeIndex) {
|
||||||
if (modeIndex > 0 && modeIndex == this->mode)
|
if (modeIndex > 0 && modeIndex == this->mode) {
|
||||||
return;
|
return;
|
||||||
if (!modeIndex)
|
}
|
||||||
|
|
||||||
|
if (!modeIndex) {
|
||||||
modeIndex = 1;
|
modeIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
assert(modeIndex < LAST_METERMODE);
|
assert(modeIndex < LAST_METERMODE);
|
||||||
if (Meter_defaultMode(this) == CUSTOM_METERMODE) {
|
if (Meter_defaultMode(this) == CUSTOM_METERMODE) {
|
||||||
this->draw = Meter_drawFn(this);
|
this->draw = Meter_drawFn(this);
|
||||||
if (Meter_updateModeFn(this))
|
if (Meter_updateModeFn(this)) {
|
||||||
Meter_updateMode(this, modeIndex);
|
Meter_updateMode(this, modeIndex);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(modeIndex >= 1);
|
assert(modeIndex >= 1);
|
||||||
free(this->drawData);
|
free(this->drawData);
|
||||||
|
@ -128,15 +135,17 @@ void Meter_setMode(Meter* this, int modeIndex) {
|
||||||
|
|
||||||
ListItem* Meter_toListItem(Meter* this, bool moving) {
|
ListItem* Meter_toListItem(Meter* this, bool moving) {
|
||||||
char mode[21];
|
char mode[21];
|
||||||
if (this->mode)
|
if (this->mode) {
|
||||||
xSnprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
|
xSnprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
|
||||||
else
|
} else {
|
||||||
mode[0] = '\0';
|
mode[0] = '\0';
|
||||||
|
}
|
||||||
char number[11];
|
char number[11];
|
||||||
if (this->param > 0)
|
if (this->param > 0) {
|
||||||
xSnprintf(number, 10, " %d", this->param);
|
xSnprintf(number, 10, " %d", this->param);
|
||||||
else
|
} else {
|
||||||
number[0] = '\0';
|
number[0] = '\0';
|
||||||
|
}
|
||||||
char buffer[51];
|
char buffer[51];
|
||||||
xSnprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
|
xSnprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
|
||||||
ListItem* li = ListItem_new(buffer, 0);
|
ListItem* li = ListItem_new(buffer, 0);
|
||||||
|
@ -261,7 +270,9 @@ static int GraphMeterMode_pixPerRow;
|
||||||
|
|
||||||
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
|
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
|
||||||
|
|
||||||
if (!this->drawData) this->drawData = xCalloc(1, sizeof(GraphData));
|
if (!this->drawData) {
|
||||||
|
this->drawData = xCalloc(1, sizeof(GraphData));
|
||||||
|
}
|
||||||
GraphData* data = this->drawData;
|
GraphData* data = this->drawData;
|
||||||
const int nValues = METER_BUFFER_LEN;
|
const int nValues = METER_BUFFER_LEN;
|
||||||
|
|
||||||
|
|
6
Object.c
6
Object.c
|
@ -20,12 +20,16 @@ const ObjectClass Object_class = {
|
||||||
bool Object_isA(const Object* o, const ObjectClass* klass) {
|
bool Object_isA(const Object* o, const ObjectClass* klass) {
|
||||||
if (!o)
|
if (!o)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ObjectClass* type = o->klass;
|
const ObjectClass* type = o->klass;
|
||||||
while (type) {
|
while (type) {
|
||||||
if (type == klass)
|
if (type == klass) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
type = type->extends;
|
type = type->extends;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
Object.h
2
Object.h
|
@ -33,7 +33,7 @@ typedef void(*Object_Delete)(Object*);
|
||||||
|
|
||||||
#define Class(class_) ((const ObjectClass*)(&(class_ ## _class)))
|
#define Class(class_) ((const ObjectClass*)(&(class_ ## _class)))
|
||||||
|
|
||||||
#define AllocThis(class_) (class_*) xMalloc(sizeof(class_)); Object_setClass(this, Class(class_));
|
#define AllocThis(class_) (class_*) xMalloc(sizeof(class_)); Object_setClass(this, Class(class_))
|
||||||
|
|
||||||
typedef struct ObjectClass_ {
|
typedef struct ObjectClass_ {
|
||||||
const void* const extends;
|
const void* const extends;
|
||||||
|
|
|
@ -69,10 +69,11 @@ static const char* getDataForType(const OpenFiles_Data* data, char type) {
|
||||||
OpenFilesScreen* OpenFilesScreen_new(const Process* process) {
|
OpenFilesScreen* OpenFilesScreen_new(const Process* process) {
|
||||||
OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen));
|
OpenFilesScreen* this = xMalloc(sizeof(OpenFilesScreen));
|
||||||
Object_setClass(this, Class(OpenFilesScreen));
|
Object_setClass(this, Class(OpenFilesScreen));
|
||||||
if (Process_isThread(process))
|
if (Process_isThread(process)) {
|
||||||
this->pid = process->tgid;
|
this->pid = process->tgid;
|
||||||
else
|
} else {
|
||||||
this->pid = process->pid;
|
this->pid = process->pid;
|
||||||
|
}
|
||||||
return (OpenFilesScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 3, " FD TYPE MODE DEVICE SIZE NODE NAME");
|
return (OpenFilesScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 3, " FD TYPE MODE DEVICE SIZE NODE NAME");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +107,10 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
|
||||||
dup2(fdpair[1], STDOUT_FILENO);
|
dup2(fdpair[1], STDOUT_FILENO);
|
||||||
close(fdpair[1]);
|
close(fdpair[1]);
|
||||||
int fdnull = open("/dev/null", O_WRONLY);
|
int fdnull = open("/dev/null", O_WRONLY);
|
||||||
if (fdnull < 0)
|
if (fdnull < 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
dup2(fdnull, STDERR_FILENO);
|
dup2(fdnull, STDERR_FILENO);
|
||||||
close(fdnull);
|
close(fdnull);
|
||||||
char buffer[32] = {0};
|
char buffer[32] = {0};
|
||||||
|
@ -182,10 +185,11 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
|
||||||
return pdata;
|
return pdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WIFEXITED(wstatus))
|
if (!WIFEXITED(wstatus)) {
|
||||||
pdata->error = 1;
|
pdata->error = 1;
|
||||||
else
|
} else {
|
||||||
pdata->error = WEXITSTATUS(wstatus);
|
pdata->error = WEXITSTATUS(wstatus);
|
||||||
|
}
|
||||||
|
|
||||||
return pdata;
|
return pdata;
|
||||||
}
|
}
|
||||||
|
|
22
Panel.c
22
Panel.c
|
@ -97,8 +97,10 @@ void Panel_move(Panel* this, int x, int y) {
|
||||||
void Panel_resize(Panel* this, int w, int h) {
|
void Panel_resize(Panel* this, int w, int h) {
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
|
|
||||||
if (RichString_sizeVal(this->header) > 0)
|
if (RichString_sizeVal(this->header) > 0) {
|
||||||
h--;
|
h--;
|
||||||
|
}
|
||||||
|
|
||||||
this->w = w;
|
this->w = w;
|
||||||
this->h = h;
|
this->h = h;
|
||||||
this->needsRedraw = true;
|
this->needsRedraw = true;
|
||||||
|
@ -145,34 +147,39 @@ Object* Panel_remove(Panel* this, int i) {
|
||||||
|
|
||||||
this->needsRedraw = true;
|
this->needsRedraw = true;
|
||||||
Object* removed = Vector_remove(this->items, i);
|
Object* removed = Vector_remove(this->items, i);
|
||||||
if (this->selected > 0 && this->selected >= Vector_size(this->items))
|
if (this->selected > 0 && this->selected >= Vector_size(this->items)) {
|
||||||
this->selected--;
|
this->selected--;
|
||||||
|
}
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* Panel_getSelected(Panel* this) {
|
Object* Panel_getSelected(Panel* this) {
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
if (Vector_size(this->items) > 0)
|
if (Vector_size(this->items) > 0) {
|
||||||
return Vector_get(this->items, this->selected);
|
return Vector_get(this->items, this->selected);
|
||||||
else
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel_moveSelectedUp(Panel* this) {
|
void Panel_moveSelectedUp(Panel* this) {
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
|
|
||||||
Vector_moveUp(this->items, this->selected);
|
Vector_moveUp(this->items, this->selected);
|
||||||
if (this->selected > 0)
|
if (this->selected > 0) {
|
||||||
this->selected--;
|
this->selected--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel_moveSelectedDown(Panel* this) {
|
void Panel_moveSelectedDown(Panel* this) {
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
|
|
||||||
Vector_moveDown(this->items, this->selected);
|
Vector_moveDown(this->items, this->selected);
|
||||||
if (this->selected + 1 < Vector_size(this->items))
|
if (this->selected + 1 < Vector_size(this->items)) {
|
||||||
this->selected++;
|
this->selected++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Panel_getSelectedIndex(Panel* this) {
|
int Panel_getSelectedIndex(Panel* this) {
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
|
@ -193,8 +200,9 @@ void Panel_setSelected(Panel* this, int selected) {
|
||||||
if (selected >= size) {
|
if (selected >= size) {
|
||||||
selected = size - 1;
|
selected = size - 1;
|
||||||
}
|
}
|
||||||
if (selected < 0)
|
if (selected < 0) {
|
||||||
selected = 0;
|
selected = 0;
|
||||||
|
}
|
||||||
this->selected = selected;
|
this->selected = selected;
|
||||||
if (Panel_eventHandlerFn(this)) {
|
if (Panel_eventHandlerFn(this)) {
|
||||||
Panel_eventHandler(this, EVENT_SET_SELECTED);
|
Panel_eventHandler(this, EVENT_SET_SELECTED);
|
||||||
|
|
43
Process.c
43
Process.c
|
@ -43,7 +43,9 @@ static char Process_titleBuffer[20][20];
|
||||||
|
|
||||||
void Process_setupColumnWidths() {
|
void Process_setupColumnWidths() {
|
||||||
int maxPid = Platform_getMaxPid();
|
int maxPid = Platform_getMaxPid();
|
||||||
if (maxPid == -1) return;
|
if (maxPid == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
int digits = ceil(log10(maxPid));
|
int digits = ceil(log10(maxPid));
|
||||||
assert(digits < 20);
|
assert(digits < 20);
|
||||||
for (int i = 0; Process_pidColumns[i].label; i++) {
|
for (int i = 0; Process_pidColumns[i].label; i++) {
|
||||||
|
@ -201,10 +203,11 @@ static inline void Process_writeCommand(const Process* this, int attr, int basea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!finish) {
|
if (!finish) {
|
||||||
if (this->settings->showProgramPath)
|
if (this->settings->showProgramPath) {
|
||||||
start += basename;
|
start += basename;
|
||||||
else
|
} else {
|
||||||
comm += basename;
|
comm += basename;
|
||||||
|
}
|
||||||
finish = this->basenameOffset - basename;
|
finish = this->basenameOffset - basename;
|
||||||
}
|
}
|
||||||
finish += start - 1;
|
finish += start - 1;
|
||||||
|
@ -212,9 +215,10 @@ static inline void Process_writeCommand(const Process* this, int attr, int basea
|
||||||
|
|
||||||
RichString_append(str, attr, comm);
|
RichString_append(str, attr, comm);
|
||||||
|
|
||||||
if (this->settings->highlightBaseName)
|
if (this->settings->highlightBaseName) {
|
||||||
RichString_setAttrn(str, baseattr, start, finish);
|
RichString_setAttrn(str, baseattr, start, finish);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring) {
|
void Process_outputRate(RichString* str, char* buffer, int n, double rate, int coloring) {
|
||||||
int largeNumberColor = CRT_colors[LARGE_NUMBER];
|
int largeNumberColor = CRT_colors[LARGE_NUMBER];
|
||||||
|
@ -285,15 +289,19 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
|
||||||
bool lastItem = (this->indent < 0);
|
bool lastItem = (this->indent < 0);
|
||||||
int indent = (this->indent < 0 ? -this->indent : this->indent);
|
int indent = (this->indent < 0 ? -this->indent : this->indent);
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++) {
|
||||||
if (indent & (1U << i))
|
if (indent & (1U << i)) {
|
||||||
maxIndent = i + 1;
|
maxIndent = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < maxIndent - 1; i++) {
|
for (int i = 0; i < maxIndent - 1; i++) {
|
||||||
int written, ret;
|
int written, ret;
|
||||||
if (indent & (1 << i))
|
if (indent & (1 << i)) {
|
||||||
ret = snprintf(buf, n, "%s ", CRT_treeStr[TREE_STR_VERT]);
|
ret = snprintf(buf, n, "%s ", CRT_treeStr[TREE_STR_VERT]);
|
||||||
else
|
} else {
|
||||||
ret = snprintf(buf, n, " ");
|
ret = snprintf(buf, n, " ");
|
||||||
|
}
|
||||||
if (ret < 0 || ret >= n) {
|
if (ret < 0 || ret >= n) {
|
||||||
written = n;
|
written = n;
|
||||||
} else {
|
} else {
|
||||||
|
@ -377,10 +385,15 @@ void Process_display(const Object* cast, RichString* out) {
|
||||||
RichString_prune(out);
|
RichString_prune(out);
|
||||||
for (int i = 0; fields[i]; i++)
|
for (int i = 0; fields[i]; i++)
|
||||||
As_Process(this)->writeField(this, out, fields[i]);
|
As_Process(this)->writeField(this, out, fields[i]);
|
||||||
if (this->settings->shadowOtherUsers && (int)this->st_uid != Process_getuid)
|
|
||||||
|
if (this->settings->shadowOtherUsers && (int)this->st_uid != Process_getuid) {
|
||||||
RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
|
RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
|
||||||
if (this->tag == true)
|
}
|
||||||
|
|
||||||
|
if (this->tag == true) {
|
||||||
RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
|
RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
|
||||||
|
}
|
||||||
|
|
||||||
assert(out->chlen > 0);
|
assert(out->chlen > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +419,10 @@ void Process_init(Process* this, const struct Settings_* settings) {
|
||||||
this->show = true;
|
this->show = true;
|
||||||
this->updated = false;
|
this->updated = false;
|
||||||
this->basenameOffset = -1;
|
this->basenameOffset = -1;
|
||||||
if (Process_getuid == -1) Process_getuid = getuid();
|
|
||||||
|
if (Process_getuid == -1) {
|
||||||
|
Process_getuid = getuid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process_toggleTag(Process* this) {
|
void Process_toggleTag(Process* this) {
|
||||||
|
@ -483,11 +499,12 @@ long Process_compare(const void* v1, const void* v2) {
|
||||||
case SESSION:
|
case SESSION:
|
||||||
return (p1->session - p2->session);
|
return (p1->session - p2->session);
|
||||||
case STARTTIME: {
|
case STARTTIME: {
|
||||||
if (p1->starttime_ctime == p2->starttime_ctime)
|
if (p1->starttime_ctime == p2->starttime_ctime) {
|
||||||
return (p1->pid - p2->pid);
|
return (p1->pid - p2->pid);
|
||||||
else
|
} else {
|
||||||
return (p1->starttime_ctime - p2->starttime_ctime);
|
return (p1->starttime_ctime - p2->starttime_ctime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case STATE:
|
case STATE:
|
||||||
return (Process_sortState(p1->state) - Process_sortState(p2->state));
|
return (Process_sortState(p1->state) - Process_sortState(p2->state));
|
||||||
case ST_UID:
|
case ST_UID:
|
||||||
|
|
|
@ -70,13 +70,17 @@ void ProcessList_printHeader(ProcessList* this, RichString* header) {
|
||||||
const ProcessField* fields = this->settings->fields;
|
const ProcessField* fields = this->settings->fields;
|
||||||
for (int i = 0; fields[i]; i++) {
|
for (int i = 0; fields[i]; i++) {
|
||||||
const char* field = Process_fields[fields[i]].title;
|
const char* field = Process_fields[fields[i]].title;
|
||||||
if (!field) field = "- ";
|
if (!field) {
|
||||||
if (!this->settings->treeView && this->settings->sortKey == fields[i])
|
field = "- ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->settings->treeView && this->settings->sortKey == fields[i]) {
|
||||||
RichString_append(header, CRT_colors[PANEL_SELECTION_FOCUS], field);
|
RichString_append(header, CRT_colors[PANEL_SELECTION_FOCUS], field);
|
||||||
else
|
} else {
|
||||||
RichString_append(header, CRT_colors[PANEL_HEADER_FOCUS], field);
|
RichString_append(header, CRT_colors[PANEL_HEADER_FOCUS], field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessList_add(ProcessList* this, Process* p) {
|
void ProcessList_add(ProcessList* this, Process* p) {
|
||||||
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
|
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
|
||||||
|
@ -93,12 +97,18 @@ void ProcessList_add(ProcessList* this, Process* p) {
|
||||||
void ProcessList_remove(ProcessList* this, Process* p) {
|
void ProcessList_remove(ProcessList* this, Process* p) {
|
||||||
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
|
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
|
||||||
assert(Hashtable_get(this->processTable, p->pid) != NULL);
|
assert(Hashtable_get(this->processTable, p->pid) != NULL);
|
||||||
|
|
||||||
Process* pp = Hashtable_remove(this->processTable, p->pid);
|
Process* pp = Hashtable_remove(this->processTable, p->pid);
|
||||||
assert(pp == p); (void)pp;
|
assert(pp == p); (void)pp;
|
||||||
|
|
||||||
unsigned int pid = p->pid;
|
unsigned int pid = p->pid;
|
||||||
int idx = Vector_indexOf(this->processes, p, Process_pidCompare);
|
int idx = Vector_indexOf(this->processes, p, Process_pidCompare);
|
||||||
assert(idx != -1);
|
assert(idx != -1);
|
||||||
if (idx >= 0) Vector_remove(this->processes, idx);
|
|
||||||
|
if (idx >= 0) {
|
||||||
|
Vector_remove(this->processes, idx);
|
||||||
|
}
|
||||||
|
|
||||||
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
|
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
|
||||||
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
|
||||||
}
|
}
|
||||||
|
@ -124,21 +134,28 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
|
||||||
int size = Vector_size(children);
|
int size = Vector_size(children);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
Process* process = (Process*) (Vector_get(children, i));
|
Process* process = (Process*) (Vector_get(children, i));
|
||||||
if (!show)
|
if (!show) {
|
||||||
process->show = false;
|
process->show = false;
|
||||||
|
}
|
||||||
|
|
||||||
int s = Vector_size(this->processes2);
|
int s = Vector_size(this->processes2);
|
||||||
if (direction == 1)
|
if (direction == 1) {
|
||||||
Vector_add(this->processes2, process);
|
Vector_add(this->processes2, process);
|
||||||
else
|
} else {
|
||||||
Vector_insert(this->processes2, 0, process);
|
Vector_insert(this->processes2, 0, process);
|
||||||
|
}
|
||||||
|
|
||||||
assert(Vector_size(this->processes2) == s + 1); (void)s;
|
assert(Vector_size(this->processes2) == s + 1); (void)s;
|
||||||
|
|
||||||
int nextIndent = indent | (1 << level);
|
int nextIndent = indent | (1 << level);
|
||||||
ProcessList_buildTree(this, process->pid, level + 1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
|
ProcessList_buildTree(this, process->pid, level + 1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
|
||||||
if (i == size - 1)
|
|
||||||
|
if (i == size - 1) {
|
||||||
process->indent = -nextIndent;
|
process->indent = -nextIndent;
|
||||||
else
|
} else {
|
||||||
process->indent = nextIndent;
|
process->indent = nextIndent;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Vector_delete(children);
|
Vector_delete(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +197,7 @@ void ProcessList_sort(ProcessList* this) {
|
||||||
// root.
|
// root.
|
||||||
if (process->pid == ppid)
|
if (process->pid == ppid)
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
while (l < r) {
|
while (l < r) {
|
||||||
int c = (l + r) / 2;
|
int c = (l + r) / 2;
|
||||||
pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;
|
pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;
|
||||||
|
@ -219,7 +237,10 @@ ProcessField ProcessList_keyAt(ProcessList* this, int at) {
|
||||||
ProcessField field;
|
ProcessField field;
|
||||||
for (int i = 0; (field = fields[i]); i++) {
|
for (int i = 0; (field = fields[i]); i++) {
|
||||||
const char* title = Process_fields[field].title;
|
const char* title = Process_fields[field].title;
|
||||||
if (!title) title = "- ";
|
if (!title) {
|
||||||
|
title = "- ";
|
||||||
|
}
|
||||||
|
|
||||||
int len = strlen(title);
|
int len = strlen(title);
|
||||||
if (at >= x && at <= x + len) {
|
if (at >= x && at <= x + len) {
|
||||||
return field;
|
return field;
|
||||||
|
@ -306,9 +327,10 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
|
||||||
|
|
||||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||||
Process* p = (Process*) Vector_get(this->processes, i);
|
Process* p = (Process*) Vector_get(this->processes, i);
|
||||||
if (p->updated == false)
|
if (p->updated == false) {
|
||||||
ProcessList_remove(this, p);
|
ProcessList_remove(this, p);
|
||||||
else
|
} else {
|
||||||
p->updated = false;
|
p->updated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ static inline void RichString_writeFrom(RichString* this, int attrs, const char*
|
||||||
len = mbstowcs(data, data_c, len);
|
len = mbstowcs(data, data_c, len);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int newLen = from + len;
|
int newLen = from + len;
|
||||||
RichString_setLen(this, newLen);
|
RichString_setLen(this, newLen);
|
||||||
for (int i = from, j = 0; i < newLen; i++, j++) {
|
for (int i = from, j = 0; i < newLen; i++, j++) {
|
||||||
|
@ -84,8 +85,9 @@ int RichString_findChar(RichString* this, char c, int start) {
|
||||||
static inline void RichString_writeFrom(RichString* this, int attrs, const char* data_c, int from, int len) {
|
static inline void RichString_writeFrom(RichString* this, int attrs, const char* data_c, int from, int len) {
|
||||||
int newLen = from + len;
|
int newLen = from + len;
|
||||||
RichString_setLen(this, newLen);
|
RichString_setLen(this, newLen);
|
||||||
for (int i = from, j = 0; i < newLen; i++, j++)
|
for (int i = from, j = 0; i < newLen; i++, j++) {
|
||||||
this->chptr[i] = (data_c[j] >= 32 ? data_c[j] : '?') | attrs;
|
this->chptr[i] = (data_c[j] >= 32 ? data_c[j] : '?') | attrs;
|
||||||
|
}
|
||||||
this->chptr[newLen] = 0;
|
this->chptr[newLen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ in the source distribution for its full text.
|
||||||
#define RichString_size(this) ((this)->chlen)
|
#define RichString_size(this) ((this)->chlen)
|
||||||
#define RichString_sizeVal(this) ((this).chlen)
|
#define RichString_sizeVal(this) ((this).chlen)
|
||||||
|
|
||||||
#define RichString_begin(this) RichString (this); RichString_beginAllocated(this);
|
#define RichString_begin(this) RichString (this); RichString_beginAllocated(this)
|
||||||
#define RichString_beginAllocated(this) memset(&(this), 0, sizeof(RichString)); (this).chptr = (this).chstr;
|
#define RichString_beginAllocated(this) do { memset(&(this), 0, sizeof(RichString)); (this).chptr = (this).chstr; } while(0)
|
||||||
#define RichString_end(this) RichString_prune(&(this));
|
#define RichString_end(this) RichString_prune(&(this))
|
||||||
|
|
||||||
#ifdef HAVE_LIBNCURSESW
|
#ifdef HAVE_LIBNCURSESW
|
||||||
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, (this).chptr)
|
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, (this).chptr)
|
||||||
|
|
|
@ -103,8 +103,12 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
double newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
|
double newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
|
||||||
*timedOut = (newTime - *oldTime > this->settings->delay);
|
*timedOut = (newTime - *oldTime > this->settings->delay);
|
||||||
*rescan = *rescan || *timedOut;
|
*rescan |= *timedOut;
|
||||||
if (newTime < *oldTime) *rescan = true; // clock was adjusted?
|
|
||||||
|
if (newTime < *oldTime) {
|
||||||
|
*rescan = true; // clock was adjusted?
|
||||||
|
}
|
||||||
|
|
||||||
if (*rescan) {
|
if (*rescan) {
|
||||||
*oldTime = newTime;
|
*oldTime = newTime;
|
||||||
ProcessList_scan(pl, this->state->pauseProcessUpdate);
|
ProcessList_scan(pl, this->state->pauseProcessUpdate);
|
||||||
|
@ -134,8 +138,9 @@ static void ScreenManager_drawPanels(ScreenManager* this, int focus) {
|
||||||
|
|
||||||
static Panel* setCurrentPanel(const ScreenManager* this, Panel* panel) {
|
static Panel* setCurrentPanel(const ScreenManager* this, Panel* panel) {
|
||||||
FunctionBar_draw(panel->currentBar);
|
FunctionBar_draw(panel->currentBar);
|
||||||
if (panel == this->state->panel && this->state->pauseProcessUpdate)
|
if (panel == this->state->panel && this->state->pauseProcessUpdate) {
|
||||||
FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
|
FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
|
||||||
|
}
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
@ -218,8 +223,9 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||||
if (closeTimeout == 100) {
|
if (closeTimeout == 100) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
closeTimeout = 0;
|
closeTimeout = 0;
|
||||||
|
}
|
||||||
redraw = false;
|
redraw = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -261,14 +267,21 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||||
if (this->panelCount < 2) {
|
if (this->panelCount < 2) {
|
||||||
goto defaultHandler;
|
goto defaultHandler;
|
||||||
}
|
}
|
||||||
if (!this->allowFocusChange)
|
|
||||||
|
if (!this->allowFocusChange) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
tryLeft:
|
tryLeft:
|
||||||
if (focus > 0)
|
if (focus > 0) {
|
||||||
focus--;
|
focus--;
|
||||||
|
}
|
||||||
|
|
||||||
panelFocus = setCurrentPanel(this, (Panel*) Vector_get(this->panels, focus));
|
panelFocus = setCurrentPanel(this, (Panel*) Vector_get(this->panels, focus));
|
||||||
if (Panel_size(panelFocus) == 0 && focus > 0)
|
if (Panel_size(panelFocus) == 0 && focus > 0) {
|
||||||
goto tryLeft;
|
goto tryLeft;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KEY_RIGHT:
|
case KEY_RIGHT:
|
||||||
case KEY_CTRL('F'):
|
case KEY_CTRL('F'):
|
||||||
|
@ -276,14 +289,20 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||||
if (this->panelCount < 2) {
|
if (this->panelCount < 2) {
|
||||||
goto defaultHandler;
|
goto defaultHandler;
|
||||||
}
|
}
|
||||||
if (!this->allowFocusChange)
|
if (!this->allowFocusChange) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
tryRight:
|
tryRight:
|
||||||
if (focus < this->panelCount - 1)
|
if (focus < this->panelCount - 1) {
|
||||||
focus++;
|
focus++;
|
||||||
|
}
|
||||||
|
|
||||||
panelFocus = setCurrentPanel(this, (Panel*) Vector_get(this->panels, focus));
|
panelFocus = setCurrentPanel(this, (Panel*) Vector_get(this->panels, focus));
|
||||||
if (Panel_size(panelFocus) == 0 && focus < this->panelCount - 1)
|
if (Panel_size(panelFocus) == 0 && focus < this->panelCount - 1) {
|
||||||
goto tryRight;
|
goto tryRight;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KEY_F(10):
|
case KEY_F(10):
|
||||||
case 'q':
|
case 'q':
|
||||||
|
@ -298,8 +317,11 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastFocus)
|
if (lastFocus) {
|
||||||
*lastFocus = panelFocus;
|
*lastFocus = panelFocus;
|
||||||
if (lastKey)
|
}
|
||||||
|
|
||||||
|
if (lastKey) {
|
||||||
*lastKey = ch;
|
*lastKey = ch;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
17
Settings.c
17
Settings.c
|
@ -116,6 +116,7 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo
|
||||||
CRT_restorePrivileges();
|
CRT_restorePrivileges();
|
||||||
if (!fd)
|
if (!fd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool didReadMeters = false;
|
bool didReadMeters = false;
|
||||||
bool didReadFields = false;
|
bool didReadFields = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -182,7 +183,9 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo
|
||||||
this->delay = atoi(option[1]);
|
this->delay = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "color_scheme")) {
|
} else if (String_eq(option[0], "color_scheme")) {
|
||||||
this->colorScheme = atoi(option[1]);
|
this->colorScheme = atoi(option[1]);
|
||||||
if (this->colorScheme < 0 || this->colorScheme >= LAST_COLORSCHEME) this->colorScheme = 0;
|
if (this->colorScheme < 0 || this->colorScheme >= LAST_COLORSCHEME) {
|
||||||
|
this->colorScheme = 0;
|
||||||
|
}
|
||||||
} else if (String_eq(option[0], "enable_mouse")) {
|
} else if (String_eq(option[0], "enable_mouse")) {
|
||||||
this->enableMouse = atoi(option[1]);
|
this->enableMouse = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "left_meters")) {
|
} else if (String_eq(option[0], "left_meters")) {
|
||||||
|
@ -326,7 +329,9 @@ Settings* Settings_new(int initialCpuCount) {
|
||||||
this->filename = xStrdup(rcfile);
|
this->filename = xStrdup(rcfile);
|
||||||
} else {
|
} else {
|
||||||
const char* home = getenv("HOME");
|
const char* home = getenv("HOME");
|
||||||
if (!home) home = "";
|
if (!home)
|
||||||
|
home = "";
|
||||||
|
|
||||||
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||||
char* configDir = NULL;
|
char* configDir = NULL;
|
||||||
char* htopDir = NULL;
|
char* htopDir = NULL;
|
||||||
|
@ -362,9 +367,10 @@ Settings* Settings_new(int initialCpuCount) {
|
||||||
ok = Settings_read(this, legacyDotfile, initialCpuCount);
|
ok = Settings_read(this, legacyDotfile, initialCpuCount);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
// Transition to new location and delete old configuration file
|
// Transition to new location and delete old configuration file
|
||||||
if (Settings_write(this))
|
if (Settings_write(this)) {
|
||||||
unlink(legacyDotfile);
|
unlink(legacyDotfile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(legacyDotfile);
|
free(legacyDotfile);
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
@ -388,8 +394,9 @@ Settings* Settings_new(int initialCpuCount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings_invertSortOrder(Settings* this) {
|
void Settings_invertSortOrder(Settings* this) {
|
||||||
if (this->direction == 1)
|
if (this->direction == 1) {
|
||||||
this->direction = -1;
|
this->direction = -1;
|
||||||
else
|
} else {
|
||||||
this->direction = 1;
|
this->direction = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -61,8 +61,11 @@ void TraceScreen_delete(Object* cast) {
|
||||||
kill(this->child, SIGTERM);
|
kill(this->child, SIGTERM);
|
||||||
waitpid(this->child, NULL, 0);
|
waitpid(this->child, NULL, 0);
|
||||||
}
|
}
|
||||||
if (this->strace)
|
|
||||||
|
if (this->strace) {
|
||||||
fclose(this->strace);
|
fclose(this->strace);
|
||||||
|
}
|
||||||
|
|
||||||
CRT_enableDelay();
|
CRT_enableDelay();
|
||||||
free(InfoScreen_done((InfoScreen*)this));
|
free(InfoScreen_done((InfoScreen*)this));
|
||||||
}
|
}
|
||||||
|
@ -140,12 +143,13 @@ void TraceScreen_updateTrace(InfoScreen* super) {
|
||||||
// FD_SET(STDIN_FILENO, &fds);
|
// FD_SET(STDIN_FILENO, &fds);
|
||||||
FD_SET(fd_strace, &fds);
|
FD_SET(fd_strace, &fds);
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv = { .tv_sec = 0, .tv_usec = 500 };
|
||||||
tv.tv_sec = 0; tv.tv_usec = 500;
|
|
||||||
int ready = select(fd_strace + 1, &fds, NULL, NULL, &tv);
|
int ready = select(fd_strace + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
size_t nread = 0;
|
size_t nread = 0;
|
||||||
if (ready > 0 && FD_ISSET(fd_strace, &fds))
|
if (ready > 0 && FD_ISSET(fd_strace, &fds))
|
||||||
nread = fread(buffer, 1, sizeof(buffer) - 1, this->strace);
|
nread = fread(buffer, 1, sizeof(buffer) - 1, this->strace);
|
||||||
|
|
||||||
if (nread && this->tracing) {
|
if (nread && this->tracing) {
|
||||||
const char* line = buffer;
|
const char* line = buffer;
|
||||||
buffer[nread] = '\0';
|
buffer[nread] = '\0';
|
||||||
|
@ -166,10 +170,11 @@ void TraceScreen_updateTrace(InfoScreen* super) {
|
||||||
buffer[nread] = '\0';
|
buffer[nread] = '\0';
|
||||||
this->contLine = true;
|
this->contLine = true;
|
||||||
}
|
}
|
||||||
if (this->follow)
|
if (this->follow) {
|
||||||
Panel_setSelected(this->super.display, Panel_size(this->super.display) - 1);
|
Panel_setSelected(this->super.display, Panel_size(this->super.display) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TraceScreen_onKey(InfoScreen* super, int ch) {
|
bool TraceScreen_onKey(InfoScreen* super, int ch) {
|
||||||
TraceScreen* this = (TraceScreen*) super;
|
TraceScreen* this = (TraceScreen*) super;
|
||||||
|
|
34
Vector.c
34
Vector.c
|
@ -17,8 +17,10 @@ in the source distribution for its full text.
|
||||||
Vector* Vector_new(const ObjectClass* type, bool owner, int size) {
|
Vector* Vector_new(const ObjectClass* type, bool owner, int size) {
|
||||||
Vector* this;
|
Vector* this;
|
||||||
|
|
||||||
if (size == DEFAULT_SIZE)
|
if (size == DEFAULT_SIZE) {
|
||||||
size = 10;
|
size = 10;
|
||||||
|
}
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
this = xMalloc(sizeof(Vector));
|
this = xMalloc(sizeof(Vector));
|
||||||
this->growthRate = size;
|
this->growthRate = size;
|
||||||
|
@ -32,10 +34,12 @@ Vector* Vector_new(const ObjectClass* type, bool owner, int size) {
|
||||||
|
|
||||||
void Vector_delete(Vector* this) {
|
void Vector_delete(Vector* this) {
|
||||||
if (this->owner) {
|
if (this->owner) {
|
||||||
for (int i = 0; i < this->items; i++)
|
for (int i = 0; i < this->items; i++) {
|
||||||
if (this->array[i])
|
if (this->array[i]) {
|
||||||
Object_delete(this->array[i]);
|
Object_delete(this->array[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
free(this->array);
|
free(this->array);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
@ -45,9 +49,11 @@ void Vector_delete(Vector* this) {
|
||||||
static bool Vector_isConsistent(const Vector* this) {
|
static bool Vector_isConsistent(const Vector* this) {
|
||||||
assert(this->items <= this->arraySize);
|
assert(this->items <= this->arraySize);
|
||||||
if (this->owner) {
|
if (this->owner) {
|
||||||
for (int i = 0; i < this->items; i++)
|
for (int i = 0; i < this->items; i++) {
|
||||||
if (this->array[i] && !Object_isA(this->array[i], this->type))
|
if (this->array[i] && !Object_isA(this->array[i], this->type)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -57,9 +63,10 @@ static bool Vector_isConsistent(const Vector* this) {
|
||||||
int Vector_count(const Vector* this) {
|
int Vector_count(const Vector* this) {
|
||||||
int items = 0;
|
int items = 0;
|
||||||
for (int i = 0; i < this->items; i++) {
|
for (int i = 0; i < this->items; i++) {
|
||||||
if (this->array[i])
|
if (this->array[i]) {
|
||||||
items++;
|
items++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
assert(items == this->items);
|
assert(items == this->items);
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +125,7 @@ static int partition(Object** array, int left, int right, int pivotIndex, Object
|
||||||
static void quickSort(Object** array, int left, int right, Object_Compare compare) {
|
static void quickSort(Object** array, int left, int right, Object_Compare compare) {
|
||||||
if (left >= right)
|
if (left >= right)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int pivotIndex = (left + right) / 2;
|
int pivotIndex = (left + right) / 2;
|
||||||
int pivotNewIndex = partition(array, left, right, pivotIndex, compare);
|
int pivotNewIndex = partition(array, left, right, pivotIndex, compare);
|
||||||
quickSort(array, left, pivotNewIndex - 1, compare);
|
quickSort(array, left, pivotNewIndex - 1, compare);
|
||||||
|
@ -155,6 +163,7 @@ static void insertionSort(Object** array, int left, int right, Object_Compare co
|
||||||
//comparisons++;
|
//comparisons++;
|
||||||
if (compare(array[j], t) <= 0)
|
if (compare(array[j], t) <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
array[j + 1] = array[j];
|
array[j + 1] = array[j];
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
@ -228,15 +237,18 @@ Object* Vector_remove(Vector* this, int idx) {
|
||||||
if (this->owner) {
|
if (this->owner) {
|
||||||
Object_delete(removed);
|
Object_delete(removed);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
} else {
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Vector_moveUp(Vector* this, int idx) {
|
void Vector_moveUp(Vector* this, int idx) {
|
||||||
assert(idx >= 0 && idx < this->items);
|
assert(idx >= 0 && idx < this->items);
|
||||||
assert(Vector_isConsistent(this));
|
assert(Vector_isConsistent(this));
|
||||||
|
|
||||||
if (idx == 0)
|
if (idx == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Object* temp = this->array[idx];
|
Object* temp = this->array[idx];
|
||||||
this->array[idx] = this->array[idx - 1];
|
this->array[idx] = this->array[idx - 1];
|
||||||
this->array[idx - 1] = temp;
|
this->array[idx - 1] = temp;
|
||||||
|
@ -245,8 +257,10 @@ void Vector_moveUp(Vector* this, int idx) {
|
||||||
void Vector_moveDown(Vector* this, int idx) {
|
void Vector_moveDown(Vector* this, int idx) {
|
||||||
assert(idx >= 0 && idx < this->items);
|
assert(idx >= 0 && idx < this->items);
|
||||||
assert(Vector_isConsistent(this));
|
assert(Vector_isConsistent(this));
|
||||||
|
|
||||||
if (idx == this->items - 1)
|
if (idx == this->items - 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Object* temp = this->array[idx];
|
Object* temp = this->array[idx];
|
||||||
this->array[idx] = this->array[idx + 1];
|
this->array[idx] = this->array[idx + 1];
|
||||||
this->array[idx + 1] = temp;
|
this->array[idx + 1] = temp;
|
||||||
|
@ -305,9 +319,10 @@ int Vector_indexOf(const Vector* this, const void* search_, Object_Compare compa
|
||||||
for (int i = 0; i < this->items; i++) {
|
for (int i = 0; i < this->items; i++) {
|
||||||
const Object* o = this->array[i];
|
const Object* o = this->array[i];
|
||||||
assert(o);
|
assert(o);
|
||||||
if (compare(search, o) == 0)
|
if (compare(search, o) == 0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +334,7 @@ void Vector_splice(Vector* this, Vector* from) {
|
||||||
int olditems = this->items;
|
int olditems = this->items;
|
||||||
this->items += from->items;
|
this->items += from->items;
|
||||||
Vector_checkArraySize(this);
|
Vector_checkArraySize(this);
|
||||||
for (int j = 0; j < from->items; j++)
|
for (int j = 0; j < from->items; j++) {
|
||||||
this->array[olditems + j] = from->array[j];
|
this->array[olditems + j] = from->array[j];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,9 @@ void GetKernelVersion(struct kern *k) {
|
||||||
char str[256] = {0};
|
char str[256] = {0};
|
||||||
size_t size = sizeof(str);
|
size_t size = sizeof(str);
|
||||||
int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
|
int ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
|
||||||
if (ret == 0) sscanf(str, "%hd.%hd.%hd", &version_[0], &version_[1], &version_[2]);
|
if (ret == 0) {
|
||||||
|
sscanf(str, "%hd.%hd.%hd", &version_[0], &version_[1], &version_[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memcpy(k->version, version_, sizeof(version_));
|
memcpy(k->version, version_, sizeof(version_));
|
||||||
}
|
}
|
||||||
|
@ -48,9 +50,17 @@ negative value if more than the installed version
|
||||||
int CompareKernelVersion(short int major, short int minor, short int component) {
|
int CompareKernelVersion(short int major, short int minor, short int component) {
|
||||||
struct kern k;
|
struct kern k;
|
||||||
GetKernelVersion(&k);
|
GetKernelVersion(&k);
|
||||||
if ( k.version[0] != major) return k.version[0] - major;
|
|
||||||
if ( k.version[1] != minor) return k.version[1] - minor;
|
if (k.version[0] != major) {
|
||||||
if ( k.version[2] != component) return k.version[2] - component;
|
return k.version[0] - major;
|
||||||
|
}
|
||||||
|
if (k.version[1] != minor) {
|
||||||
|
return k.version[1] - minor;
|
||||||
|
}
|
||||||
|
if (k.version[2] != component) {
|
||||||
|
return k.version[2] - component;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +96,10 @@ unsigned ProcessList_allocateCPULoadInfo(processor_cpu_load_info_t *p) {
|
||||||
void ProcessList_getVMStats(vm_statistics_t p) {
|
void ProcessList_getVMStats(vm_statistics_t p) {
|
||||||
mach_msg_type_number_t info_size = HOST_VM_INFO_COUNT;
|
mach_msg_type_number_t info_size = HOST_VM_INFO_COUNT;
|
||||||
|
|
||||||
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)p, &info_size) != 0)
|
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)p, &info_size) != 0) {
|
||||||
CRT_fatalError("Unable to retrieve VM statistics\n");
|
CRT_fatalError("Unable to retrieve VM statistics\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) {
|
struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) {
|
||||||
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
|
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
|
||||||
|
@ -99,15 +110,18 @@ struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) {
|
||||||
* process entry or two.
|
* process entry or two.
|
||||||
*/
|
*/
|
||||||
*count = 0;
|
*count = 0;
|
||||||
if (sysctl(mib, 4, NULL, count, NULL, 0) < 0)
|
if (sysctl(mib, 4, NULL, count, NULL, 0) < 0) {
|
||||||
CRT_fatalError("Unable to get size of kproc_infos");
|
CRT_fatalError("Unable to get size of kproc_infos");
|
||||||
|
}
|
||||||
|
|
||||||
processes = xMalloc(*count);
|
processes = xMalloc(*count);
|
||||||
if (processes == NULL)
|
if (processes == NULL) {
|
||||||
CRT_fatalError("Out of memory for kproc_infos");
|
CRT_fatalError("Out of memory for kproc_infos");
|
||||||
|
}
|
||||||
|
|
||||||
if (sysctl(mib, 4, processes, count, NULL, 0) < 0)
|
if (sysctl(mib, 4, processes, count, NULL, 0) < 0) {
|
||||||
CRT_fatalError("Unable to get kinfo_procs");
|
CRT_fatalError("Unable to get kinfo_procs");
|
||||||
|
}
|
||||||
|
|
||||||
*count = *count / sizeof(struct kinfo_proc);
|
*count = *count / sizeof(struct kinfo_proc);
|
||||||
|
|
||||||
|
@ -159,8 +173,9 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
openzfs_sysctl_updateArcStats(&dpl->zfs);
|
openzfs_sysctl_updateArcStats(&dpl->zfs);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the time difference */
|
/* Get the time difference */
|
||||||
dpl->global_diff = 0;
|
dpl->global_diff = 0;
|
||||||
|
|
|
@ -14,15 +14,17 @@ in the source distribution for its full text.
|
||||||
void Battery_getData(double* level, ACPresence* isOnAC) {
|
void Battery_getData(double* level, ACPresence* isOnAC) {
|
||||||
int life;
|
int life;
|
||||||
size_t life_len = sizeof(life);
|
size_t life_len = sizeof(life);
|
||||||
if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1)
|
if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1) {
|
||||||
*level = NAN;
|
*level = NAN;
|
||||||
else
|
} else {
|
||||||
*level = life;
|
*level = life;
|
||||||
|
}
|
||||||
|
|
||||||
int acline;
|
int acline;
|
||||||
size_t acline_len = sizeof(acline);
|
size_t acline_len = sizeof(acline);
|
||||||
if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1)
|
if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1) {
|
||||||
*isOnAC = AC_ERROR;
|
*isOnAC = AC_ERROR;
|
||||||
else
|
} else {
|
||||||
*isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
|
*isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -131,8 +131,9 @@ long DragonFlyBSDProcess_compare(const void* v1, const void* v2) {
|
||||||
bool Process_isThread(const Process* this) {
|
bool Process_isThread(const Process* this) {
|
||||||
const DragonFlyBSDProcess* fp = (const DragonFlyBSDProcess*) this;
|
const DragonFlyBSDProcess* fp = (const DragonFlyBSDProcess*) this;
|
||||||
|
|
||||||
if (fp->kernel == 1 )
|
if (fp->kernel == 1 ) {
|
||||||
return 1;
|
return 1;
|
||||||
else
|
} else {
|
||||||
return (Process_isUserlandThread(this));
|
return (Process_isUserlandThread(this));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -123,7 +123,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
|
||||||
|
|
||||||
void ProcessList_delete(ProcessList* this) {
|
void ProcessList_delete(ProcessList* this) {
|
||||||
const DragonFlyBSDProcessList* dfpl = (DragonFlyBSDProcessList*) this;
|
const DragonFlyBSDProcessList* dfpl = (DragonFlyBSDProcessList*) this;
|
||||||
if (dfpl->kd) kvm_close(dfpl->kd);
|
if (dfpl->kd) {
|
||||||
|
kvm_close(dfpl->kd);
|
||||||
|
}
|
||||||
|
|
||||||
if (dfpl->jails) {
|
if (dfpl->jails) {
|
||||||
Hashtable_delete(dfpl->jails);
|
Hashtable_delete(dfpl->jails);
|
||||||
|
@ -199,7 +201,9 @@ static inline void DragonFlyBSDProcessList_scanCPUTime(ProcessList* pl) {
|
||||||
|
|
||||||
// totals
|
// totals
|
||||||
total_d = total_n - total_o;
|
total_d = total_n - total_o;
|
||||||
if (total_d < 1 ) total_d = 1;
|
if (total_d < 1 ) {
|
||||||
|
total_d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// save current state as old and calc percentages
|
// save current state as old and calc percentages
|
||||||
for (int s = 0; s < CPUSTATES; ++s) {
|
for (int s = 0; s < CPUSTATES; ++s) {
|
||||||
|
@ -331,8 +335,9 @@ retry:
|
||||||
int jailid;
|
int jailid;
|
||||||
char* str_hostname;
|
char* str_hostname;
|
||||||
nextpos = strchr(curpos, '\n');
|
nextpos = strchr(curpos, '\n');
|
||||||
if (nextpos)
|
if (nextpos) {
|
||||||
*nextpos++ = 0;
|
*nextpos++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
jailid = atoi(strtok(curpos, " "));
|
jailid = atoi(strtok(curpos, " "));
|
||||||
str_hostname = strtok(NULL, " ");
|
str_hostname = strtok(NULL, " ");
|
||||||
|
@ -345,6 +350,7 @@ retry:
|
||||||
|
|
||||||
curpos = nextpos;
|
curpos = nextpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(jls);
|
free(jls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +377,9 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
DragonFlyBSDProcessList_scanJails(dfpl);
|
DragonFlyBSDProcessList_scanJails(dfpl);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -176,8 +176,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
percent = v[0] + v[1] + v[2];
|
percent = v[0] + v[1] + v[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
percent = CLAMP(percent, 0.0, 100.0);
|
percent = isnan(percent) ? 0.0 : CLAMP(percent, 0.0, 100.0);
|
||||||
if (isnan(percent)) percent = 0.0;
|
|
||||||
|
|
||||||
v[CPU_METER_FREQUENCY] = NAN;
|
v[CPU_METER_FREQUENCY] = NAN;
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,17 @@ in the source distribution for its full text.
|
||||||
void Battery_getData(double* level, ACPresence* isOnAC) {
|
void Battery_getData(double* level, ACPresence* isOnAC) {
|
||||||
int life;
|
int life;
|
||||||
size_t life_len = sizeof(life);
|
size_t life_len = sizeof(life);
|
||||||
if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1)
|
if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1) {
|
||||||
*level = NAN;
|
*level = NAN;
|
||||||
else
|
} else {
|
||||||
*level = life;
|
*level = life;
|
||||||
|
}
|
||||||
|
|
||||||
int acline;
|
int acline;
|
||||||
size_t acline_len = sizeof(acline);
|
size_t acline_len = sizeof(acline);
|
||||||
if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1)
|
if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1) {
|
||||||
*isOnAC = AC_ERROR;
|
*isOnAC = AC_ERROR;
|
||||||
else
|
} else {
|
||||||
*isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
|
*isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -134,11 +134,12 @@ static long FreeBSDProcess_compare(const void* v1, const void* v2) {
|
||||||
bool Process_isThread(const Process* this) {
|
bool Process_isThread(const Process* this) {
|
||||||
const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
|
const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
|
||||||
|
|
||||||
if (fp->kernel == 1 )
|
if (fp->kernel == 1 ) {
|
||||||
return 1;
|
return 1;
|
||||||
else
|
} else {
|
||||||
return Process_isUserlandThread(this);
|
return Process_isUserlandThread(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ProcessClass FreeBSDProcess_class = {
|
const ProcessClass FreeBSDProcess_class = {
|
||||||
.super = {
|
.super = {
|
||||||
|
|
|
@ -98,7 +98,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
|
||||||
|
|
||||||
if (smp) {
|
if (smp) {
|
||||||
int err = sysctlbyname("kern.smp.cpus", &cpus, &len, NULL, 0);
|
int err = sysctlbyname("kern.smp.cpus", &cpus, &len, NULL, 0);
|
||||||
if (err) cpus = 1;
|
if (err) {
|
||||||
|
cpus = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cpus = 1;
|
cpus = 1;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +154,9 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
|
|
||||||
Hashtable_delete(fpl->ttys);
|
Hashtable_delete(fpl->ttys);
|
||||||
|
|
||||||
if (fpl->kd) kvm_close(fpl->kd);
|
if (fpl->kd) {
|
||||||
|
kvm_close(fpl->kd);
|
||||||
|
}
|
||||||
|
|
||||||
free(fpl->cp_time_o);
|
free(fpl->cp_time_o);
|
||||||
free(fpl->cp_time_n);
|
free(fpl->cp_time_n);
|
||||||
|
@ -225,7 +229,9 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
|
||||||
|
|
||||||
// totals
|
// totals
|
||||||
total_d = total_n - total_o;
|
total_d = total_n - total_o;
|
||||||
if (total_d < 1 ) total_d = 1;
|
if (total_d < 1 ) {
|
||||||
|
total_d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// save current state as old and calc percentages
|
// save current state as old and calc percentages
|
||||||
for (int s = 0; s < CPUSTATES; ++s) {
|
for (int s = 0; s < CPUSTATES; ++s) {
|
||||||
|
@ -434,13 +440,15 @@ IGNORE_WCASTQUAL_END
|
||||||
jail_errmsg[0] = 0;
|
jail_errmsg[0] = 0;
|
||||||
jid = jail_get(jiov, 6, 0);
|
jid = jail_get(jiov, 6, 0);
|
||||||
if (jid < 0) {
|
if (jid < 0) {
|
||||||
if (!jail_errmsg[0])
|
if (!jail_errmsg[0]) {
|
||||||
xSnprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
|
xSnprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (jid == kproc->ki_jid) {
|
} else if (jid == kproc->ki_jid) {
|
||||||
jname = xStrdup(jnamebuf);
|
jname = xStrdup(jnamebuf);
|
||||||
if (jname == NULL)
|
if (jname == NULL) {
|
||||||
strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN);
|
strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN);
|
||||||
|
}
|
||||||
return jname;
|
return jname;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -464,11 +472,13 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
FreeBSDProcessList_scanCPUTime(super);
|
FreeBSDProcessList_scanCPUTime(super);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (settings->flags & PROCESS_FLAG_FREEBSD_TTY)
|
if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
|
||||||
FreeBSDProcessList_scanTTYs(super);
|
FreeBSDProcessList_scanTTYs(super);
|
||||||
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count);
|
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count);
|
||||||
|
@ -485,10 +495,11 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
if (!preExisting) {
|
if (!preExisting) {
|
||||||
fp->jid = kproc->ki_jid;
|
fp->jid = kproc->ki_jid;
|
||||||
proc->pid = kproc->ki_pid;
|
proc->pid = kproc->ki_pid;
|
||||||
if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM)
|
if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM) {
|
||||||
fp->kernel = 1;
|
fp->kernel = 1;
|
||||||
else
|
} else {
|
||||||
fp->kernel = 0;
|
fp->kernel = 0;
|
||||||
|
}
|
||||||
proc->ppid = kproc->ki_ppid;
|
proc->ppid = kproc->ki_ppid;
|
||||||
proc->tpgid = kproc->ki_tpgid;
|
proc->tpgid = kproc->ki_tpgid;
|
||||||
proc->tgid = kproc->ki_pid;
|
proc->tgid = kproc->ki_pid;
|
||||||
|
@ -565,8 +576,9 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
default: proc->state = '?';
|
default: proc->state = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->flags & PROCESS_FLAG_FREEBSD_TTY)
|
if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
|
||||||
fp->ttyPath = (kproc->ki_tdev == NODEV) ? nodevStr : Hashtable_get(fpl->ttys, kproc->ki_tdev);
|
fp->ttyPath = (kproc->ki_tdev == NODEV) ? nodevStr : Hashtable_get(fpl->ttys, kproc->ki_tdev);
|
||||||
|
}
|
||||||
|
|
||||||
if (Process_isKernelThread(proc))
|
if (Process_isKernelThread(proc))
|
||||||
super->kernelThreads++;
|
super->kernelThreads++;
|
||||||
|
|
19
htop.c
19
htop.c
|
@ -243,12 +243,13 @@ static void setCommFilter(State* state, char** commFilter) {
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
char* lc_ctype = getenv("LC_CTYPE");
|
char* lc_ctype = getenv("LC_CTYPE");
|
||||||
if(lc_ctype != NULL)
|
if (lc_ctype != NULL) {
|
||||||
setlocale(LC_CTYPE, lc_ctype);
|
setlocale(LC_CTYPE, lc_ctype);
|
||||||
else if ((lc_ctype = getenv("LC_ALL")))
|
} else if ((lc_ctype = getenv("LC_ALL"))) {
|
||||||
setlocale(LC_CTYPE, lc_ctype);
|
setlocale(LC_CTYPE, lc_ctype);
|
||||||
else
|
} else {
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
}
|
||||||
|
|
||||||
CommandLineSettings flags = parseArguments(argc, argv); // may exit()
|
CommandLineSettings flags = parseArguments(argc, argv); // may exit()
|
||||||
|
|
||||||
|
@ -271,14 +272,18 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
Header_populateFromSettings(header);
|
Header_populateFromSettings(header);
|
||||||
|
|
||||||
if (flags.delay != -1)
|
if (flags.delay != -1) {
|
||||||
settings->delay = flags.delay;
|
settings->delay = flags.delay;
|
||||||
if (!flags.useColors)
|
}
|
||||||
|
if (!flags.useColors) {
|
||||||
settings->colorScheme = COLORSCHEME_MONOCHROME;
|
settings->colorScheme = COLORSCHEME_MONOCHROME;
|
||||||
if (!flags.enableMouse)
|
}
|
||||||
|
if (!flags.enableMouse) {
|
||||||
settings->enableMouse = false;
|
settings->enableMouse = false;
|
||||||
if (flags.treeView)
|
}
|
||||||
|
if (flags.treeView) {
|
||||||
settings->treeView = true;
|
settings->treeView = true;
|
||||||
|
}
|
||||||
|
|
||||||
CRT_init(settings->delay, settings->colorScheme, flags.allowUnicode);
|
CRT_init(settings->delay, settings->colorScheme, flags.allowUnicode);
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,11 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short
|
||||||
struct dirent* dirEntry = readdir(batteryDir);
|
struct dirent* dirEntry = readdir(batteryDir);
|
||||||
if (!dirEntry)
|
if (!dirEntry)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
char* entryName = dirEntry->d_name;
|
char* entryName = dirEntry->d_name;
|
||||||
if (!String_startsWith(entryName, "BAT"))
|
if (!String_startsWith(entryName, "BAT"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
batteries[nBatteries] = xStrdup(entryName);
|
batteries[nBatteries] = xStrdup(entryName);
|
||||||
nBatteries++;
|
nBatteries++;
|
||||||
}
|
}
|
||||||
|
@ -74,12 +76,14 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short
|
||||||
for (unsigned short int j = 0; j < lineNum; j++) {
|
for (unsigned short int j = 0; j < lineNum; j++) {
|
||||||
free(line);
|
free(line);
|
||||||
line = String_readLine(file);
|
line = String_readLine(file);
|
||||||
if (!line) break;
|
if (!line)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
if (!line) break;
|
if (!line)
|
||||||
|
break;
|
||||||
|
|
||||||
char* foundNumStr = String_getToken(line, wordNum);
|
char* foundNumStr = String_getToken(line, wordNum);
|
||||||
const unsigned long int foundNum = atoi(foundNumStr);
|
const unsigned long int foundNum = atoi(foundNumStr);
|
||||||
|
@ -115,15 +119,18 @@ static ACPresence procAcpiCheck(void) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char statePath[256];
|
char statePath[256];
|
||||||
xSnprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
|
xSnprintf(statePath, sizeof(statePath), "%s/%s/state", power_supplyPath, entryName);
|
||||||
FILE* file = fopen(statePath, "r");
|
FILE* file = fopen(statePath, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
isOn = AC_ERROR;
|
isOn = AC_ERROR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char* line = String_readLine(file);
|
char* line = String_readLine(file);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
if (!line) continue;
|
|
||||||
|
if (!line)
|
||||||
|
continue;
|
||||||
|
|
||||||
char* isOnline = String_getToken(line, 2);
|
char* isOnline = String_getToken(line, 2);
|
||||||
free(line);
|
free(line);
|
||||||
|
@ -139,8 +146,10 @@ static ACPresence procAcpiCheck(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir)
|
if (dir) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
return isOn;
|
return isOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,14 +179,21 @@ static inline ssize_t xread(int fd, void *buf, size_t count) {
|
||||||
size_t alreadyRead = 0;
|
size_t alreadyRead = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t res = read(fd, buf, count);
|
ssize_t res = read(fd, buf, count);
|
||||||
if (res == -1 && errno == EINTR) continue;
|
if (res == -1) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
buf = ((char*)buf) + res;
|
buf = ((char*)buf) + res;
|
||||||
count -= res;
|
count -= res;
|
||||||
alreadyRead += res;
|
alreadyRead += res;
|
||||||
}
|
}
|
||||||
if (res == -1) return -1;
|
|
||||||
if (count == 0 || res == 0) return alreadyRead;
|
if (count == 0 || res == 0) {
|
||||||
|
return alreadyRead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +213,7 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
|
||||||
struct dirent* dirEntry = readdir(dir);
|
struct dirent* dirEntry = readdir(dir);
|
||||||
if (!dirEntry)
|
if (!dirEntry)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const char* entryName = dirEntry->d_name;
|
const char* entryName = dirEntry->d_name;
|
||||||
char filePath[256];
|
char filePath[256];
|
||||||
|
|
||||||
|
@ -232,9 +249,11 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
|
||||||
bool now = false;
|
bool now = false;
|
||||||
int fullSize = 0;
|
int fullSize = 0;
|
||||||
double capacityLevel = NAN;
|
double capacityLevel = NAN;
|
||||||
while ((line = strsep(&buf, "\n")) != NULL) {
|
|
||||||
#define match(str,prefix) \
|
#define match(str,prefix) \
|
||||||
(String_startsWith(str,prefix) ? (str) + strlen(prefix) : NULL)
|
(String_startsWith(str,prefix) ? (str) + strlen(prefix) : NULL)
|
||||||
|
|
||||||
|
while ((line = strsep(&buf, "\n")) != NULL) {
|
||||||
const char* ps = match(line, "POWER_SUPPLY_");
|
const char* ps = match(line, "POWER_SUPPLY_");
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -255,18 +274,24 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
|
||||||
fullSize = atoi(value);
|
fullSize = atoi(value);
|
||||||
totalFull += fullSize;
|
totalFull += fullSize;
|
||||||
full = true;
|
full = true;
|
||||||
if (now) break;
|
if (now) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
value = (!now) ? match(energy, "NOW=") : NULL;
|
value = (!now) ? match(energy, "NOW=") : NULL;
|
||||||
if (value) {
|
if (value) {
|
||||||
totalRemain += atoi(value);
|
totalRemain += atoi(value);
|
||||||
now = true;
|
now = true;
|
||||||
if (full) break;
|
if (full) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef match
|
#undef match
|
||||||
|
|
||||||
if (!now && full && !isnan(capacityLevel)) {
|
if (!now && full && !isnan(capacityLevel)) {
|
||||||
totalRemain += (capacityLevel * fullSize);
|
totalRemain += (capacityLevel * fullSize);
|
||||||
}
|
}
|
||||||
|
@ -284,7 +309,9 @@ static void Battery_getSysData(double* level, ACPresence* isOnAC) {
|
||||||
char buffer[2] = "";
|
char buffer[2] = "";
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t res = read(fd3, buffer, 1);
|
ssize_t res = read(fd3, buffer, 1);
|
||||||
if (res == -1 && errno == EINTR) continue;
|
if (res == -1 && errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(fd3);
|
close(fd3);
|
||||||
|
|
|
@ -21,8 +21,13 @@ Panel* IOPriorityPanel_new(IOPriority currPrio) {
|
||||||
|
|
||||||
Panel_setHeader(this, "IO Priority:");
|
Panel_setHeader(this, "IO Priority:");
|
||||||
Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None));
|
Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None));
|
||||||
if (currPrio == IOPriority_None) Panel_setSelected(this, 0);
|
if (currPrio == IOPriority_None) {
|
||||||
static const struct { int klass; const char* name; } classes[] = {
|
Panel_setSelected(this, 0);
|
||||||
|
}
|
||||||
|
static const struct {
|
||||||
|
int klass;
|
||||||
|
const char* name;
|
||||||
|
} classes[] = {
|
||||||
{ .klass = IOPRIO_CLASS_RT, .name = "Realtime" },
|
{ .klass = IOPRIO_CLASS_RT, .name = "Realtime" },
|
||||||
{ .klass = IOPRIO_CLASS_BE, .name = "Best-effort" },
|
{ .klass = IOPRIO_CLASS_BE, .name = "Best-effort" },
|
||||||
{ .klass = 0, .name = NULL }
|
{ .klass = 0, .name = NULL }
|
||||||
|
@ -33,11 +38,15 @@ Panel* IOPriorityPanel_new(IOPriority currPrio) {
|
||||||
xSnprintf(name, sizeof(name) - 1, "%s %d %s", classes[c].name, i, i == 0 ? "(High)" : (i == 7 ? "(Low)" : ""));
|
xSnprintf(name, sizeof(name) - 1, "%s %d %s", classes[c].name, i, i == 0 ? "(High)" : (i == 7 ? "(Low)" : ""));
|
||||||
IOPriority ioprio = IOPriority_tuple(classes[c].klass, i);
|
IOPriority ioprio = IOPriority_tuple(classes[c].klass, i);
|
||||||
Panel_add(this, (Object*) ListItem_new(name, ioprio));
|
Panel_add(this, (Object*) ListItem_new(name, ioprio));
|
||||||
if (currPrio == ioprio) Panel_setSelected(this, Panel_size(this) - 1);
|
if (currPrio == ioprio) {
|
||||||
|
Panel_setSelected(this, Panel_size(this) - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Panel_add(this, (Object*) ListItem_new("Idle", IOPriority_Idle));
|
Panel_add(this, (Object*) ListItem_new("Idle", IOPriority_Idle));
|
||||||
if (currPrio == IOPriority_Idle) Panel_setSelected(this, Panel_size(this) - 1);
|
if (currPrio == IOPriority_Idle) {
|
||||||
|
Panel_setSelected(this, Panel_size(this) - 1);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,8 +168,9 @@ dynamically derived from the cpu nice level of the process:
|
||||||
io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
|
io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
|
||||||
*/
|
*/
|
||||||
static int LinuxProcess_effectiveIOPriority(const LinuxProcess* this) {
|
static int LinuxProcess_effectiveIOPriority(const LinuxProcess* this) {
|
||||||
if (IOPriority_class(this->ioPriority) == IOPRIO_CLASS_NONE)
|
if (IOPriority_class(this->ioPriority) == IOPRIO_CLASS_NONE) {
|
||||||
return IOPriority_tuple(IOPRIO_CLASS_BE, (this->super.nice + 20) / 5);
|
return IOPriority_tuple(IOPRIO_CLASS_BE, (this->super.nice + 20) / 5);
|
||||||
|
}
|
||||||
|
|
||||||
return this->ioPriority;
|
return this->ioPriority;
|
||||||
}
|
}
|
||||||
|
@ -290,8 +291,9 @@ void LinuxProcess_writeField(const Process* this, RichString* str, ProcessField
|
||||||
case PERCENT_SWAP_DELAY: LinuxProcess_printDelay(lp->swapin_delay_percent, buffer, n); break;
|
case PERCENT_SWAP_DELAY: LinuxProcess_printDelay(lp->swapin_delay_percent, buffer, n); break;
|
||||||
#endif
|
#endif
|
||||||
case CTXT:
|
case CTXT:
|
||||||
if (lp->ctxt_diff > 1000)
|
if (lp->ctxt_diff > 1000) {
|
||||||
attr |= A_BOLD;
|
attr |= A_BOLD;
|
||||||
|
}
|
||||||
xSnprintf(buffer, n, "%5lu ", lp->ctxt_diff);
|
xSnprintf(buffer, n, "%5lu ", lp->ctxt_diff);
|
||||||
break;
|
break;
|
||||||
case SECATTR: snprintf(buffer, n, "%-30s ", lp->secattr ? lp->secattr : "?"); break;
|
case SECATTR: snprintf(buffer, n, "%-30s ", lp->secattr ? lp->secattr : "?"); break;
|
||||||
|
@ -379,6 +381,7 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
|
||||||
default:
|
default:
|
||||||
return Process_compare(v1, v2);
|
return Process_compare(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
test_diff:
|
test_diff:
|
||||||
return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
|
return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,14 +56,21 @@ static ssize_t xread(int fd, void *buf, size_t count) {
|
||||||
size_t alreadyRead = 0;
|
size_t alreadyRead = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t res = read(fd, buf, count);
|
ssize_t res = read(fd, buf, count);
|
||||||
if (res == -1 && errno == EINTR) continue;
|
if (res == -1) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
buf = ((char*)buf) + res;
|
buf = ((char*)buf) + res;
|
||||||
count -= res;
|
count -= res;
|
||||||
alreadyRead += res;
|
alreadyRead += res;
|
||||||
}
|
}
|
||||||
if (res == -1) return -1;
|
|
||||||
if (count == 0 || res == 0) return alreadyRead;
|
if (count == 0 || res == 0) {
|
||||||
|
return alreadyRead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +85,7 @@ static void LinuxProcessList_initTtyDrivers(LinuxProcessList* this) {
|
||||||
int fd = open(PROCTTYDRIVERSFILE, O_RDONLY);
|
int fd = open(PROCTTYDRIVERSFILE, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char* buf = NULL;
|
char* buf = NULL;
|
||||||
int bufSize = MAX_READ;
|
int bufSize = MAX_READ;
|
||||||
int bufLen = 0;
|
int bufLen = 0;
|
||||||
|
@ -160,21 +168,24 @@ static void LinuxProcessList_initNetlinkSocket(LinuxProcessList* this) {
|
||||||
|
|
||||||
static int LinuxProcessList_computeCPUcount(void) {
|
static int LinuxProcessList_computeCPUcount(void) {
|
||||||
FILE* file = fopen(PROCSTATFILE, "r");
|
FILE* file = fopen(PROCSTATFILE, "r");
|
||||||
if (file == NULL)
|
if (file == NULL) {
|
||||||
CRT_fatalError("Cannot open " PROCSTATFILE);
|
CRT_fatalError("Cannot open " PROCSTATFILE);
|
||||||
|
}
|
||||||
|
|
||||||
int cpus = 0;
|
int cpus = 0;
|
||||||
char buffer[PROC_LINE_LENGTH + 1];
|
char buffer[PROC_LINE_LENGTH + 1];
|
||||||
while (fgets(buffer, sizeof(buffer), file)) {
|
while (fgets(buffer, sizeof(buffer), file)) {
|
||||||
if (String_startsWith(buffer, "cpu"))
|
if (String_startsWith(buffer, "cpu")) {
|
||||||
cpus++;
|
cpus++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
/* subtract raw cpu entry */
|
/* subtract raw cpu entry */
|
||||||
if (cpus > 0)
|
if (cpus > 0) {
|
||||||
cpus--;
|
cpus--;
|
||||||
|
}
|
||||||
|
|
||||||
return cpus;
|
return cpus;
|
||||||
}
|
}
|
||||||
|
@ -218,16 +229,18 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
|
||||||
// Read btime
|
// Read btime
|
||||||
{
|
{
|
||||||
FILE* statfile = fopen(PROCSTATFILE, "r");
|
FILE* statfile = fopen(PROCSTATFILE, "r");
|
||||||
if (statfile == NULL)
|
if (statfile == NULL) {
|
||||||
CRT_fatalError("Cannot open " PROCSTATFILE);
|
CRT_fatalError("Cannot open " PROCSTATFILE);
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
char buffer[PROC_LINE_LENGTH + 1];
|
char buffer[PROC_LINE_LENGTH + 1];
|
||||||
if (fgets(buffer, sizeof(buffer), statfile) == NULL) {
|
if (fgets(buffer, sizeof(buffer), statfile) == NULL) {
|
||||||
CRT_fatalError("No btime in " PROCSTATFILE);
|
CRT_fatalError("No btime in " PROCSTATFILE);
|
||||||
} else if (String_startsWith(buffer, "btime ")) {
|
} else if (String_startsWith(buffer, "btime ")) {
|
||||||
if (sscanf(buffer, "btime %lld\n", &btime) != 1)
|
if (sscanf(buffer, "btime %lld\n", &btime) != 1) {
|
||||||
CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
|
CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,16 +311,19 @@ static bool LinuxProcessList_readStatFile(Process *process, const char* dirname,
|
||||||
|
|
||||||
int size = xread(fd, buf, MAX_READ);
|
int size = xread(fd, buf, MAX_READ);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (size <= 0) return false;
|
if (size <= 0)
|
||||||
|
return false;
|
||||||
buf[size] = '\0';
|
buf[size] = '\0';
|
||||||
|
|
||||||
assert(process->pid == atoi(buf));
|
assert(process->pid == atoi(buf));
|
||||||
char* location = strchr(buf, ' ');
|
char* location = strchr(buf, ' ');
|
||||||
if (!location) return false;
|
if (!location)
|
||||||
|
return false;
|
||||||
|
|
||||||
location += 2;
|
location += 2;
|
||||||
char* end = strrchr(location, ')');
|
char* end = strrchr(location, ')');
|
||||||
if (!end) return false;
|
if (!end)
|
||||||
|
return false;
|
||||||
|
|
||||||
int commsize = MINIMUM(end - location, commLenIn - 1);
|
int commsize = MINIMUM(end - location, commLenIn - 1);
|
||||||
// deepcode ignore BufferOverflow: commsize is bounded by the allocated length passed in by commLen, saved into commLenIn
|
// deepcode ignore BufferOverflow: commsize is bounded by the allocated length passed in by commLen, saved into commLenIn
|
||||||
|
@ -359,7 +375,9 @@ static bool LinuxProcessList_readStatFile(Process *process, const char* dirname,
|
||||||
location = strchr(location, ' ') + 1;
|
location = strchr(location, ' ') + 1;
|
||||||
}
|
}
|
||||||
location += 1;
|
location += 1;
|
||||||
for (int i=0; i<15; i++) location = strchr(location, ' ')+1;
|
for (int i = 0; i < 15; i++) {
|
||||||
|
location = strchr(location, ' ') + 1;
|
||||||
|
}
|
||||||
process->exit_signal = strtol(location, &location, 10);
|
process->exit_signal = strtol(location, &location, 10);
|
||||||
location += 1;
|
location += 1;
|
||||||
assert(location != NULL);
|
assert(location != NULL);
|
||||||
|
@ -410,7 +428,9 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, const char* dirna
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
ssize_t buflen = xread(fd, buffer, 1023);
|
ssize_t buflen = xread(fd, buffer, 1023);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (buflen < 1) return;
|
if (buflen < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
buffer[buflen] = '\0';
|
buffer[buflen] = '\0';
|
||||||
unsigned long long last_read = process->io_read_bytes;
|
unsigned long long last_read = process->io_read_bytes;
|
||||||
unsigned long long last_write = process->io_write_bytes;
|
unsigned long long last_write = process->io_write_bytes;
|
||||||
|
@ -419,9 +439,9 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, const char* dirna
|
||||||
while ((line = strsep(&buf, "\n")) != NULL) {
|
while ((line = strsep(&buf, "\n")) != NULL) {
|
||||||
switch (line[0]) {
|
switch (line[0]) {
|
||||||
case 'r':
|
case 'r':
|
||||||
if (line[1] == 'c' && String_startsWith(line+2, "har: "))
|
if (line[1] == 'c' && String_startsWith(line + 2, "har: ")) {
|
||||||
process->io_rchar = strtoull(line + 7, NULL, 10);
|
process->io_rchar = strtoull(line + 7, NULL, 10);
|
||||||
else if (String_startsWith(line+1, "ead_bytes: ")) {
|
} else if (String_startsWith(line + 1, "ead_bytes: ")) {
|
||||||
process->io_read_bytes = strtoull(line + 12, NULL, 10);
|
process->io_read_bytes = strtoull(line + 12, NULL, 10);
|
||||||
process->io_rate_read_bps =
|
process->io_rate_read_bps =
|
||||||
((double)(process->io_read_bytes - last_read)) / (((double)(now - process->io_rate_read_time)) / 1000);
|
((double)(process->io_read_bytes - last_read)) / (((double)(now - process->io_rate_read_time)) / 1000);
|
||||||
|
@ -429,9 +449,9 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, const char* dirna
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
if (line[1] == 'c' && String_startsWith(line+2, "har: "))
|
if (line[1] == 'c' && String_startsWith(line + 2, "har: ")) {
|
||||||
process->io_wchar = strtoull(line + 7, NULL, 10);
|
process->io_wchar = strtoull(line + 7, NULL, 10);
|
||||||
else if (String_startsWith(line+1, "rite_bytes: ")) {
|
} else if (String_startsWith(line + 1, "rite_bytes: ")) {
|
||||||
process->io_write_bytes = strtoull(line + 13, NULL, 10);
|
process->io_write_bytes = strtoull(line + 13, NULL, 10);
|
||||||
process->io_rate_write_bps =
|
process->io_rate_write_bps =
|
||||||
((double)(process->io_write_bytes - last_write)) / (((double)(now - process->io_rate_write_time)) / 1000);
|
((double)(process->io_write_bytes - last_write)) / (((double)(now - process->io_rate_write_time)) / 1000);
|
||||||
|
@ -463,6 +483,7 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, const char* di
|
||||||
FILE* statmfile = fopen(filename, "r");
|
FILE* statmfile = fopen(filename, "r");
|
||||||
if (!statmfile)
|
if (!statmfile)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int r = fscanf(statmfile, "%ld %ld %ld %ld %ld %ld %ld",
|
int r = fscanf(statmfile, "%ld %ld %ld %ld %ld %ld %ld",
|
||||||
&process->super.m_size,
|
&process->super.m_size,
|
||||||
&process->super.m_resident,
|
&process->super.m_resident,
|
||||||
|
@ -635,9 +656,13 @@ static void LinuxProcessList_readCGroupFile(LinuxProcess* process, const char* d
|
||||||
while (!feof(file) && left > 0) {
|
while (!feof(file) && left > 0) {
|
||||||
char buffer[PROC_LINE_LENGTH + 1];
|
char buffer[PROC_LINE_LENGTH + 1];
|
||||||
char* ok = fgets(buffer, PROC_LINE_LENGTH, file);
|
char* ok = fgets(buffer, PROC_LINE_LENGTH, file);
|
||||||
if (!ok) break;
|
if (!ok)
|
||||||
|
break;
|
||||||
|
|
||||||
char* group = strchr(buffer, ':');
|
char* group = strchr(buffer, ':');
|
||||||
if (!group) break;
|
if (!group)
|
||||||
|
break;
|
||||||
|
|
||||||
if (at != output) {
|
if (at != output) {
|
||||||
*at = ';';
|
*at = ';';
|
||||||
at++;
|
at++;
|
||||||
|
@ -661,6 +686,7 @@ static void LinuxProcessList_readVServerData(LinuxProcess* process, const char*
|
||||||
FILE* file = fopen(filename, "r");
|
FILE* file = fopen(filename, "r");
|
||||||
if (!file)
|
if (!file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buffer[PROC_LINE_LENGTH + 1];
|
char buffer[PROC_LINE_LENGTH + 1];
|
||||||
process->vxid = 0;
|
process->vxid = 0;
|
||||||
while (fgets(buffer, PROC_LINE_LENGTH, file)) {
|
while (fgets(buffer, PROC_LINE_LENGTH, file)) {
|
||||||
|
@ -710,21 +736,24 @@ static void LinuxProcessList_readCtxtData(LinuxProcess* process, const char* dir
|
||||||
FILE* file = fopen(filename, "r");
|
FILE* file = fopen(filename, "r");
|
||||||
if (!file)
|
if (!file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buffer[PROC_LINE_LENGTH + 1];
|
char buffer[PROC_LINE_LENGTH + 1];
|
||||||
unsigned long ctxt = 0;
|
unsigned long ctxt = 0;
|
||||||
while (fgets(buffer, PROC_LINE_LENGTH, file)) {
|
while (fgets(buffer, PROC_LINE_LENGTH, file)) {
|
||||||
if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
|
if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
|
||||||
unsigned long vctxt;
|
unsigned long vctxt;
|
||||||
int ok = sscanf(buffer, "voluntary_ctxt_switches:\t%lu", &vctxt);
|
int ok = sscanf(buffer, "voluntary_ctxt_switches:\t%lu", &vctxt);
|
||||||
if (ok >= 1)
|
if (ok >= 1) {
|
||||||
ctxt += vctxt;
|
ctxt += vctxt;
|
||||||
|
}
|
||||||
} else if (String_startsWith(buffer, "nonvoluntary_ctxt_switches:")) {
|
} else if (String_startsWith(buffer, "nonvoluntary_ctxt_switches:")) {
|
||||||
unsigned long nvctxt;
|
unsigned long nvctxt;
|
||||||
int ok = sscanf(buffer, "nonvoluntary_ctxt_switches:\t%lu", &nvctxt);
|
int ok = sscanf(buffer, "nonvoluntary_ctxt_switches:\t%lu", &nvctxt);
|
||||||
if (ok >= 1)
|
if (ok >= 1) {
|
||||||
ctxt += nvctxt;
|
ctxt += nvctxt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
process->ctxt_diff = (ctxt > process->ctxt_total) ? (ctxt - process->ctxt_total) : 0;
|
process->ctxt_diff = (ctxt > process->ctxt_total) ? (ctxt - process->ctxt_total) : 0;
|
||||||
process->ctxt_total = ctxt;
|
process->ctxt_total = ctxt;
|
||||||
|
@ -748,10 +777,12 @@ static void LinuxProcessList_readSecattrData(LinuxProcess* process, const char*
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char* newline = strchr(buffer, '\n');
|
char* newline = strchr(buffer, '\n');
|
||||||
if (newline)
|
if (newline) {
|
||||||
*newline = '\0';
|
*newline = '\0';
|
||||||
if (process->secattr && String_eq(process->secattr, buffer))
|
}
|
||||||
|
if (process->secattr && String_eq(process->secattr, buffer)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
free(process->secattr);
|
free(process->secattr);
|
||||||
process->secattr = xStrdup(buffer);
|
process->secattr = xStrdup(buffer);
|
||||||
}
|
}
|
||||||
|
@ -777,14 +808,15 @@ static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) {
|
||||||
memcpy(&stats, nla_data(nla_next(nla_data(nlattr), &rem)), sizeof(stats));
|
memcpy(&stats, nla_data(nla_next(nla_data(nlattr), &rem)), sizeof(stats));
|
||||||
assert(lp->super.pid == (pid_t)stats.ac_pid);
|
assert(lp->super.pid == (pid_t)stats.ac_pid);
|
||||||
|
|
||||||
timeDelta = (stats.ac_etime*1000 - lp->delay_read_time);
|
timeDelta = stats.ac_etime * 1000 - lp->delay_read_time;
|
||||||
#define BOUNDS(x) isnan(x) ? 0.0 : ((x) > 100) ? 100.0 : (x);
|
#define BOUNDS(x) (isnan(x) ? 0.0 : ((x) > 100) ? 100.0 : (x))
|
||||||
#define DELTAPERC(x,y) BOUNDS((float) ((x) - (y)) / timeDelta * 100);
|
#define DELTAPERC(x,y) BOUNDS((float) ((x) - (y)) / timeDelta * 100)
|
||||||
lp->cpu_delay_percent = DELTAPERC(stats.cpu_delay_total, lp->cpu_delay_total);
|
lp->cpu_delay_percent = DELTAPERC(stats.cpu_delay_total, lp->cpu_delay_total);
|
||||||
lp->blkio_delay_percent = DELTAPERC(stats.blkio_delay_total, lp->blkio_delay_total);
|
lp->blkio_delay_percent = DELTAPERC(stats.blkio_delay_total, lp->blkio_delay_total);
|
||||||
lp->swapin_delay_percent = DELTAPERC(stats.swapin_delay_total, lp->swapin_delay_total);
|
lp->swapin_delay_percent = DELTAPERC(stats.swapin_delay_total, lp->swapin_delay_total);
|
||||||
#undef DELTAPERC
|
#undef DELTAPERC
|
||||||
#undef BOUNDS
|
#undef BOUNDS
|
||||||
|
|
||||||
lp->swapin_delay_total = stats.swapin_delay_total;
|
lp->swapin_delay_total = stats.swapin_delay_total;
|
||||||
lp->blkio_delay_total = stats.blkio_delay_total;
|
lp->blkio_delay_total = stats.blkio_delay_total;
|
||||||
lp->cpu_delay_total = stats.cpu_delay_total;
|
lp->cpu_delay_total = stats.cpu_delay_total;
|
||||||
|
@ -903,17 +935,28 @@ static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned in
|
||||||
for (;;) {
|
for (;;) {
|
||||||
xAsprintf(&fullPath, "%s/%d", ttyDrivers[i].path, idx);
|
xAsprintf(&fullPath, "%s/%d", ttyDrivers[i].path, idx);
|
||||||
int err = stat(fullPath, &sstat);
|
int err = stat(fullPath, &sstat);
|
||||||
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
|
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
free(fullPath);
|
free(fullPath);
|
||||||
|
|
||||||
xAsprintf(&fullPath, "%s%d", ttyDrivers[i].path, idx);
|
xAsprintf(&fullPath, "%s%d", ttyDrivers[i].path, idx);
|
||||||
err = stat(fullPath, &sstat);
|
err = stat(fullPath, &sstat);
|
||||||
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) return fullPath;
|
if (err == 0 && major(sstat.st_rdev) == maj && minor(sstat.st_rdev) == min) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
free(fullPath);
|
free(fullPath);
|
||||||
if (idx == min) break;
|
|
||||||
|
if (idx == min) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
idx = min;
|
idx = min;
|
||||||
}
|
}
|
||||||
int err = stat(ttyDrivers[i].path, &sstat);
|
int err = stat(ttyDrivers[i].path, &sstat);
|
||||||
if (err == 0 && tty_nr == sstat.st_rdev) return xStrdup(ttyDrivers[i].path);
|
if (err == 0 && tty_nr == sstat.st_rdev) {
|
||||||
|
return xStrdup(ttyDrivers[i].path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
char* out;
|
char* out;
|
||||||
xAsprintf(&out, "/dev/%u:%u", maj, min);
|
xAsprintf(&out, "/dev/%u:%u", maj, min);
|
||||||
|
@ -931,7 +974,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dir = opendir(dirname);
|
dir = opendir(dirname);
|
||||||
if (!dir) return false;
|
if (!dir)
|
||||||
|
return false;
|
||||||
|
|
||||||
int cpus = pl->cpuCount;
|
int cpus = pl->cpuCount;
|
||||||
bool hideKernelThreads = settings->hideKernelThreads;
|
bool hideKernelThreads = settings->hideKernelThreads;
|
||||||
bool hideUserlandThreads = settings->hideUserlandThreads;
|
bool hideUserlandThreads = settings->hideUserlandThreads;
|
||||||
|
@ -999,15 +1044,18 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
unsigned int tty_nr = proc->tty_nr;
|
unsigned int tty_nr = proc->tty_nr;
|
||||||
if (! LinuxProcessList_readStatFile(proc, dirname, name, command, &commLen))
|
if (! LinuxProcessList_readStatFile(proc, dirname, name, command, &commLen))
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
|
|
||||||
if (tty_nr != proc->tty_nr && this->ttyDrivers) {
|
if (tty_nr != proc->tty_nr && this->ttyDrivers) {
|
||||||
free(lp->ttyDevice);
|
free(lp->ttyDevice);
|
||||||
lp->ttyDevice = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
|
lp->ttyDevice = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
|
||||||
}
|
}
|
||||||
if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO)
|
|
||||||
|
if (settings->flags & PROCESS_FLAG_LINUX_IOPRIO) {
|
||||||
LinuxProcess_updateIOPriority(lp);
|
LinuxProcess_updateIOPriority(lp);
|
||||||
|
}
|
||||||
|
|
||||||
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
|
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
|
||||||
proc->percent_cpu = CLAMP(percent_cpu, 0.0, cpus * 100.0);
|
proc->percent_cpu = isnan(percent_cpu) ? 0.0 : CLAMP(percent_cpu, 0.0, cpus * 100.0);
|
||||||
if (isnan(proc->percent_cpu)) proc->percent_cpu = 0.0;
|
|
||||||
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(pl->totalMem) * 100.0;
|
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(pl->totalMem) * 100.0;
|
||||||
|
|
||||||
if (!preExisting) {
|
if (!preExisting) {
|
||||||
|
@ -1049,18 +1097,22 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CGROUP
|
#ifdef HAVE_CGROUP
|
||||||
if (settings->flags & PROCESS_FLAG_LINUX_CGROUP)
|
if (settings->flags & PROCESS_FLAG_LINUX_CGROUP) {
|
||||||
LinuxProcessList_readCGroupFile(lp, dirname, name);
|
LinuxProcessList_readCGroupFile(lp, dirname, name);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (settings->flags & PROCESS_FLAG_LINUX_OOM)
|
if (settings->flags & PROCESS_FLAG_LINUX_OOM) {
|
||||||
LinuxProcessList_readOomData(lp, dirname, name);
|
LinuxProcessList_readOomData(lp, dirname, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (settings->flags & PROCESS_FLAG_LINUX_CTXT)
|
if (settings->flags & PROCESS_FLAG_LINUX_CTXT) {
|
||||||
LinuxProcessList_readCtxtData(lp, dirname, name);
|
LinuxProcessList_readCtxtData(lp, dirname, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (settings->flags & PROCESS_FLAG_LINUX_SECATTR)
|
if (settings->flags & PROCESS_FLAG_LINUX_SECATTR) {
|
||||||
LinuxProcessList_readSecattrData(lp, dirname, name);
|
LinuxProcessList_readSecattrData(lp, dirname, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
|
if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
|
||||||
proc->basenameOffset = -1;
|
proc->basenameOffset = -1;
|
||||||
|
@ -1070,9 +1122,10 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
proc->basenameOffset = -1;
|
proc->basenameOffset = -1;
|
||||||
setCommand(proc, command, commLen);
|
setCommand(proc, command, commLen);
|
||||||
} else if (settings->showThreadNames) {
|
} else if (settings->showThreadNames) {
|
||||||
if (! LinuxProcessList_readCmdlineFile(proc, dirname, name))
|
if (! LinuxProcessList_readCmdlineFile(proc, dirname, name)) {
|
||||||
goto errorReadingProcess;
|
goto errorReadingProcess;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (Process_isKernelThread(proc)) {
|
if (Process_isKernelThread(proc)) {
|
||||||
pl->kernelThreads++;
|
pl->kernelThreads++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1087,7 +1140,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Exception handler.
|
// Exception handler.
|
||||||
errorReadingProcess: {
|
|
||||||
|
errorReadingProcess:
|
||||||
|
{
|
||||||
if (preExisting) {
|
if (preExisting) {
|
||||||
ProcessList_remove(pl, proc);
|
ProcessList_remove(pl, proc);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1111,7 +1166,12 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
while (fgets(buffer, 128, file)) {
|
while (fgets(buffer, 128, file)) {
|
||||||
|
|
||||||
#define tryRead(label, variable) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %32llu kB", variable)) { break; } } while(0)
|
#define tryRead(label, variable) \
|
||||||
|
if (String_startsWith(buffer, label)) { \
|
||||||
|
sscanf(buffer + strlen(label), " %32llu kB", variable); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
switch (buffer[0]) {
|
switch (buffer[0]) {
|
||||||
case 'M':
|
case 'M':
|
||||||
tryRead("MemTotal:", &this->totalMem);
|
tryRead("MemTotal:", &this->totalMem);
|
||||||
|
@ -1208,8 +1268,17 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
|
||||||
}
|
}
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
while (fgets(buffer, 128, file)) {
|
while (fgets(buffer, 128, file)) {
|
||||||
#define tryRead(label, variable) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %*2u %32llu", variable)) { break; } } while(0)
|
#define tryRead(label, variable) \
|
||||||
#define tryReadFlag(label, variable, flag) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %*2u %32llu", variable)) { (flag) = 1; break; } else { (flag) = 0; } } while(0)
|
if (String_startsWith(buffer, label)) { \
|
||||||
|
sscanf(buffer + strlen(label), " %*2u %32llu", variable); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
#define tryReadFlag(label, variable, flag) \
|
||||||
|
if (String_startsWith(buffer, label)) { \
|
||||||
|
(flag) = sscanf(buffer + strlen(label), " %*2u %32llu", variable); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
switch (buffer[0]) {
|
switch (buffer[0]) {
|
||||||
case 'c':
|
case 'c':
|
||||||
tryRead("c_max", &lpl->zfs.max);
|
tryRead("c_max", &lpl->zfs.max);
|
||||||
|
@ -1275,10 +1344,13 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
|
||||||
// 5, 7, 8 or 9 of these fields will be set.
|
// 5, 7, 8 or 9 of these fields will be set.
|
||||||
// The rest will remain at zero.
|
// The rest will remain at zero.
|
||||||
char* ok = fgets(buffer, PROC_LINE_LENGTH, file);
|
char* ok = fgets(buffer, PROC_LINE_LENGTH, file);
|
||||||
if (!ok) buffer[0] = '\0';
|
if (!ok) {
|
||||||
if (i == 0)
|
buffer[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
(void) sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
|
(void) sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
|
||||||
else {
|
} else {
|
||||||
int cpuid;
|
int cpuid;
|
||||||
(void) sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
|
(void) sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
|
||||||
assert(cpuid == i - 1);
|
assert(cpuid == i - 1);
|
||||||
|
@ -1322,8 +1394,8 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
|
||||||
cpuData->stealTime = steal;
|
cpuData->stealTime = steal;
|
||||||
cpuData->guestTime = virtalltime;
|
cpuData->guestTime = virtalltime;
|
||||||
cpuData->totalTime = totaltime;
|
cpuData->totalTime = totaltime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double period = (double)this->cpus[0].totalPeriod / cpus;
|
double period = (double)this->cpus[0].totalPeriod / cpus;
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return period;
|
return period;
|
||||||
|
@ -1386,13 +1458,15 @@ static void scanCPUFreqencyFromCPUinfo(LinuxProcessList* this) {
|
||||||
(sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||
|
(sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||
|
||||||
(sscanf(buffer, "cpu MHz: %lf", &frequency) == 1)
|
(sscanf(buffer, "cpu MHz: %lf", &frequency) == 1)
|
||||||
) {
|
) {
|
||||||
if (cpuid < 0 || cpuid > (cpus - 1))
|
if (cpuid < 0 || cpuid > (cpus - 1)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
CPUData* cpuData = &(this->cpus[cpuid + 1]);
|
CPUData* cpuData = &(this->cpus[cpuid + 1]);
|
||||||
/* do not override sysfs data */
|
/* do not override sysfs data */
|
||||||
if (isnan(cpuData->frequency))
|
if (isnan(cpuData->frequency)) {
|
||||||
cpuData->frequency = frequency;
|
cpuData->frequency = frequency;
|
||||||
|
}
|
||||||
numCPUsWithFrequency++;
|
numCPUsWithFrequency++;
|
||||||
totalFrequency += frequency;
|
totalFrequency += frequency;
|
||||||
} else if (buffer[0] == '\n') {
|
} else if (buffer[0] == '\n') {
|
||||||
|
@ -1401,19 +1475,22 @@ static void scanCPUFreqencyFromCPUinfo(LinuxProcessList* this) {
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
if (numCPUsWithFrequency > 0)
|
if (numCPUsWithFrequency > 0) {
|
||||||
this->cpus[0].frequency = totalFrequency / numCPUsWithFrequency;
|
this->cpus[0].frequency = totalFrequency / numCPUsWithFrequency;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
|
static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
|
||||||
int cpus = this->super.cpuCount;
|
int cpus = this->super.cpuCount;
|
||||||
assert(cpus > 0);
|
assert(cpus > 0);
|
||||||
|
|
||||||
for (int i = 0; i <= cpus; i++)
|
for (int i = 0; i <= cpus; i++) {
|
||||||
this->cpus[i].frequency = NAN;
|
this->cpus[i].frequency = NAN;
|
||||||
|
}
|
||||||
|
|
||||||
if (scanCPUFreqencyFromSysCPUFreq(this) == 0)
|
if (scanCPUFreqencyFromSysCPUFreq(this) == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scanCPUFreqencyFromCPUinfo(this);
|
scanCPUFreqencyFromCPUinfo(this);
|
||||||
}
|
}
|
||||||
|
@ -1429,12 +1506,14 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
|
|
||||||
double period = LinuxProcessList_scanCPUTime(this);
|
double period = LinuxProcessList_scanCPUTime(this);
|
||||||
|
|
||||||
if (settings->showCPUFrequency)
|
if (settings->showCPUFrequency) {
|
||||||
LinuxProcessList_scanCPUFrequency(this);
|
LinuxProcessList_scanCPUFrequency(this);
|
||||||
|
}
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
|
|
@ -103,16 +103,19 @@ static Htop_Reaction Platform_actionSetIOPriority(State* st) {
|
||||||
Panel* panel = st->panel;
|
Panel* panel = st->panel;
|
||||||
|
|
||||||
LinuxProcess* p = (LinuxProcess*) Panel_getSelected(panel);
|
LinuxProcess* p = (LinuxProcess*) Panel_getSelected(panel);
|
||||||
if (!p) return HTOP_OK;
|
if (!p)
|
||||||
|
return HTOP_OK;
|
||||||
|
|
||||||
IOPriority ioprio1 = p->ioPriority;
|
IOPriority ioprio1 = p->ioPriority;
|
||||||
Panel* ioprioPanel = IOPriorityPanel_new(ioprio1);
|
Panel* ioprioPanel = IOPriorityPanel_new(ioprio1);
|
||||||
void* set = Action_pickFromVector(st, ioprioPanel, 21, true);
|
void* set = Action_pickFromVector(st, ioprioPanel, 21, true);
|
||||||
if (set) {
|
if (set) {
|
||||||
IOPriority ioprio2 = IOPriorityPanel_getIOPriority(ioprioPanel);
|
IOPriority ioprio2 = IOPriorityPanel_getIOPriority(ioprioPanel);
|
||||||
bool ok = MainPanel_foreachProcess((MainPanel*)panel, LinuxProcess_setIOPriority, (Arg) { .i = ioprio2 }, NULL);
|
bool ok = MainPanel_foreachProcess((MainPanel*)panel, LinuxProcess_setIOPriority, (Arg) { .i = ioprio2 }, NULL);
|
||||||
if (!ok)
|
if (!ok) {
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Panel_delete((Object*)ioprioPanel);
|
Panel_delete((Object*)ioprioPanel);
|
||||||
return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR;
|
||||||
}
|
}
|
||||||
|
@ -167,14 +170,19 @@ int Platform_getUptime() {
|
||||||
if (fd) {
|
if (fd) {
|
||||||
int n = fscanf(fd, "%64lf", &uptime);
|
int n = fscanf(fd, "%64lf", &uptime);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
if (n <= 0) return 0;
|
if (n <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return floor(uptime);
|
return floor(uptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
|
void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
|
||||||
int activeProcs, totalProcs, lastProc;
|
int activeProcs, totalProcs, lastProc;
|
||||||
*one = 0; *five = 0; *fifteen = 0;
|
*one = 0;
|
||||||
|
*five = 0;
|
||||||
|
*fifteen = 0;
|
||||||
|
|
||||||
FILE* fd = fopen(PROCDIR "/loadavg", "r");
|
FILE* fd = fopen(PROCDIR "/loadavg", "r");
|
||||||
if (fd) {
|
if (fd) {
|
||||||
int total = fscanf(fd, "%32lf %32lf %32lf %32d/%32d %32d", one, five, fifteen,
|
int total = fscanf(fd, "%32lf %32lf %32lf %32d/%32d %32d", one, five, fifteen,
|
||||||
|
@ -187,7 +195,9 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
|
||||||
|
|
||||||
int Platform_getMaxPid() {
|
int Platform_getMaxPid() {
|
||||||
FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r");
|
FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r");
|
||||||
if (!file) return -1;
|
if (!file)
|
||||||
|
return -1;
|
||||||
|
|
||||||
int maxPid = 4194303;
|
int maxPid = 4194303;
|
||||||
int match = fscanf(file, "%32d", &maxPid);
|
int match = fscanf(file, "%32d", &maxPid);
|
||||||
(void) match;
|
(void) match;
|
||||||
|
@ -223,7 +233,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
percent = v[0] + v[1] + v[2] + v[3];
|
percent = v[0] + v[1] + v[2] + v[3];
|
||||||
}
|
}
|
||||||
percent = CLAMP(percent, 0.0, 100.0);
|
percent = CLAMP(percent, 0.0, 100.0);
|
||||||
if (isnan(percent)) percent = 0.0;
|
if (isnan(percent)) {
|
||||||
|
percent = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
v[CPU_METER_FREQUENCY] = cpuData->frequency;
|
v[CPU_METER_FREQUENCY] = cpuData->frequency;
|
||||||
|
|
||||||
|
|
|
@ -32,16 +32,19 @@ static bool enforcing = false;
|
||||||
static bool hasSELinuxMount(void) {
|
static bool hasSELinuxMount(void) {
|
||||||
struct statfs sfbuf;
|
struct statfs sfbuf;
|
||||||
int r = statfs("/sys/fs/selinux", &sfbuf);
|
int r = statfs("/sys/fs/selinux", &sfbuf);
|
||||||
if (r != 0)
|
if (r != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sfbuf.f_type != SELINUX_MAGIC)
|
if (sfbuf.f_type != SELINUX_MAGIC) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
r = statvfs("/sys/fs/selinux", &vfsbuf);
|
r = statvfs("/sys/fs/selinux", &vfsbuf);
|
||||||
if (r != 0 || (vfsbuf.f_flag & ST_RDONLY))
|
if (r != 0 || (vfsbuf.f_flag & ST_RDONLY)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -51,22 +54,26 @@ static bool isSelinuxEnabled(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isSelinuxEnforcing(void) {
|
static bool isSelinuxEnforcing(void) {
|
||||||
if (!enabled)
|
if (!enabled) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int fd = open("/sys/fs/selinux/enforce", O_RDONLY);
|
int fd = open("/sys/fs/selinux/enforce", O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char buf[20] = {0};
|
char buf[20] = {0};
|
||||||
int r = read(fd, buf, sizeof(buf) - 1);
|
int r = read(fd, buf, sizeof(buf) - 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int enforce = 0;
|
int enforce = 0;
|
||||||
if (sscanf(buf, "%d", &enforce) != 1)
|
if (sscanf(buf, "%d", &enforce) != 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !!enforce;
|
return !!enforce;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,127 +32,152 @@ ProcessFieldData Process_fields[] = {
|
||||||
.name = "",
|
.name = "",
|
||||||
.title = NULL,
|
.title = NULL,
|
||||||
.description = NULL,
|
.description = NULL,
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PID] = {
|
[PID] = {
|
||||||
.name = "PID",
|
.name = "PID",
|
||||||
.title = " PID ",
|
.title = " PID ",
|
||||||
.description = "Process/thread ID",
|
.description = "Process/thread ID",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[COMM] = {
|
[COMM] = {
|
||||||
.name = "Command",
|
.name = "Command",
|
||||||
.title = "Command ",
|
.title = "Command ",
|
||||||
.description = "Command line",
|
.description = "Command line",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[STATE] = {
|
[STATE] = {
|
||||||
.name = "STATE",
|
.name = "STATE",
|
||||||
.title = "S ",
|
.title = "S ",
|
||||||
.description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)",
|
.description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PPID] = {
|
[PPID] = {
|
||||||
.name = "PPID",
|
.name = "PPID",
|
||||||
.title = " PPID ",
|
.title = " PPID ",
|
||||||
.description = "Parent process ID",
|
.description = "Parent process ID",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PGRP] = {
|
[PGRP] = {
|
||||||
.name = "PGRP",
|
.name = "PGRP",
|
||||||
.title = " PGRP ",
|
.title = " PGRP ",
|
||||||
.description = "Process group ID",
|
.description = "Process group ID",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[SESSION] = {
|
[SESSION] = {
|
||||||
.name = "SESSION",
|
.name = "SESSION",
|
||||||
.title = " SESN ",
|
.title = " SESN ",
|
||||||
.description = "Process's session ID",
|
.description = "Process's session ID",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[TTY_NR] = {
|
[TTY_NR] = {
|
||||||
.name = "TTY_NR",
|
.name = "TTY_NR",
|
||||||
.title = " TTY ",
|
.title = " TTY ",
|
||||||
.description = "Controlling terminal",
|
.description = "Controlling terminal",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[TPGID] = {
|
[TPGID] = {
|
||||||
.name = "TPGID",
|
.name = "TPGID",
|
||||||
.title = " TPGID ",
|
.title = " TPGID ",
|
||||||
.description = "Process ID of the fg process group of the controlling terminal",
|
.description = "Process ID of the fg process group of the controlling terminal",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[MINFLT] = {
|
[MINFLT] = {
|
||||||
.name = "MINFLT",
|
.name = "MINFLT",
|
||||||
.title = " MINFLT ",
|
.title = " MINFLT ",
|
||||||
.description = "Number of minor faults which have not required loading a memory page from disk",
|
.description = "Number of minor faults which have not required loading a memory page from disk",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[MAJFLT] = {
|
[MAJFLT] = {
|
||||||
.name = "MAJFLT",
|
.name = "MAJFLT",
|
||||||
.title = " MAJFLT ",
|
.title = " MAJFLT ",
|
||||||
.description = "Number of major faults which have required loading a memory page from disk",
|
.description = "Number of major faults which have required loading a memory page from disk",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PRIORITY] = {
|
[PRIORITY] = {
|
||||||
.name = "PRIORITY",
|
.name = "PRIORITY",
|
||||||
.title = "PRI ",
|
.title = "PRI ",
|
||||||
.description = "Kernel's internal priority for the process",
|
.description = "Kernel's internal priority for the process",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[NICE] = {
|
[NICE] = {
|
||||||
.name = "NICE",
|
.name = "NICE",
|
||||||
.title = " NI ",
|
.title = " NI ",
|
||||||
.description = "Nice value (the higher the value, the more it lets other processes take priority)",
|
.description = "Nice value (the higher the value, the more it lets other processes take priority)",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[STARTTIME] = {
|
[STARTTIME] = {
|
||||||
.name = "STARTTIME",
|
.name = "STARTTIME",
|
||||||
.title = "START ",
|
.title = "START ",
|
||||||
.description = "Time the process was started",
|
.description = "Time the process was started",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PROCESSOR] = {
|
[PROCESSOR] = {
|
||||||
.name = "PROCESSOR",
|
.name = "PROCESSOR",
|
||||||
.title = "CPU ",
|
.title = "CPU ",
|
||||||
.description = "Id of the CPU the process last executed on",
|
.description = "Id of the CPU the process last executed on",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[M_SIZE] = {
|
[M_SIZE] = {
|
||||||
.name = "M_SIZE",
|
.name = "M_SIZE",
|
||||||
.title = " VIRT ",
|
.title = " VIRT ",
|
||||||
.description = "Total program size in virtual memory",
|
.description = "Total program size in virtual memory",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[M_RESIDENT] = {
|
[M_RESIDENT] = {
|
||||||
.name = "M_RESIDENT",
|
.name = "M_RESIDENT",
|
||||||
.title = " RES ",
|
.title = " RES ",
|
||||||
.description = "Resident set size, size of the text and data sections, plus stack usage",
|
.description = "Resident set size, size of the text and data sections, plus stack usage",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[ST_UID] = {
|
[ST_UID] = {
|
||||||
.name = "ST_UID",
|
.name = "ST_UID",
|
||||||
.title = " UID ",
|
.title = " UID ",
|
||||||
.description = "User ID of the process owner",
|
.description = "User ID of the process owner",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PERCENT_CPU] = {
|
[PERCENT_CPU] = {
|
||||||
.name = "PERCENT_CPU",
|
.name = "PERCENT_CPU",
|
||||||
.title = "CPU% ",
|
.title = "CPU% ",
|
||||||
.description = "Percentage of the CPU time the process used in the last sampling",
|
.description = "Percentage of the CPU time the process used in the last sampling",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[PERCENT_MEM] = {
|
[PERCENT_MEM] = {
|
||||||
.name = "PERCENT_MEM",
|
.name = "PERCENT_MEM",
|
||||||
.title = "MEM% ",
|
.title = "MEM% ",
|
||||||
.description = "Percentage of the memory the process is using, based on resident memory size",
|
.description = "Percentage of the memory the process is using, based on resident memory size",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[USER] = {
|
[USER] = {
|
||||||
.name = "USER",
|
.name = "USER",
|
||||||
.title = "USER ",
|
.title = "USER ",
|
||||||
.description = "Username of the process owner (or user ID if name cannot be determined)",
|
.description = "Username of the process owner (or user ID if name cannot be determined)",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[TIME] = {
|
[TIME] = {
|
||||||
.name = "TIME",
|
.name = "TIME",
|
||||||
.title = " TIME+ ",
|
.title = " TIME+ ",
|
||||||
.description = "Total time the process has spent in user and system time",
|
.description = "Total time the process has spent in user and system time",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[NLWP] = {
|
[NLWP] = {
|
||||||
.name = "NLWP",
|
.name = "NLWP",
|
||||||
.title = "NLWP ",
|
.title = "NLWP ",
|
||||||
.description = "Number of threads in the process",
|
.description = "Number of threads in the process",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[TGID] = {
|
[TGID] = {
|
||||||
.name = "TGID",
|
.name = "TGID",
|
||||||
.title = " TGID ",
|
.title = " TGID ",
|
||||||
.description = "Thread group ID (i.e. process ID)",
|
.description = "Thread group ID (i.e. process ID)",
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
[LAST_PROCESSFIELD] = {
|
[LAST_PROCESSFIELD] = {
|
||||||
.name = "*** report bug! ***",
|
.name = "*** report bug! ***",
|
||||||
.title = NULL,
|
.title = NULL,
|
||||||
.description = NULL,
|
.description = NULL,
|
||||||
.flags = 0, },
|
.flags = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ProcessPidColumn Process_pidColumns[] = {
|
ProcessPidColumn Process_pidColumns[] = {
|
||||||
|
|
|
@ -177,7 +177,7 @@ char *OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, in
|
||||||
*/
|
*/
|
||||||
static double getpcpu(const struct kinfo_proc* kp) {
|
static double getpcpu(const struct kinfo_proc* kp) {
|
||||||
if (fscale == 0)
|
if (fscale == 0)
|
||||||
return (0.0);
|
return 0.0;
|
||||||
|
|
||||||
#define fxtofl(fixpt) ((double)(fixpt) / fscale)
|
#define fxtofl(fixpt) ((double)(fixpt) / fscale)
|
||||||
|
|
||||||
|
@ -347,8 +347,9 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
OpenBSDProcessList_scanCPUTime(opl);
|
OpenBSDProcessList_scanCPUTime(opl);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OpenBSDProcessList_scanProcs(opl);
|
OpenBSDProcessList_scanProcs(opl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPercent = CLAMP(totalPercent, 0.0, 100.0);
|
totalPercent = CLAMP(totalPercent, 0.0, 100.0);
|
||||||
if (isnan(totalPercent)) totalPercent = 0.0;
|
if (isnan(totalPercent)) {
|
||||||
|
totalPercent = 0.0;
|
||||||
|
}
|
||||||
return totalPercent;
|
return totalPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,11 +252,12 @@ char* Platform_getProcessEnv(pid_t pid) {
|
||||||
struct kinfo_proc* kproc;
|
struct kinfo_proc* kproc;
|
||||||
size_t capacity = 4096, size = 0;
|
size_t capacity = 4096, size = 0;
|
||||||
|
|
||||||
if ((kt = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL)
|
if ((kt = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((kproc = kvm_getprocs(kt, KERN_PROC_PID, pid,
|
if ((kproc = kvm_getprocs(kt, KERN_PROC_PID, pid,
|
||||||
sizeof(struct kinfo_proc), &count)) == NULL) {\
|
sizeof(struct kinfo_proc), &count)) == NULL) {
|
||||||
(void) kvm_close(kt);
|
(void) kvm_close(kt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,13 +156,19 @@ int Platform_getMaxPid() {
|
||||||
kvar_t* ksvar = NULL;
|
kvar_t* ksvar = NULL;
|
||||||
int vproc = 32778; // Reasonable Solaris default
|
int vproc = 32778; // Reasonable Solaris default
|
||||||
kc = kstat_open();
|
kc = kstat_open();
|
||||||
if (kc != NULL) { kshandle = kstat_lookup(kc,"unix",0,"var"); }
|
if (kc != NULL) {
|
||||||
if (kshandle != NULL) { kstat_read(kc,kshandle,NULL); }
|
kshandle = kstat_lookup(kc, "unix", 0, "var");
|
||||||
|
}
|
||||||
|
if (kshandle != NULL) {
|
||||||
|
kstat_read(kc, kshandle, NULL);
|
||||||
|
}
|
||||||
ksvar = kshandle->ks_data;
|
ksvar = kshandle->ks_data;
|
||||||
if (ksvar->v_proc > 0 ) {
|
if (ksvar->v_proc > 0 ) {
|
||||||
vproc = ksvar->v_proc;
|
vproc = ksvar->v_proc;
|
||||||
}
|
}
|
||||||
if (kc != NULL) { kstat_close(kc); }
|
if (kc != NULL) {
|
||||||
|
kstat_close(kc);
|
||||||
|
}
|
||||||
return vproc;
|
return vproc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +200,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
percent = v[0] + v[1] + v[2];
|
percent = v[0] + v[1] + v[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
percent = CLAMP(percent, 0.0, 100.0);
|
percent = isnan(percent) ? 0.0 : CLAMP(percent, 0.0, 100.0);
|
||||||
if (isnan(percent)) percent = 0.0;
|
|
||||||
|
|
||||||
v[CPU_METER_FREQUENCY] = NAN;
|
v[CPU_METER_FREQUENCY] = NAN;
|
||||||
|
|
||||||
|
@ -233,10 +238,12 @@ static int Platform_buildenv(void *accum, struct ps_prochandle *Phandle, uintptr
|
||||||
(void) Phandle;
|
(void) Phandle;
|
||||||
(void) addr;
|
(void) addr;
|
||||||
size_t thissz = strlen(str);
|
size_t thissz = strlen(str);
|
||||||
if ((thissz + 2) > (accump->capacity - accump->size))
|
if ((thissz + 2) > (accump->capacity - accump->size)) {
|
||||||
accump->env = xRealloc(accump->env, accump->capacity *= 2);
|
accump->env = xRealloc(accump->env, accump->capacity *= 2);
|
||||||
if ((thissz + 2) > (accump->capacity - accump->size))
|
}
|
||||||
|
if ((thissz + 2) > (accump->capacity - accump->size)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
strlcpy( accump->env + accump->size, str, (accump->capacity - accump->size));
|
strlcpy( accump->env + accump->size, str, (accump->capacity - accump->size));
|
||||||
strncpy( accump->env + accump->size + thissz + 1, "\n", 1);
|
strncpy( accump->env + accump->size + thissz + 1, "\n", 1);
|
||||||
accump->size = accump->size + thissz + 1;
|
accump->size = accump->size + thissz + 1;
|
||||||
|
@ -249,8 +256,9 @@ char* Platform_getProcessEnv(pid_t pid) {
|
||||||
int graberr;
|
int graberr;
|
||||||
struct ps_prochandle* Phandle;
|
struct ps_prochandle* Phandle;
|
||||||
|
|
||||||
if ((Phandle = Pgrab(realpid,PGRAB_RDONLY,&graberr)) == NULL)
|
if ((Phandle = Pgrab(realpid, PGRAB_RDONLY, &graberr)) == NULL) {
|
||||||
return "Unable to read process environment.";
|
return "Unable to read process environment.";
|
||||||
|
}
|
||||||
|
|
||||||
envBuilder.capacity = 4096;
|
envBuilder.capacity = 4096;
|
||||||
envBuilder.size = 0;
|
envBuilder.size = 0;
|
||||||
|
|
|
@ -30,6 +30,7 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) {
|
char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) {
|
||||||
char* zname;
|
char* zname;
|
||||||
|
|
||||||
if ( sproc->zoneid == 0 ) {
|
if ( sproc->zoneid == 0 ) {
|
||||||
zname = xStrdup(GZONE);
|
zname = xStrdup(GZONE);
|
||||||
} else if ( kd == NULL ) {
|
} else if ( kd == NULL ) {
|
||||||
|
@ -38,6 +39,7 @@ char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) {
|
||||||
kstat_t* ks = kstat_lookup( kd, "zones", sproc->zoneid, NULL );
|
kstat_t* ks = kstat_lookup( kd, "zones", sproc->zoneid, NULL );
|
||||||
zname = xStrdup(ks == NULL ? UZONE : ks->ks_name);
|
zname = xStrdup(ks == NULL ? UZONE : ks->ks_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return zname;
|
return zname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +87,12 @@ static inline void SolarisProcessList_scanCPUTime(ProcessList* pl) {
|
||||||
|
|
||||||
// Calculate per-CPU statistics first
|
// Calculate per-CPU statistics first
|
||||||
for (int i = 0; i < cpus; i++) {
|
for (int i = 0; i < cpus; i++) {
|
||||||
if (spl->kd != NULL) { cpuinfo = kstat_lookup(spl->kd,"cpu",i,"sys"); }
|
if (spl->kd != NULL) {
|
||||||
if (cpuinfo != NULL) { kchain = kstat_read(spl->kd,cpuinfo,NULL); }
|
cpuinfo = kstat_lookup(spl->kd, "cpu", i, "sys");
|
||||||
|
}
|
||||||
|
if (cpuinfo != NULL) {
|
||||||
|
kchain = kstat_read(spl->kd, cpuinfo, NULL);
|
||||||
|
}
|
||||||
if (kchain != -1 ) {
|
if (kchain != -1 ) {
|
||||||
idletime = kstat_data_lookup(cpuinfo, "cpu_nsec_idle");
|
idletime = kstat_data_lookup(cpuinfo, "cpu_nsec_idle");
|
||||||
intrtime = kstat_data_lookup(cpuinfo, "cpu_nsec_intr");
|
intrtime = kstat_data_lookup(cpuinfo, "cpu_nsec_intr");
|
||||||
|
@ -154,17 +160,20 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
|
||||||
// Look up the kstat chain just one, it never changes
|
// Look up the kstat chain just one, it never changes
|
||||||
meminfo = kstat_lookup(spl->kd, "unix", 0, "system_pages");
|
meminfo = kstat_lookup(spl->kd, "unix", 0, "system_pages");
|
||||||
}
|
}
|
||||||
if (meminfo != NULL) { ksrphyserr = kstat_read(spl->kd,meminfo,NULL); }
|
if (meminfo != NULL) {
|
||||||
|
ksrphyserr = kstat_read(spl->kd, meminfo, NULL);
|
||||||
|
}
|
||||||
if (ksrphyserr != -1) {
|
if (ksrphyserr != -1) {
|
||||||
totalmem_pgs = kstat_data_lookup(meminfo, "physmem");
|
totalmem_pgs = kstat_data_lookup(meminfo, "physmem");
|
||||||
freemem_pgs = kstat_data_lookup(meminfo, "freemem");
|
freemem_pgs = kstat_data_lookup(meminfo, "freemem");
|
||||||
pages = kstat_data_lookup(meminfo, "pagestotal");
|
pages = kstat_data_lookup(meminfo, "pagestotal");
|
||||||
|
|
||||||
pl->totalMem = totalmem_pgs->value.ui64 * CRT_pageSizeKB;
|
pl->totalMem = totalmem_pgs->value.ui64 * CRT_pageSizeKB;
|
||||||
if (pl->totalMem > freemem_pgs->value.ui64 * CRT_pageSizeKB)
|
if (pl->totalMem > freemem_pgs->value.ui64 * CRT_pageSizeKB) {
|
||||||
pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * CRT_pageSizeKB;
|
pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * CRT_pageSizeKB;
|
||||||
else
|
} else {
|
||||||
pl->usedMem = 0; // This can happen in non-global zone (in theory)
|
pl->usedMem = 0; // This can happen in non-global zone (in theory)
|
||||||
|
}
|
||||||
// Not sure how to implement this on Solaris - suggestions welcome!
|
// Not sure how to implement this on Solaris - suggestions welcome!
|
||||||
pl->cachedMem = 0;
|
pl->cachedMem = 0;
|
||||||
// Not really "buffers" but the best Solaris analogue that I can find to
|
// Not really "buffers" but the best Solaris analogue that I can find to
|
||||||
|
@ -180,8 +189,12 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
|
||||||
|
|
||||||
// Part 2 - swap
|
// Part 2 - swap
|
||||||
nswap = swapctl(SC_GETNSWP, NULL);
|
nswap = swapctl(SC_GETNSWP, NULL);
|
||||||
if (nswap > 0) { sl = xMalloc((nswap * sizeof(swapent_t)) + sizeof(int)); }
|
if (nswap > 0) {
|
||||||
if (sl != NULL) { spathbase = xMalloc( nswap * MAXPATHLEN ); }
|
sl = xMalloc((nswap * sizeof(swapent_t)) + sizeof(int));
|
||||||
|
}
|
||||||
|
if (sl != NULL) {
|
||||||
|
spathbase = xMalloc( nswap * MAXPATHLEN );
|
||||||
|
}
|
||||||
if (spathbase != NULL) {
|
if (spathbase != NULL) {
|
||||||
spath = spathbase;
|
spath = spathbase;
|
||||||
swapdev = sl->swt_ent;
|
swapdev = sl->swt_ent;
|
||||||
|
@ -211,8 +224,12 @@ static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) {
|
||||||
int ksrphyserr = -1;
|
int ksrphyserr = -1;
|
||||||
kstat_named_t *cur_kstat = NULL;
|
kstat_named_t *cur_kstat = NULL;
|
||||||
|
|
||||||
if (spl->kd != NULL) { arcstats = kstat_lookup(spl->kd, "zfs", 0, "arcstats"); }
|
if (spl->kd != NULL) {
|
||||||
if (arcstats != NULL) { ksrphyserr = kstat_read(spl->kd, arcstats, NULL); }
|
arcstats = kstat_lookup(spl->kd, "zfs", 0, "arcstats");
|
||||||
|
}
|
||||||
|
if (arcstats != NULL) {
|
||||||
|
ksrphyserr = kstat_read(spl->kd, arcstats, NULL);
|
||||||
|
}
|
||||||
if (ksrphyserr != -1) {
|
if (ksrphyserr != -1) {
|
||||||
cur_kstat = kstat_data_lookup( arcstats, "size" );
|
cur_kstat = kstat_data_lookup( arcstats, "size" );
|
||||||
spl->zfs.size = cur_kstat->value.ui64 / 1024;
|
spl->zfs.size = cur_kstat->value.ui64 / 1024;
|
||||||
|
@ -252,7 +269,9 @@ void ProcessList_delete(ProcessList* pl) {
|
||||||
SolarisProcessList* spl = (SolarisProcessList*) pl;
|
SolarisProcessList* spl = (SolarisProcessList*) pl;
|
||||||
ProcessList_done(pl);
|
ProcessList_done(pl);
|
||||||
free(spl->cpus);
|
free(spl->cpus);
|
||||||
if (spl->kd) kstat_close(spl->kd);
|
if (spl->kd) {
|
||||||
|
kstat_close(spl->kd);
|
||||||
|
}
|
||||||
free(spl);
|
free(spl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +290,10 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *
|
||||||
SolarisProcessList* spl = (SolarisProcessList*) listptr;
|
SolarisProcessList* spl = (SolarisProcessList*) listptr;
|
||||||
|
|
||||||
id_t lwpid_real = _lwpsinfo->pr_lwpid;
|
id_t lwpid_real = _lwpsinfo->pr_lwpid;
|
||||||
if (lwpid_real > 1023) return 0;
|
if (lwpid_real > 1023) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
pid_t lwpid = (_psinfo->pr_pid * 1024) + lwpid_real;
|
pid_t lwpid = (_psinfo->pr_pid * 1024) + lwpid_real;
|
||||||
bool onMasterLWP = (_lwpsinfo->pr_lwpid == _psinfo->pr_lwp.pr_lwpid);
|
bool onMasterLWP = (_lwpsinfo->pr_lwpid == _psinfo->pr_lwp.pr_lwpid);
|
||||||
if (onMasterLWP) {
|
if (onMasterLWP) {
|
||||||
|
@ -331,9 +353,13 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *
|
||||||
if (sproc->kernel && !pl->settings->hideKernelThreads) {
|
if (sproc->kernel && !pl->settings->hideKernelThreads) {
|
||||||
pl->kernelThreads += proc->nlwp;
|
pl->kernelThreads += proc->nlwp;
|
||||||
pl->totalTasks += proc->nlwp + 1;
|
pl->totalTasks += proc->nlwp + 1;
|
||||||
if (proc->state == 'O') pl->runningTasks++;
|
if (proc->state == 'O') {
|
||||||
|
pl->runningTasks++;
|
||||||
|
}
|
||||||
} else if (!sproc->kernel) {
|
} else if (!sproc->kernel) {
|
||||||
if (proc->state == 'O') pl->runningTasks++;
|
if (proc->state == 'O') {
|
||||||
|
pl->runningTasks++;
|
||||||
|
}
|
||||||
if (pl->settings->hideUserlandThreads) {
|
if (pl->settings->hideUserlandThreads) {
|
||||||
pl->totalTasks++;
|
pl->totalTasks++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -355,8 +381,12 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void *
|
||||||
}
|
}
|
||||||
|
|
||||||
// Top-level process only gets this for the representative LWP
|
// Top-level process only gets this for the representative LWP
|
||||||
if (sproc->kernel && !pl->settings->hideKernelThreads) proc->show = true;
|
if (sproc->kernel && !pl->settings->hideKernelThreads) {
|
||||||
if (!sproc->kernel && !pl->settings->hideUserlandThreads) proc->show = true;
|
proc->show = true;
|
||||||
|
}
|
||||||
|
if (!sproc->kernel && !pl->settings->hideUserlandThreads) {
|
||||||
|
proc->show = true;
|
||||||
|
}
|
||||||
} // Top-level LWP or subordinate LWP
|
} // Top-level LWP or subordinate LWP
|
||||||
|
|
||||||
// Common code pass 2
|
// Common code pass 2
|
||||||
|
@ -383,8 +413,9 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
SolarisProcessList_scanZfsArcstats(super);
|
SolarisProcessList_scanZfsArcstats(super);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
super->kernelThreads = 1;
|
super->kernelThreads = 1;
|
||||||
proc_walk(&SolarisProcessList_walkproc, super, PR_WALK_LWP);
|
proc_walk(&SolarisProcessList_walkproc, super, PR_WALK_LWP);
|
||||||
|
|
|
@ -27,8 +27,9 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate)
|
if (pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool preExisting = true;
|
bool preExisting = true;
|
||||||
Process* proc;
|
Process* proc;
|
||||||
|
|
|
@ -34,7 +34,9 @@ void openzfs_sysctl_init(ZfsArcStats *stats) {
|
||||||
len = sizeof(arcSize);
|
len = sizeof(arcSize);
|
||||||
if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arcSize, &len, NULL, 0) == 0 && arcSize != 0) {
|
if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arcSize, &len, NULL, 0) == 0 && arcSize != 0) {
|
||||||
stats->enabled = 1;
|
stats->enabled = 1;
|
||||||
len = 5; sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len);
|
|
||||||
|
len = 5;
|
||||||
|
sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len);
|
||||||
|
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.c_max", MIB_kstat_zfs_misc_arcstats_c_max, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.c_max", MIB_kstat_zfs_misc_arcstats_c_max, &len);
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.mfu_size", MIB_kstat_zfs_misc_arcstats_mfu_size, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.mfu_size", MIB_kstat_zfs_misc_arcstats_mfu_size, &len);
|
||||||
|
@ -42,6 +44,7 @@ void openzfs_sysctl_init(ZfsArcStats *stats) {
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.anon_size", MIB_kstat_zfs_misc_arcstats_anon_size, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.anon_size", MIB_kstat_zfs_misc_arcstats_anon_size, &len);
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.hdr_size", MIB_kstat_zfs_misc_arcstats_hdr_size, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.hdr_size", MIB_kstat_zfs_misc_arcstats_hdr_size, &len);
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.other_size", MIB_kstat_zfs_misc_arcstats_other_size, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.other_size", MIB_kstat_zfs_misc_arcstats_other_size, &len);
|
||||||
|
|
||||||
if (sysctlnametomib("kstat.zfs.misc.arcstats.compressed_size", MIB_kstat_zfs_misc_arcstats_compressed_size, &len) == 0) {
|
if (sysctlnametomib("kstat.zfs.misc.arcstats.compressed_size", MIB_kstat_zfs_misc_arcstats_compressed_size, &len) == 0) {
|
||||||
stats->isCompressed = 1;
|
stats->isCompressed = 1;
|
||||||
sysctlnametomib("kstat.zfs.misc.arcstats.uncompressed_size", MIB_kstat_zfs_misc_arcstats_uncompressed_size, &len);
|
sysctlnametomib("kstat.zfs.misc.arcstats.uncompressed_size", MIB_kstat_zfs_misc_arcstats_uncompressed_size, &len);
|
||||||
|
|
Loading…
Reference in New Issue