diff options
-rw-r--r-- | libps/spec.c | 246 |
1 files changed, 140 insertions, 106 deletions
diff --git a/libps/spec.c b/libps/spec.c index 49119f29..03389fde 100644 --- a/libps/spec.c +++ b/libps/spec.c @@ -335,46 +335,47 @@ const struct ps_getter ps_zero_fills_getter = /* 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)) + called varies depending on the getter. */ +#define G(getter,type) ((type (*)())((getter)->fn)) + +/* Similar to G, but takes a fmt field and uses its getter. */ +#define FG(field,type) G(field->spec->getter, type) error_t -ps_emit_int (struct proc_stat *ps, - const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_int (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { - return ps_stream_write_int_field (stream, G (getter, int)(ps), width); + return ps_stream_write_int_field (stream, FG (field, int)(ps), field->width); } error_t -ps_emit_nz_int (struct proc_stat *ps, - const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_nz_int (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { - int value = G (getter, int)(ps); + int value = FG (field, int)(ps); if (value) - return ps_stream_write_int_field (stream, value, width); + return ps_stream_write_int_field (stream, value, field->width); else - return ps_stream_write_field (stream, "-", width); + return ps_stream_write_field (stream, "-", field->width); } error_t -ps_emit_priority (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_priority (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { return ps_stream_write_int_field (stream, - MACH_PRIORITY_TO_NICE (G (getter, int)(ps)), - width); + MACH_PRIORITY_TO_NICE (FG (field, int)(ps)), + field->width); } error_t -ps_emit_num_blocks (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_num_blocks (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char buf[20]; - sprintf(buf, "%d", G (getter, int)(ps) / 1024); - return ps_stream_write_field (stream, buf, width); + sprintf(buf, "%d", FG (field, int)(ps) / 1024); + return ps_stream_write_field (stream, buf, field->width); } int @@ -410,11 +411,12 @@ sprint_frac_value (char *buf, } error_t -ps_emit_percent (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_percent (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char buf[20]; - float perc = G (getter, float)(ps) * 100; + int width = field->width; + float perc = FG (field, float)(ps) * 100; if (width == 0) sprintf (buf, "%g", perc); @@ -428,11 +430,11 @@ ps_emit_percent (struct proc_stat *ps, const struct ps_getter *getter, /* prints its value nicely */ error_t -ps_emit_nice_int (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_nice_int (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char buf[20]; - int value = G (getter, int)(ps); + int value = FG (field, int)(ps); char *sfx = " KMG"; int frac = 0; @@ -443,49 +445,55 @@ ps_emit_nice_int (struct proc_stat *ps, const struct ps_getter *getter, sfx++; } - sprintf(buf + sprint_frac_value (buf, value, 1, frac, 3, ABS (width) - 1), + sprintf(buf + + sprint_frac_value (buf, value, 1, frac, 3, ABS (field->width) - 1), "%c", *sfx); - return ps_stream_write_field (stream, buf, width); + return ps_stream_write_field (stream, buf, field->width); } error_t -ps_emit_seconds (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_seconds (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char buf[20]; struct timeval tv; + int width = field->width, prec = field->precision; - G (getter, void)(ps, &tv); + FG (field, void)(ps, &tv); - fmt_seconds (&tv, width != 0, width ? -1 : 0, ABS (width), buf, sizeof (buf)); + fmt_seconds (&tv, !(field->flags & PS_FMT_FIELD_AT_MOD), prec, ABS (width), + buf, sizeof (buf)); return ps_stream_write_field (stream, buf, width); } error_t -ps_emit_minutes (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_minutes (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char buf[20]; struct timeval tv; + int width = field->width; - G (getter, int)(ps, &tv); + FG (field, int)(ps, &tv); - fmt_minutes (&tv, width != 0, ABS (width), buf, sizeof (buf)); + fmt_minutes (&tv, !(field->flags & PS_FMT_FIELD_AT_MOD), ABS (width), + buf, sizeof (buf)); return ps_stream_write_field (stream, buf, width); } error_t -ps_emit_past_time (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_past_time (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { static struct timeval now; - struct timeval tv; char buf[20]; + struct timeval tv; + int width = field->width; - G (getter, int)(ps, &tv); + FG (field, int)(ps, &tv); if (now.tv_sec == 0 && gettimeofday (&now, 0) < 0) return errno; @@ -496,21 +504,22 @@ ps_emit_past_time (struct proc_stat *ps, const struct ps_getter *getter, } error_t -ps_emit_uid (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_uid (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { - int uid = G (getter, int)(ps); + int uid = FG (field, int)(ps); if (uid < 0) - return ps_stream_write_field (stream, "-", width); + return ps_stream_write_field (stream, "-", field->width); else - return ps_stream_write_int_field (stream, uid, width); + return ps_stream_write_int_field (stream, uid, field->width); } error_t -ps_emit_uname (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_uname (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { - struct ps_user *u = G (getter, struct ps_user *)(ps); + int width = field->width; + struct ps_user *u = FG (field, struct ps_user *)(ps); if (u) { struct passwd *pw = ps_user_passwd (u); @@ -523,18 +532,41 @@ ps_emit_uname (struct proc_stat *ps, const struct ps_getter *getter, return ps_stream_write_field (stream, "-", width); } +error_t +ps_emit_user_name (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) +{ + int width = field->width; + struct ps_user *u = FG (field, struct ps_user *)(ps); + if (u) + { + struct passwd *pw = ps_user_passwd (u); + if (pw == NULL) + { + char buf[20]; + sprintf (buf, "(UID %d)", pw->pw_uid); + return ps_stream_write_field (stream, buf, width); + } + else + return ps_stream_write_field (stream, pw->pw_gecos, width); + } + else + return ps_stream_write_field (stream, "-", width); +} + /* prints a string with embedded nuls as spaces */ error_t -ps_emit_string0 (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_args (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char *s0, *p, *q; int s0len; + int width = field->width; int fwidth = ABS (width); char static_buf[200]; char *buf = static_buf; - G (getter, void)(ps, &s0, &s0len); + FG (field, void)(ps, &s0, &s0len); if (s0 == NULL) *buf = '\0'; @@ -570,26 +602,26 @@ ps_emit_string0 (struct proc_stat *ps, const struct ps_getter *getter, } error_t -ps_emit_string (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_string (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char *str; int len; - G (getter, void)(ps, &str, &len); + FG (field, void)(ps, &str, &len); if (str == NULL) str = ""; - return ps_stream_write_trunc_field (stream, str, width); + return ps_stream_write_trunc_field (stream, str, field->width); } error_t -ps_emit_tty_name (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_tty_name (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { const char *name = "-"; - struct ps_tty *tty = G (getter, struct ps_tty *)(ps); + struct ps_tty *tty = FG (field, struct ps_tty *)(ps); if (tty) { @@ -598,7 +630,7 @@ ps_emit_tty_name (struct proc_stat *ps, const struct ps_getter *getter, name = "?"; } - return ps_stream_write_field (stream, name, width); + return ps_stream_write_field (stream, name, field->width); } struct state_shadow @@ -630,11 +662,11 @@ state_shadows[] = { }; error_t -ps_emit_state (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_state (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { char *tags; - int raw_state = G (getter, int)(ps); + int raw_state = FG (field, int)(ps); int state = raw_state; char buf[20], *p = buf; const struct state_shadow *shadow = state_shadows; @@ -654,23 +686,23 @@ ps_emit_state (struct proc_stat *ps, const struct ps_getter *getter, *p = '\0'; - return ps_stream_write_field (stream, buf, width); + return ps_stream_write_field (stream, buf, field->width); } error_t -ps_emit_wait (struct proc_stat *ps, const struct ps_getter *getter, - int width, struct ps_stream *stream) +ps_emit_wait (struct proc_stat *ps, struct ps_fmt_field *field, + struct ps_stream *stream) { int rpc; char *wait; char buf[80]; - G (getter, void)(ps, &wait, &rpc); + FG (field, void)(ps, &wait, &rpc); if (wait == 0) - return ps_stream_write_field (stream, "?", width); + return ps_stream_write_field (stream, "?", field->width); else if (*wait == 0) - return ps_stream_write_field (stream, "-", width); + return ps_stream_write_field (stream, "-", field->width); else if (strcmp (wait, "kernel") == 0) /* A syscall. RPC is actually the syscall number. */ { @@ -681,7 +713,7 @@ ps_emit_wait (struct proc_stat *ps, const struct ps_getter *getter, sprintf (buf, "syscall:%d", -rpc); name = buf; } - return ps_stream_write_trunc_field (stream, name, width); + return ps_stream_write_trunc_field (stream, name, field->width); } else if (rpc) /* An rpc (with msg id RPC); WAIT describes the dest port. */ @@ -719,10 +751,10 @@ ps_emit_wait (struct proc_stat *ps, const struct ps_getter *getter, else snprintf (buf, sizeof buf, "%s:%d", wait, rpc); - return ps_stream_write_trunc_field (stream, buf, width); + return ps_stream_write_trunc_field (stream, buf, field->width); } else - return ps_stream_write_field (stream, wait, width); + return ps_stream_write_field (stream, wait, field->width); } /* ---------------------------------------------------------------- */ /* comparison functions */ @@ -935,6 +967,8 @@ specs_add_alias (struct ps_fmt_specs *specs, /* Copy the rest of the fields from ALIAS, but defaulting to SRC. */ exp->title = alias->title ?: src->title; exp->width = alias->width ?: src->width; + exp->precision = alias->precision >= 0 ? alias->precision : src->precision; + exp->flags = src->flags ^ alias->flags; exp->getter = alias->getter ?: src->getter; exp->output_fn = alias->output_fn ?: src->output_fn; exp->cmp_fn = alias->cmp_fn ?: src->cmp_fn; @@ -995,73 +1029,73 @@ ps_fmt_specs_find (struct ps_fmt_specs *specs, const char *name) static const struct ps_fmt_spec specs[] = { - {"PID", 0, -5, + {"PID", 0, -5, -1, 0, &ps_pid_getter, ps_emit_int, ps_cmp_ints, 0}, - {"TH#", 0, -2, + {"TH", "TH#", -2, -1, 0, &ps_thread_index_getter,ps_emit_int, ps_cmp_ints, 0}, - {"PPID", 0, -5, + {"PPID", 0, -5, -1, 0, &ps_ppid_getter, ps_emit_int, ps_cmp_ints, 0}, - {"UID", 0, -4, + {"UID", 0, -4, -1, PS_FMT_FIELD_KEEP, &ps_owner_uid_getter, ps_emit_uid, ps_cmp_ints, ps_nominal_uid}, - {"User", 0, 8, + {"User", 0, 8, -1, PS_FMT_FIELD_KEEP, &ps_owner_getter, ps_emit_uname, ps_cmp_unames, ps_nominal_user}, - {"NTh", 0, -2, + {"NTh", 0, -2, -1, 0, &ps_num_threads_getter, ps_emit_int, ps_cmp_ints, ps_nominal_nth}, - {"PGrp", 0, -5, + {"PGrp", 0, -5, -1, 0, &ps_pgrp_getter, ps_emit_int, ps_cmp_ints, 0}, - {"Sess", 0, -5, + {"Sess", 0, -5, -1, 0, &ps_session_getter, ps_emit_int, ps_cmp_ints, 0}, - {"LColl", 0, -5, + {"LColl", 0, -5, -1, 0, &ps_login_col_getter, ps_emit_int, ps_cmp_ints, 0}, - {"Args", 0, 0, - &ps_args_getter, ps_emit_string0, ps_cmp_strings,0}, - {"Arg0", 0, 0, + {"Args", 0, 0, -1, 0, + &ps_args_getter, ps_emit_args, ps_cmp_strings,0}, + {"Arg0", 0, 0, -1, 0, &ps_args_getter, ps_emit_string, ps_cmp_strings,0}, - {"Time", 0, -8, + {"Time", 0, -8, -1, 0, &ps_tot_time_getter, ps_emit_seconds, ps_cmp_times, 0}, - {"UTime", 0, -8, + {"UTime", 0, -8, -1, 0, &ps_usr_time_getter, ps_emit_seconds, ps_cmp_times, 0}, - {"STime", 0, -8, + {"STime", 0, -8, -1, 0, &ps_sys_time_getter, ps_emit_seconds, ps_cmp_times, 0}, - {"VSize", 0, -5, + {"VSize", 0, -5, -1, 0, &ps_vsize_getter, ps_emit_nice_int,ps_cmp_ints, 0}, - {"RSize", 0, -5, + {"RSize", 0, -5, -1, 0, &ps_rsize_getter, ps_emit_nice_int,ps_cmp_ints, 0}, - {"Pri", 0, -3, + {"Pri", 0, -3, -1, 0, &ps_cur_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, - {"BPri", 0, -3, + {"BPri", 0, -3, -1, 0, &ps_base_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, - {"MPri", 0, -3, + {"MPri", 0, -3, -1, 0, &ps_max_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, - {"%Mem", 0, -4, + {"Mem", "%Mem", -4, -1, 0, &ps_rmem_frac_getter, ps_emit_percent, ps_cmp_floats, 0}, - {"%CPU", 0, -4, + {"CPU", "%CPU", -4, -1, 0, &ps_cpu_frac_getter, ps_emit_percent, ps_cmp_floats, 0}, - {"State", 0, 4, + {"State", 0, 4, -1, 0, &ps_state_getter, ps_emit_state, 0, 0}, - {"Wait", 0, 10, + {"Wait", 0, 10, -1, 0, &ps_wait_getter, ps_emit_wait, 0, 0}, - {"Sleep", 0, -2, + {"Sleep", 0, -2, -1, 0, &ps_sleep_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"Susp", 0, -2, + {"Susp", 0, -2, -1, 0, &ps_susp_count_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"PSusp", 0, -2, + {"PSusp", 0, -2, -1, 0, &ps_proc_susp_count_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"TSusp", 0, -2, + {"TSusp", 0, -2, -1, 0, &ps_thread_susp_count_getter, ps_emit_int,ps_cmp_ints, ps_nominal_zint}, - {"TTY", 0, -2, + {"TTY", 0, -2, -1, 0, &ps_tty_getter, ps_emit_tty_name,ps_cmp_strings,0}, - {"PgFlts", 0, -5, + {"PgFlts", 0, -5, -1, 0, &ps_page_faults_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"COWFlts", 0, -5, + {"COWFlts", 0, -5, -1, 0, &ps_cow_faults_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"PgIns", 0, -5, + {"PgIns", 0, -5, -1, 0, &ps_pageins_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"MsgIn", 0, -5, + {"MsgIn", 0, -5, -1, 0, &ps_msgs_rcvd_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"MsgOut", 0, -5, + {"MsgOut", 0, -5, -1, 0, &ps_msgs_sent_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, - {"ZFills", 0, -5, + {"ZFills", 0, -5, -1, 0, &ps_zero_fills_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, {0} }; |