OpenBSDProcess.c 6.44 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
htop - OpenBSDProcess.c
(C) 2015 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "Process.h"
#include "ProcessList.h"
#include "OpenBSDProcess.h"
#include "Platform.h"
#include "CRT.h"

#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>

/*{

typedef enum OpenBSDProcessFields {
   // Add platform-specific fields here, with ids >= 100
   LAST_PROCESSFIELD = 100,
} OpenBSDProcessField;

typedef struct OpenBSDProcess_ {
   Process super;
} OpenBSDProcess;

#ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif

#ifndef Process_isUserlandThread
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
#endif

}*/

ProcessClass OpenBSDProcess_class = {
   .super = {
      .extends = Class(Process),
      .display = Process_display,
      .delete = Process_delete,
      .compare = OpenBSDProcess_compare
   },
   .writeField = (Process_WriteField) OpenBSDProcess_writeField,
};

ProcessFieldData Process_fields[] = {
   [0] = {
52
53
54
55
      .name = "",
      .title = NULL,
      .description = NULL,
      .flags = 0, },
56
   [PID] = {
57
58
59
60
      .name = "PID",
      .title = "    PID ",
      .description = "Process/thread ID",
      .flags = 0, },
61
   [COMM] = {
62
63
64
65
      .name = "Command",
      .title = "Command ",
      .description = "Command line",
      .flags = 0, },
66
   [STATE] = {
67
68
69
70
      .name = "STATE",
      .title = "S ",
      .description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)",
      .flags = 0, },
71
   [PPID] = {
72
73
74
75
      .name = "PPID",
      .title = "   PPID ",
      .description = "Parent process ID",
      .flags = 0, },
76
   [PGRP] = {
77
78
79
80
      .name = "PGRP",
      .title = "   PGRP ",
      .description = "Process group ID",
      .flags = 0, },
81
   [SESSION] = {
82
83
84
85
      .name = "SESSION",
      .title = "   SESN ",
      .description = "Process's session ID",
      .flags = 0, },
86
   [TTY_NR] = {
87
      .name = "TTY_NR",
Hisham's avatar
Hisham committed
88
      .title = "    TTY ",
89
90
      .description = "Controlling terminal",
      .flags = 0, },
91
   [TPGID] = {
92
93
94
95
      .name = "TPGID",
      .title = "  TPGID ",
      .description = "Process ID of the fg process group of the controlling terminal",
      .flags = 0, },
96
   [MINFLT] = {
97
98
99
100
      .name = "MINFLT",
      .title = "     MINFLT ",
      .description = "Number of minor faults which have not required loading a memory page from disk",
      .flags = 0, },
101
   [MAJFLT] = {
102
103
104
105
      .name = "MAJFLT",
      .title = "     MAJFLT ",
      .description = "Number of major faults which have required loading a memory page from disk",
      .flags = 0, },
106
   [PRIORITY] = {
107
108
109
110
      .name = "PRIORITY",
      .title = "PRI ",
      .description = "Kernel's internal priority for the process",
      .flags = 0, },
111
   [NICE] = {
112
113
114
115
      .name = "NICE",
      .title = " NI ",
      .description = "Nice value (the higher the value, the more it lets other processes take priority)",
      .flags = 0, },
116
   [STARTTIME] = {
117
118
119
120
      .name = "STARTTIME",
      .title = "START ",
      .description = "Time the process was started",
      .flags = 0, },
121
   [PROCESSOR] = {
122
123
124
125
      .name = "PROCESSOR",
      .title = "CPU ",
      .description = "Id of the CPU the process last executed on",
      .flags = 0, },
126
   [M_SIZE] = {
127
128
129
130
      .name = "M_SIZE",
      .title = " VIRT ",
      .description = "Total program size in virtual memory",
      .flags = 0, },
131
   [M_RESIDENT] = {
132
133
134
135
      .name = "M_RESIDENT",
      .title = "  RES ",
      .description = "Resident set size, size of the text and data sections, plus stack usage",
      .flags = 0, },
136
   [ST_UID] = {
137
138
139
140
      .name = "ST_UID",
      .title = " UID ",
      .description = "User ID of the process owner",
      .flags = 0, },
141
   [PERCENT_CPU] = {
142
143
144
145
      .name = "PERCENT_CPU",
      .title = "CPU% ",
      .description = "Percentage of the CPU time the process used in the last sampling",
      .flags = 0, },
146
   [PERCENT_MEM] = {
147
148
149
150
      .name = "PERCENT_MEM",
      .title = "MEM% ",
      .description = "Percentage of the memory the process is using, based on resident memory size",
      .flags = 0, },
151
   [USER] = {
152
153
154
155
      .name = "USER",
      .title = "USER      ",
      .description = "Username of the process owner (or user ID if name cannot be determined)",
      .flags = 0, },
156
   [TIME] = {
157
158
159
160
      .name = "TIME",
      .title = "  TIME+  ",
      .description = "Total time the process has spent in user and system time",
      .flags = 0, },
161
   [NLWP] = {
162
163
164
165
      .name = "NLWP",
      .title = "NLWP ",
      .description = "Number of threads in the process",
      .flags = 0, },
166
   [TGID] = {
167
168
169
170
      .name = "TGID",
      .title = "   TGID ",
      .description = "Thread group ID (i.e. process ID)",
      .flags = 0, },
171
   [LAST_PROCESSFIELD] = {
172
173
174
175
      .name = "*** report bug! ***",
      .title = NULL,
      .description = NULL,
      .flags = 0, },
176
177
178
179
180
181
182
183
184
185
186
187
188
};

ProcessPidColumn Process_pidColumns[] = {
   { .id = PID, .label = "PID" },
   { .id = PPID, .label = "PPID" },
   { .id = TPGID, .label = "TPGID" },
   { .id = TGID, .label = "TGID" },
   { .id = PGRP, .label = "PGRP" },
   { .id = SESSION, .label = "SESN" },
   { .id = 0, .label = NULL },
};

OpenBSDProcess* OpenBSDProcess_new(Settings* settings) {
Hisham's avatar
Hisham committed
189
   OpenBSDProcess* this = xCalloc(sizeof(OpenBSDProcess), 1);
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
   Object_setClass(this, Class(OpenBSDProcess));
   Process_init(&this->super, settings);
   return this;
}

void Process_delete(Object* cast) {
   OpenBSDProcess* this = (OpenBSDProcess*) cast;
   Process_done((Process*)cast);
   free(this);
}

void OpenBSDProcess_writeField(Process* this, RichString* str, ProcessField field) {
   //OpenBSDProcess* fp = (OpenBSDProcess*) this;
   char buffer[256]; buffer[255] = '\0';
   int attr = CRT_colors[DEFAULT_COLOR];
   //int n = sizeof(buffer) - 1;
   switch (field) {
   // add OpenBSD-specific fields here
   default:
      Process_writeField(this, str, field);
      return;
   }
   RichString_append(str, attr, buffer);
}

long OpenBSDProcess_compare(const void* v1, const void* v2) {
   OpenBSDProcess *p1, *p2;
   Settings *settings = ((Process*)v1)->settings;
   if (settings->direction == 1) {
      p1 = (OpenBSDProcess*)v1;
      p2 = (OpenBSDProcess*)v2;
   } else {
      p2 = (OpenBSDProcess*)v1;
      p1 = (OpenBSDProcess*)v2;
   }
   switch (settings->sortKey) {
   // add OpenBSD-specific fields here
   default:
      return Process_compare(v1, v2);
   }
}

bool Process_isThread(Process* this) {
   return (Process_isKernelThread(this));
}