summaryrefslogtreecommitdiff
path: root/libps/spec.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-03-13 19:34:44 +0000
committerMiles Bader <miles@gnu.org>1995-03-13 19:34:44 +0000
commitbf919d11aedc8b4c52edbdfe02be9853d485f895 (patch)
treed4e6e7fe03f7f2936f399143fdcb0eea8da9325a /libps/spec.c
parent19afee96c919afc4a71d17f1cef2e04da23de9a1 (diff)
Initial revision
Diffstat (limited to 'libps/spec.c')
-rw-r--r--libps/spec.c756
1 files changed, 756 insertions, 0 deletions
diff --git a/libps/spec.c b/libps/spec.c
new file mode 100644
index 00000000..c3e68f95
--- /dev/null
+++ b/libps/spec.c
@@ -0,0 +1,756 @@
+/* Access, formatting, & comparison routines for printing process info.
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <hurd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pwd.h>
+
+#include "ps.h"
+#include "pshost.h"
+#include "common.h"
+
+/* ---------------------------------------------------------------- */
+/* Getter definitions */
+
+typedef void (*vf)();
+
+static int
+ps_get_pid(proc_stat_t ps)
+{
+ return proc_stat_pid(ps);
+}
+struct ps_getter ps_pid_getter =
+{"pid", PSTAT_PID, (vf) ps_get_pid};
+
+static int
+ps_get_thread_index(proc_stat_t ps)
+{
+ return proc_stat_thread_index(ps);
+}
+struct ps_getter ps_thread_index_getter =
+{"thread_index", PSTAT_THREAD, (vf) ps_get_thread_index};
+
+static int
+ps_get_owner(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->owner;
+}
+struct ps_getter ps_owner_getter =
+{"owner", PSTAT_INFO, (vf) ps_get_owner};
+
+static int
+ps_get_ppid(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->ppid;
+}
+struct ps_getter ps_ppid_getter =
+{"ppid", PSTAT_INFO, (vf) ps_get_ppid};
+
+static int
+ps_get_pgrp(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->pgrp;
+}
+struct ps_getter ps_pgrp_getter =
+{"pgrp", PSTAT_INFO, (vf) ps_get_pgrp};
+
+static int
+ps_get_session(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->session;
+}
+struct ps_getter ps_session_getter =
+{"session", PSTAT_INFO, (vf) ps_get_session};
+
+static int
+ps_get_login_col(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->logincollection;
+}
+struct ps_getter ps_login_col_getter =
+{"login_col", PSTAT_INFO, (vf) ps_get_login_col};
+
+static int
+ps_get_num_threads(proc_stat_t ps)
+{
+ return proc_stat_num_threads(ps);
+}
+struct ps_getter ps_num_threads_getter =
+{"num_threads", PSTAT_NUM_THREADS, (vf)ps_get_num_threads};
+
+static void
+ps_get_args(proc_stat_t ps, char **args_p, int *args_len_p)
+{
+ *args_p = proc_stat_args(ps);
+ *args_len_p = proc_stat_args_len(ps);
+}
+struct ps_getter ps_args_getter =
+{"args", PSTAT_ARGS, ps_get_args};
+
+static int
+ps_get_state(proc_stat_t ps)
+{
+ return proc_stat_state(ps);
+}
+struct ps_getter ps_state_getter =
+{"state", PSTAT_STATE, (vf) ps_get_state};
+
+static int
+ps_get_vsize(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->taskinfo.virtual_size;
+}
+struct ps_getter ps_vsize_getter =
+{"vsize", PSTAT_INFO, (vf) ps_get_vsize};
+
+static int
+ps_get_rsize(proc_stat_t ps)
+{
+ return proc_stat_info(ps)->taskinfo.resident_size;
+}
+struct ps_getter ps_rsize_getter =
+{"rsize", PSTAT_INFO, (vf) ps_get_rsize};
+
+static int
+ps_get_cur_priority(proc_stat_t ps)
+{
+ return proc_stat_thread_sched_info(ps)->cur_priority;
+}
+struct ps_getter ps_cur_priority_getter =
+{"cur_priority", PSTAT_THREAD_INFO, (vf) ps_get_cur_priority};
+
+static int
+ps_get_base_priority(proc_stat_t ps)
+{
+ return proc_stat_thread_sched_info(ps)->base_priority;
+}
+struct ps_getter ps_base_priority_getter =
+{"base_priority", PSTAT_THREAD_INFO, (vf) ps_get_base_priority};
+
+static int
+ps_get_max_priority(proc_stat_t ps)
+{
+ return proc_stat_thread_sched_info(ps)->max_priority;
+}
+struct ps_getter ps_max_priority_getter =
+{"max_priority", PSTAT_THREAD_INFO, (vf) ps_get_max_priority};
+
+static void
+ps_get_usr_time(proc_stat_t ps, time_value_t * tv_out)
+{
+ *tv_out = proc_stat_thread_basic_info(ps)->user_time;
+}
+struct ps_getter ps_usr_time_getter =
+{"usr_time", PSTAT_THREAD_INFO, ps_get_usr_time};
+
+static void
+ps_get_sys_time(proc_stat_t ps, time_value_t * tv_out)
+{
+ *tv_out = proc_stat_thread_basic_info(ps)->system_time;
+}
+struct ps_getter ps_sys_time_getter =
+{"sys_time", PSTAT_THREAD_INFO, ps_get_sys_time};
+
+static void
+ps_get_tot_time(proc_stat_t ps, time_value_t * tv_out)
+{
+ *tv_out = proc_stat_thread_basic_info(ps)->user_time;
+ time_value_add(tv_out, &proc_stat_thread_basic_info(ps)->system_time);
+}
+struct ps_getter ps_tot_time_getter =
+{"tot_time", PSTAT_THREAD_INFO, ps_get_tot_time};
+
+static float
+ps_get_rmem_frac(proc_stat_t ps)
+{
+ static int mem_size = 0;
+
+ if (mem_size == 0)
+ {
+ host_basic_info_t info;
+ error_t err = ps_host_basic_info(&info);
+ if (err == 0)
+ mem_size = info->memory_size;
+ }
+
+ if (mem_size > 0)
+ return (float)proc_stat_info(ps)->taskinfo.resident_size / (float)mem_size;
+ else
+ return 0.0;
+}
+struct ps_getter ps_rmem_frac_getter =
+{"rmem_frac", PSTAT_INFO, (vf) ps_get_rmem_frac};
+
+static float
+ps_get_cpu_frac(proc_stat_t ps)
+{
+ return (float) proc_stat_thread_basic_info(ps)->cpu_usage
+ / (float) TH_USAGE_SCALE;
+}
+struct ps_getter ps_cpu_frac_getter =
+{"cpu_frac", PSTAT_THREAD_INFO, (vf) ps_get_cpu_frac};
+
+static int
+ps_get_sleep(proc_stat_t ps)
+{
+ return proc_stat_thread_basic_info(ps)->sleep_time;
+}
+struct ps_getter ps_sleep_getter =
+{"sleep", PSTAT_THREAD_INFO, (vf) ps_get_sleep};
+
+static void
+ps_get_tty_name(proc_stat_t ps, char **str_p, int *len_p)
+{
+ *str_p = proc_stat_tty_name(ps);
+ if (*str_p != NULL)
+ *len_p = strlen(*str_p) + 1;
+}
+struct ps_getter ps_tty_name_getter =
+{"tty_name", PSTAT_TTY_NAME, ps_get_tty_name};
+
+static int
+ps_get_page_faults(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->faults;
+}
+struct ps_getter ps_page_faults_getter =
+{"page_faults", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_page_faults};
+
+static int
+ps_get_cow_faults(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->cow_faults;
+}
+struct ps_getter ps_cow_faults_getter =
+{"cow_faults", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_cow_faults};
+
+static int
+ps_get_pageins(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->pageins;
+}
+struct ps_getter ps_pageins_getter =
+{"pageins", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_pageins};
+
+static int
+ps_get_msgs_sent(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->messages_sent;
+}
+struct ps_getter ps_msgs_sent_getter =
+{"msgs_sent", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_msgs_sent};
+
+static int
+ps_get_msgs_rcvd(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->messages_received;
+}
+struct ps_getter ps_msgs_rcvd_getter =
+{"msgs_rcvd", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_msgs_rcvd};
+
+static int
+ps_get_zero_fills(proc_stat_t ps)
+{
+ return proc_stat_task_events_info(ps)->zero_fills;
+}
+struct ps_getter ps_zero_fills_getter =
+{"zero_fills", PSTAT_TASK_EVENTS_INFO, (vf) ps_get_zero_fills};
+
+/* ---------------------------------------------------------------- */
+/* some printing functions */
+
+/* G() is a helpful macro that just returns the getter G's access function
+ cast into a function pointer returning TYPE, as how the function should be
+ called varies depending on the getter */
+#define G(g,type)((type (*)())ps_getter_function(g))
+
+error_t
+ps_emit_int(proc_stat_t ps, ps_getter_t getter, int width, FILE *stream, int *count)
+{
+ return ps_write_int_field(G(getter, int)(ps), width, stream, count);
+}
+
+error_t
+ps_emit_num_blocks(proc_stat_t ps, ps_getter_t getter, int width, FILE
+ *stream, int *count)
+{
+ char buf[20];
+ sprintf(buf, "%ld", G(getter, int)(ps) / 1024);
+ return ps_write_field(buf, width, stream, count);
+}
+
+int
+sprint_frac_value(char *buf,
+ int value, int min_value_len,
+ int frac, int frac_scale,
+ int width)
+{
+ int value_len;
+ int frac_len;
+
+ if (value >= 100) /* the integer part */
+ value_len = 3;
+ else if (value >= 10)
+ value_len = 2;
+ else
+ value_len = 1;
+
+ while (value_len < min_value_len--)
+ *buf++ = '0';
+
+ for (frac_len = frac_scale
+ ; frac_len > 0 && (width < value_len + 1 + frac_len || frac % 10 == 0)
+ ; frac_len--)
+ frac /= 10;
+
+ if (frac_len > 0)
+ sprintf(buf, "%ld.%0*ld", value, frac_len, frac);
+ else
+ sprintf(buf, "%ld", value);
+
+ return strlen(buf);
+}
+
+error_t
+ps_emit_percent(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char buf[20];
+ float perc = G(getter, float)(ps) * 100;
+
+ if (width == 0)
+ sprintf(buf, "%g", perc);
+ else if (ABS(width) > 3)
+ sprintf(buf, "%.*f", ABS(width) - 3, perc);
+ else
+ sprintf(buf, "%d", (int) perc);
+
+ return ps_write_field(buf, width, stream, count);
+}
+
+/* prints its value nicely */
+error_t
+ps_emit_nice_int(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char buf[20];
+ int value = G(getter, int)(ps);
+ char *sfx = " KMG";
+ int frac = 0;
+
+ while (value >= 1024)
+ {
+ frac = ((value & 0x3FF) * 1000) >> 10;
+ value >>= 10;
+ sfx++;
+ }
+
+ sprintf(buf + sprint_frac_value(buf, value, 1, frac, 3, ABS(width) - 1),
+ "%c", *sfx);
+
+ return ps_write_field(buf, width, stream, count);
+}
+
+#define MINUTE 60
+#define HOUR (60*MINUTE)
+#define DAY (24*HOUR)
+#define WEEK (7*DAY)
+
+static int
+sprint_long_time(char *buf, int seconds, int width)
+{
+ char *p = buf;
+ struct tscale
+ {
+ int length;
+ char *sfx;
+ char *short_sfx;
+ }
+ time_scales[] =
+ {
+ { WEEK, " week", "wk"} ,
+ { DAY, " day", "dy"} ,
+ { HOUR, " hour", "hr"} ,
+ { MINUTE," min", "m"} ,
+ { 0}
+ };
+ struct tscale *ts = time_scales;
+
+ while (ts->length > 0 && width > 0)
+ {
+ if (ts->length < seconds)
+ {
+ int len;
+ int num = seconds / ts->length;
+ seconds %= ts->length;
+ sprintf(p, "%d%s", num, ts->sfx);
+ len = strlen(p);
+ width -= len;
+ if (width < 0 && p > buf)
+ break;
+ p += len;
+ }
+ ts++;
+ }
+
+ *p = '\0';
+
+ return p - buf;
+}
+
+error_t
+ps_emit_nice_seconds(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char buf[20];
+ time_value_t tv;
+
+ G(getter, int)(ps, &tv);
+
+ if (tv.seconds == 0)
+ {
+ if (tv.microseconds < 500)
+ sprintf(buf, "%dus", tv.microseconds);
+ else
+ strcpy(buf
+ + sprint_frac_value(buf,
+ tv.microseconds / 1000, 1,
+ tv.microseconds % 1000, 3,
+ ABS(width) - 2),
+ "ms");
+ }
+ else if (tv.seconds < MINUTE)
+ sprint_frac_value(buf, tv.seconds, 1, tv.microseconds, 6, ABS(width));
+ else if (tv.seconds < HOUR)
+ {
+ /* 0:00.00... */
+ int min_len;
+ sprintf(buf, "%d:", tv.seconds / 60);
+ min_len = strlen(buf);
+ sprint_frac_value(buf + min_len,
+ tv.seconds % 60, 2,
+ tv.microseconds, 6,
+ ABS(width) - min_len);
+ }
+ else
+ sprint_long_time(buf, tv.seconds, width);
+
+ return ps_write_field(buf, width, stream, count);
+}
+
+static int
+append_fraction(char *buf, int frac, int digits, int width)
+{
+ int slen = strlen(buf);
+ int left = width - strlen(buf);
+ if (left > 1)
+ {
+ buf[slen] = '.';
+ left--;
+ while (digits > left)
+ frac /= 10, digits--;
+ sprintf(buf + slen + 1, "%0*d", digits, frac);
+ return slen + 1 + digits;
+ }
+ else
+ return slen;
+}
+
+error_t
+ps_emit_seconds(proc_stat_t ps, ps_getter_t getter, int width, FILE *stream,
+ int *count)
+{
+ int max = (width == 0 ? 999 : ABS(width));
+ char buf[20];
+ time_value_t tv;
+
+ G(getter, void)(ps, &tv);
+
+ if (tv.seconds > DAY)
+ sprint_long_time(buf, tv.seconds, max);
+ else if (tv.seconds > HOUR)
+ if (max >= 8)
+ {
+ /* 0:00:00.00... */
+ sprintf(buf, "%2d:%02d:%02d",
+ tv.seconds / HOUR,
+ (tv.seconds % HOUR) / MINUTE, (tv.seconds % MINUTE));
+ append_fraction(buf, tv.microseconds, 6, max);
+ }
+ else
+ sprint_long_time(buf, tv.seconds, max);
+ else if (max >= 5 || tv.seconds > MINUTE)
+ {
+ /* 0:00.00... */
+ sprintf(buf, "%2d:%02d", tv.seconds / MINUTE, tv.seconds % MINUTE);
+ append_fraction(buf, tv.microseconds, 6, max);
+ }
+ else
+ sprint_frac_value(buf, tv.seconds, 1, tv.microseconds, 6, max);
+
+ return ps_write_field(buf, width, stream, count);
+}
+
+error_t
+ps_emit_user(proc_stat_t ps, ps_getter_t getter, int width, FILE *stream, int *count)
+{
+ int uid = G(getter, int)(ps);
+ if (uid < 0)
+ return ps_write_padding(0, width, stream, count);
+ else
+ {
+ struct passwd *pw = getpwuid(uid);
+ if (pw == NULL)
+ return ps_write_int_field(uid, width, stream, count);
+ else
+ return ps_write_field(pw->pw_name, width, stream, count);
+ }
+}
+
+/* prints a string with embedded nuls as spaces */
+error_t
+ps_emit_string0(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char *s0, *p, *q;
+ int s0len;
+ int fwidth = ABS(width);
+ char static_buf[200];
+ char *buf = static_buf;
+
+ G(getter, void)(ps, &s0, &s0len);
+
+ if (s0 == NULL)
+ *buf = '\0';
+ else
+ {
+ if (s0len > sizeof static_buf)
+ {
+ buf = malloc(s0len + 1);
+ if (buf == NULL)
+ return ENOMEM;
+ }
+
+ if (fwidth == 0 || fwidth > s0len)
+ fwidth = s0len;
+
+ for (p = buf, q = s0; fwidth-- > 0; p++, q++)
+ {
+ int ch = *q;
+ *p = (ch == '\0' ? ' ' : ch);
+ }
+ if (q > s0 && *(q - 1) == '\0')
+ *--p = '\0';
+ else
+ *p = '\0';
+ }
+
+ {
+ error_t err = ps_write_field(buf, width, stream, count);
+ if (buf != static_buf)
+ free(buf);
+ return err;
+ }
+}
+
+error_t
+ps_emit_string(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char *str;
+ int len;
+
+ G(getter, void)(ps, &str, &len);
+
+ if (str == NULL)
+ str = "";
+ else if (width != 0 && len > ABS(width))
+ str[ABS(width)] = '\0';
+
+ return ps_write_field(str, width, stream, count);
+}
+
+error_t
+ps_emit_tty_name(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ struct tty_abbrev
+ {
+ char *pfx, *subst;
+ }
+ abbrevs[] =
+ {
+ { "/tmp/console", "oc" }, /* temp hack */
+ { "/dev/console", "co"},
+ { "/dev/tty", ""},
+ { "/dev/pty", ""},
+ { "/dev/", ""},
+ { 0 }
+ };
+ char buf[20];
+ char *str;
+ int len;
+
+ G(getter, void)(ps, &str, &len);
+
+ if (str == NULL || len == 0)
+ str = "-";
+ else
+ {
+ struct tty_abbrev *abbrev = abbrevs;
+ while (abbrev->pfx != NULL)
+ {
+ int pfx_len = strlen(abbrev->pfx);
+ if (strncmp(str, abbrev->pfx, pfx_len) == 0)
+ {
+ strcpy(buf, abbrev->subst);
+ strcat(buf, str + pfx_len);
+ str = buf;
+ break;
+ }
+ else
+ abbrev++;
+ }
+ }
+
+ return ps_write_field(str, width, stream, count);
+}
+
+error_t
+ps_emit_state(proc_stat_t ps, ps_getter_t getter,
+ int width, FILE *stream, int *count)
+{
+ char *tags;
+ int state = G(getter, int)(ps);
+ char buf[20], *p = buf;
+
+ /* turn off seemingly bogus or annoying flags */
+ state &= ~PSTAT_STATE_SWAPPED;
+
+ /* If any thread is running, don't mention sleeping or idle threads --
+ presumably *some* work is getting done... */
+ if (state & PSTAT_STATE_RUNNING)
+ state &= ~(PSTAT_STATE_SLEEPING | PSTAT_STATE_IDLE);
+ if (state & PSTAT_STATE_IDLE)
+ state &= ~PSTAT_STATE_SLEEPING;
+
+ for (tags = proc_stat_state_tags
+ ; state != 0 && *tags != '\0'
+ ; state >>= 1, tags++)
+ if (state & 1)
+ *p++ = *tags;
+
+ *p = '\0';
+
+ return ps_write_field(buf, width, stream, count);
+}
+
+/* ---------------------------------------------------------------- */
+/* comparison functions */
+
+int
+ps_cmp_ints(proc_stat_t ps1, proc_stat_t ps2, ps_getter_t getter)
+{
+ int (*gf)() = G(getter, int);
+ int v1 = gf(ps1), v2 = gf(ps2);
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : 1;
+}
+
+int
+ps_cmp_floats(proc_stat_t ps1, proc_stat_t ps2, ps_getter_t getter)
+{
+ float (*gf)() = G(getter, float);
+ float v1 = gf(ps1), v2 = gf(ps2);
+ return v1 == v2 ? 0 : v1 < v2 ? -1 : 1;
+}
+
+int
+ps_cmp_strings(proc_stat_t ps1, proc_stat_t ps2, ps_getter_t getter)
+{
+ void (*gf)() = G(getter, void);
+ char *s1, *s2;
+ int s1len, s2len;
+
+ /* Get both strings */
+ gf(ps1, &s1, &s1len);
+ gf(ps2, &s2, &s2len);
+
+ if (s1 == NULL)
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ else
+ if (s2 == NULL)
+ return 1;
+ else
+ return strncmp(s1, s2, MIN(s1len, s2len));
+}
+
+/* ---------------------------------------------------------------- */
+
+ps_fmt_spec_t
+find_ps_fmt_spec(char *name, ps_fmt_spec_t specs)
+{
+ while (!ps_fmt_spec_is_end(specs))
+ if (strcasecmp(ps_fmt_spec_name(specs), name) == 0)
+ return specs;
+ else
+ specs++;
+ return NULL;
+}
+
+/* ---------------------------------------------------------------- */
+
+struct ps_fmt_spec ps_std_fmt_specs[] =
+{
+ {"PID", &ps_pid_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"TH#", &ps_thread_index_getter,ps_emit_int, ps_cmp_ints, -2},
+ {"PPID", &ps_ppid_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"UID", &ps_owner_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"NTh", &ps_num_threads_getter, ps_emit_int, ps_cmp_ints, -2},
+ {"PGrp", &ps_pgrp_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"User", &ps_owner_getter, ps_emit_user, ps_cmp_ints, 6},
+ {"Sess", &ps_session_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"LColl", &ps_login_col_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"Args", &ps_args_getter, ps_emit_string0, ps_cmp_strings, 0},
+ {"Time", &ps_tot_time_getter, ps_emit_seconds, ps_cmp_ints, -8},
+ {"UTime", &ps_usr_time_getter, ps_emit_seconds, ps_cmp_ints, -8},
+ {"STime", &ps_sys_time_getter, ps_emit_seconds, ps_cmp_ints, -8},
+ {"VSize", &ps_vsize_getter, ps_emit_nice_int, ps_cmp_ints, -5},
+ {"RSize", &ps_rsize_getter, ps_emit_nice_int, ps_cmp_ints, -5},
+ {"Pri", &ps_cur_priority_getter,ps_emit_int, ps_cmp_ints, -2},
+ {"BPri", &ps_base_priority_getter,ps_emit_int, ps_cmp_ints, -2},
+ {"MPri", &ps_max_priority_getter,ps_emit_int, ps_cmp_ints, -2},
+ {"%Mem", &ps_rmem_frac_getter, ps_emit_percent, ps_cmp_floats, -4},
+ {"%CPU", &ps_cpu_frac_getter, ps_emit_percent, ps_cmp_floats, -4},
+ {"State", &ps_state_getter, ps_emit_state, NULL, 4},
+ {"Sleep", &ps_sleep_getter, ps_emit_int, ps_cmp_ints, -2},
+ {"TTY", &ps_tty_name_getter, ps_emit_tty_name, ps_cmp_strings, 2},
+ {"PgFlts", &ps_page_faults_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"COWFlts",&ps_cow_faults_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"PgIns", &ps_pageins_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"MsgsIn", &ps_msgs_rcvd_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"MsgsOut",&ps_msgs_sent_getter, ps_emit_int, ps_cmp_ints, -5},
+ {"ZFills", &ps_zero_fills_getter, ps_emit_int, ps_cmp_ints, -5},
+ {0}
+};