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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
|
// proc.h emacs, this is written in -*-c++-*-
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegrd, 1997, 1998
#ifndef PROC_H
#define PROC_H
#include <unistd.h>
#include <sys/time.h>
#include <qstring.h>
#include <qwindefs.h>
#include <qintdict.h>
#include "svec.h"
enum fields {
F_PID, F_PPID, F_PGID, F_SID, F_TTY, F_TPGID,
F_USER,
F_PRI, F_NICE,
F_PLCY, F_RPRI,
F_MAJFLT, F_MINFLT, F_TRS, F_DRS, F_SIZE, F_SWAP, F_RSS, F_SHARE, F_DT,
F_STAT,
F_FLAGS,
F_WCHAN,
F_UID,
F_WCPU, F_CPU, F_MEM,
F_START, F_TIME,
F_COMM, F_CMDLINE,
F_END = -1 };
class Details;
class Sockinfo
{
public:
enum proto_t { TCP, UDP };
proto_t proto;
unsigned char st;
unsigned char tr;
unsigned local_addr;
unsigned rem_addr;
unsigned short local_port;
unsigned short rem_port;
unsigned tx_queue;
unsigned rx_queue;
unsigned tm_when;
unsigned rexmits;
int uid;
int timeout;
int inode;
};
class Mapsinfo
{
public:
// members rearranged to minimize padding (should be done in all structs)
unsigned long from, to;
unsigned long offset;
unsigned long inode;
QString filename; // null if Linux 2.0 and name unknown
char perm[4]; // "rwx[ps]"; last is private/shared flag
unsigned char minor, major;
};
class Fileinfo
{
public:
Fileinfo(int descr, QString name) : fd(descr), filename(name) {};
int fd;
QString filename; // "major:minor inode" in Linux 2.0
};
class Procinfo
{
public:
Procinfo(int pid);
~Procinfo();
int readproc(int pid);
static void read_common();
static void read_loadavg();
static int read_file(char *name, char *buf, int max);
bool read_fds();
static bool read_socket_list(Sockinfo::proto_t proto, char *pseudofile);
static void read_sockets();
static void invalidate_sockets();
bool read_maps();
// accessors for lazy evaluation
int get_policy();
int get_rtprio();
int pid;
// from /proc/XX/status
int uid, euid, suid, fsuid;
int gid, egid, sgid, fsgid;
// from /proc/XX/cmdline
QString cmdline;
// from /proc/XX/stat
QString comm;
char state;
int ppid;
int pgrp;
int session;
int tty;
int tpgid;
unsigned long flags;
unsigned long minflt;
unsigned long cminflt;
unsigned long majflt;
unsigned long cmajflt;
long utime;
long stime;
long cutime;
long cstime;
int priority;
int nice;
unsigned long timeout;
unsigned long starttime;
unsigned long rss;
unsigned long wchan;
// from /proc/XX/statm
// (not required to be long but it's more rational)
unsigned long size; // total memory (K)
unsigned long resident; // pages in resident set (non-swapped) (K)
unsigned long share; // shared memory pages (mmaped) (K)
unsigned long trs; // text resident set size (K)
unsigned long lrs; // shared-lib resident set size (K)
unsigned long drs; // data resident set size (K)
unsigned long dt; // dirty pages (number of pages, not K)
// from gettimeofday(2)
struct timeval tv;
// from sched_getscheduler(2)
int policy; // -1 = uninitialized
// from sched_getparam(2)
int rtprio; // 0-99, higher can pre-empt lower (-1 = uninitialized)
// computed %cpu and %mem since last update
float wcpu;
float pcpu;
float pmem;
// from /proc/loadavg
static float loadavg[3];
// from /proc/meminfo (these are in kB)
static int mem_total, mem_free, mem_shared, mem_buffers;
static int mem_cached;
static int swap_total, swap_free;
// from /proc/stat
enum { CPU_USER, CPU_NICE, CPU_SYSTEM, CPU_IDLE };
const int CPUTIMES = CPU_IDLE + 1;
static unsigned cpu_time[CPUTIMES];
static unsigned old_cpu_time[CPUTIMES];
static unsigned boot_time;
// from /proc/uptime
static int uptime; // seconds of uptime
// from /proc/net/{tcp,udp}
static QIntDict<Sockinfo> socks;
static bool socks_current; // true if the socks list is current
// from /proc/XX/fd
Svec<Fileinfo*> *fd_files; // file names or NULL if not read
Svec<int> *sock_inodes; // socket inodes or NULL if not read
Details *details; // details window or NULL (backlink)
// from /proc/XX/maps
Svec<Mapsinfo*> *maps; // maps or NULL if not read
bool selected; // true if selected in current view
bool viewed; // true if part of current process view
const MAX_CMD_LEN = 4096;
static int pagesize;
};
class Category
{
public:
Category(char *heading, char *explain) : name(heading), help(explain) {};
virtual int alignment() = 0;
virtual QString string(Procinfo *p) = 0;
virtual int width() = 0;
virtual int compare(Procinfo *a, Procinfo *b);
virtual int gap() { return 0; };
char *name;
char *help;
int index;
};
class Cat_int : public Category
{
public:
Cat_int(char *heading, char *explain, int w, int Procinfo::*member);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return field_width; };
virtual int compare(Procinfo *a, Procinfo *b);
protected:
int Procinfo::*int_member;
int field_width;
};
class Cat_uintl : public Category
{
public:
Cat_uintl(char *heading, char *explain, int w,
unsigned long Procinfo::*member);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return field_width; };
virtual int compare(Procinfo *a, Procinfo *b);
protected:
unsigned long Procinfo::*uintl_member;
int field_width;
};
class Cat_hex : public Cat_uintl
{
public:
Cat_hex(char *heading, char *explain, int w,
unsigned long Procinfo::*member);
virtual QString string(Procinfo *p);
};
class Cat_swap : public Category
{
public:
Cat_swap(char *heading, char *explain);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return 56; };
virtual int compare(Procinfo *a, Procinfo *b);
};
class Cat_string : public Category
{
public:
Cat_string(char *heading, char *explain, QString Procinfo::*member = 0);
virtual int alignment() { return AlignLeft; };
virtual QString string(Procinfo *p);
virtual int width() { return -1; };
virtual int gap() { return 8; };
protected:
QString Procinfo::*str_member;
};
class Cat_user : public Cat_string
{
public:
Cat_user(char *heading, char *explain);
virtual QString string(Procinfo *p);
};
class Cat_wchan : public Cat_string
{
public:
Cat_wchan(char *heading, char *explain);
virtual QString string(Procinfo *p);
};
class Cat_cmdline : public Cat_string
{
public:
Cat_cmdline(char *heading, char *explain);
virtual QString string(Procinfo *p);
};
class Cat_state : public Category
{
public:
Cat_state(char *heading, char *explain);
virtual int alignment() { return AlignLeft; };
virtual QString string(Procinfo *p);
virtual int width() { return 44; };
virtual int gap() { return 8; };
};
class Cat_policy : public Category
{
public:
Cat_policy(char *heading, char *explain);
virtual int alignment() { return AlignLeft; };
virtual QString string(Procinfo *p);
virtual int width() { return 46; };
virtual int gap() { return 8; };
virtual int compare(Procinfo *a, Procinfo *b);
};
class Cat_rtprio : public Category
{
public:
Cat_rtprio(char *heading, char *explain);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return 36; };
virtual int compare(Procinfo *a, Procinfo *b);
};
class Cat_time : public Category
{
public:
Cat_time(char *heading, char *explain);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return 48; };
virtual int compare(Procinfo *a, Procinfo *b);
};
class Cat_start : public Category
{
public:
Cat_start(char *heading, char *explain);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return 56; };
virtual int compare(Procinfo *a, Procinfo *b);
};
class Cat_percent : public Category
{
public:
Cat_percent(char *heading, char *explain, int w, float Procinfo::*member);
virtual int alignment() { return AlignRight; };
virtual QString string(Procinfo *p);
virtual int width() { return field_width; };
virtual int compare(Procinfo *a, Procinfo *b);
protected:
float Procinfo::*float_member;
int field_width;
};
class Cat_tty : public Category
{
public:
Cat_tty(char *heading, char *explain);
virtual int alignment() { return AlignLeft; };
virtual QString string(Procinfo *p);
virtual int width() { return 36; };
virtual int gap() { return 8; };
};
class Proc
{
public:
Proc();
void refresh();
Svec<Procinfo *> procs;
Svec<Category *> cats;
};
class Procview
{
public:
Procview(Proc *p);
static int compare(Procinfo **a, Procinfo **b);
static int compare_backwards(Procinfo **a, Procinfo **b);
void refresh();
void rebuild();
void set_fields();
void set_fields_list(int fields[]);
void add_cat(Category *c);
void remove_cat(int index);
int findCol(int field);
Svec<Procinfo *> procs;
Svec<Procinfo *> old_procs;
Svec<Category *> cats;
Category *sortcat;
bool reversed; // true if sorted backwards
enum procstates {ALL, OWNED, NROOT, RUNNING} viewproc;
enum fieldstates {USER = RUNNING + 1, JOBS, MEM, CUSTOM} viewfields;
// lists of fields to be used for different views, terminated by -1:
static int user_fields[];
static int jobs_fields[];
static int mem_fields[];
static float avg_factor; // exponential factor for averaging
const int cpu_avg_time = 30 * 1000; // averaging time for WCPU (ms)
private:
static Category *static_sortcat; // kludge: to be used by compare
Proc *proc;
};
#endif // PROC_H
|