summaryrefslogtreecommitdiff
path: root/utils/ps.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-12-21 16:19:51 +0000
committerMiles Bader <miles@gnu.org>1995-12-21 16:19:51 +0000
commitbbc71f855b1cd4c4bd5bcfd27e884151fd08847e (patch)
tree25e982abc1b9c6a3852e14d7a9f4bc3e5b3f28d5 /utils/ps.c
parent2989af176ce5eb0be198ebfe06f45c46af5b62af (diff)
(main, options): If the specified sort field begins with `-', reverse the sort.
(main): If there is no current uid, don't try to filter with it. (FILTER_NOT_LEADER): Renamed from FILTER_NSESSLDR. (main): Rename ps_not_leader_filter from ps_not_sess_leader_filter. (main): Use idvec routines instead of ids. Use argz functions to store tty_names instead of our own. (make_ids, ids_add, ids_contains): Routines deleted. Include <idvec.h>.
Diffstat (limited to 'utils/ps.c')
-rw-r--r--utils/ps.c196
1 files changed, 75 insertions, 121 deletions
diff --git a/utils/ps.c b/utils/ps.c
index a5366a33..845bd0bb 100644
--- a/utils/ps.c
+++ b/utils/ps.c
@@ -24,9 +24,11 @@
#include <assert.h>
#include <string.h>
#include <ctype.h>
+#include <unistd.h>
#include <argp.h>
+#include <argz.h>
+#include <idvec.h>
#include <hurd/ps.h>
-#include <unistd.h>
#include "error.h"
#include "common.h"
@@ -54,7 +56,7 @@ static struct argp_option options[] =
" leaders"},
{"all", 'e', 0, 0, "List all processes"},
{0, 'f', 0, 0, "Use the `full' output-format"},
- {0, 'g', 0, 0, "Include session leaders"},
+ {0, 'g', 0, 0, "Include session and login leaders"},
{"no-header", 'H', 0, 0, "Don't print a descriptive header line"},
{0, 'j', 0, 0, "Use the `jobc' output-format"},
{0, 'l', 0, 0, "Use the `long' output-format"},
@@ -80,7 +82,8 @@ static struct argp_option options[] =
" (which defaults to the sid of the"
" current process)"},
{"sid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
- {"sort", OPT_SORT,"FIELD", 0, "Sort the output with respect to FIELD"},
+ {"sort", OPT_SORT,"FIELD", 0, "Sort the output with respect to FIELD,"
+ " backwards if FIELD is prefixed by `-'"},
{"threads", 's', 0, 0, "Show the threads for each process"},
{"tty", 't', "TTY", OA, "Only show processes with controlling"
" terminal TTY"},
@@ -126,7 +129,7 @@ parse_enum(char *arg, char **choices, char *kind, bool allow_mismatches)
}
#define FILTER_OWNER 0x01
-#define FILTER_NSESSLDR 0x02
+#define FILTER_NOT_LEADER 0x02
#define FILTER_CTTY 0x04
#define FILTER_UNORPHANED 0x08
#define FILTER_PARENTED 0x10
@@ -306,51 +309,6 @@ lookup_user(char *name)
/* ---------------------------------------------------------------- */
-typedef unsigned id_t;
-
-struct ids
-{
- id_t *ids;
- unsigned num, alloced;
-};
-
-struct
-ids *make_ids ()
-{
- struct ids *ids = malloc (sizeof (struct ids));
- if (!ids)
- error(8, ENOMEM, "Can't allocate id list");
- ids->ids = 0;
- ids->num = ids->alloced = 0;
- return ids;
-}
-
-void
-ids_add (struct ids *ids, id_t id)
-{
- if (ids->alloced == ids->num)
- {
- ids->alloced = ids->alloced * 2 + 1;
- ids->ids = realloc (ids->ids, ids->alloced * sizeof (id_t));
- if (ids->ids == NULL)
- error(8, ENOMEM, "Can't allocate id list");
- }
-
- ids->ids[ids->num++] = id;
-}
-
-int
-ids_contains (struct ids *ids, id_t id)
-{
- unsigned i;
- for (i = 0; i < ids->num; i++)
- if (ids->ids[i] == id)
- return 1;
- return 0;
-}
-
-/* ---------------------------------------------------------------- */
-
void
main(int argc, char *argv[])
{
@@ -360,16 +318,16 @@ main(int argc, char *argv[])
realloced for each successive arg that needs it, on the assumption that
args don't get parsed multiple times. */
char *arg_hack_buf = 0;
- struct ids *only_uids = make_ids (), *not_uids = make_ids ();
- char **tty_names = 0;
- unsigned num_tty_names = 0, tty_names_alloced = 0;
+ struct idvec *only_uids = make_idvec (), *not_uids = make_idvec ();
+ char *tty_names = 0;
+ unsigned num_tty_names = 0;
proc_stat_list_t procset;
ps_context_t context;
ps_stream_t output;
ps_fmt_t fmt;
char *fmt_string = "default", *sort_key_name = NULL;
unsigned filter_mask =
- FILTER_OWNER | FILTER_NSESSLDR | FILTER_UNORPHANED | FILTER_PARENTED;
+ FILTER_OWNER | FILTER_NOT_LEADER | FILTER_UNORPHANED | FILTER_PARENTED;
bool sort_reverse = FALSE, print_heading = TRUE;
bool squash_bogus_fields = TRUE, squash_nominal_fields = TRUE;
bool show_threads = FALSE, no_msg_port = FALSE;
@@ -411,23 +369,27 @@ main(int argc, char *argv[])
}
/* Add a user who's processes should be printed out. */
- void add_uid (id_t uid)
+ void add_uid (uid_t uid)
{
- ids_add (only_uids, uid);
+ error_t err = idvec_add (only_uids, uid);
+ if (err)
+ error (23, err, "Couldn't add uid");
}
/* Add a user who's processes should not be printed out. */
- void add_not_uid (id_t uid)
+ void add_not_uid (uid_t uid)
{
- ids_add (not_uids, uid);
+ error_t err = idvec_add (not_uids, uid);
+ if (err)
+ error (23, err, "Couldn't add uid");
}
/* Returns TRUE if PS is owned by any of the users in ONLY_UIDS, and none
in NOT_UIDS. */
bool proc_stat_owner_ok(struct proc_stat *ps)
{
- id_t uid = proc_stat_proc_info (ps)->owner;
- if (only_uids->num > 0 && !ids_contains (only_uids, uid))
+ int uid = proc_stat_owner_uid (ps);
+ if (only_uids->num > 0 && !idvec_contains (only_uids, uid))
return 0;
- if (not_uids->num > 0 && ids_contains (not_uids, uid))
+ if (not_uids->num > 0 && idvec_contains (not_uids, uid))
return 0;
return 1;
}
@@ -436,14 +398,9 @@ main(int argc, char *argv[])
terminals will be printed. */
void add_tty_name (char *tty_name)
{
- if (tty_names_alloced == num_tty_names)
- {
- tty_names_alloced += tty_names_alloced + 1;
- tty_names = realloc(tty_names, tty_names_alloced * sizeof(int));
- if (tty_names == NULL)
- error(8, ENOMEM, "Can't allocate tty_name list");
- }
- tty_names[num_tty_names++] = tty_name;
+ error_t err = argz_add (&tty_names, &num_tty_names, tty_name);
+ if (err)
+ error (8, err, "%s: Can't add tty", tty_name);
}
bool proc_stat_has_ctty(struct proc_stat *ps)
{
@@ -453,13 +410,13 @@ main(int argc, char *argv[])
ps_tty_t tty = proc_stat_tty(ps);
if (tty)
{
- unsigned i;
+ char *try = 0;
char *name = ps_tty_name(tty);
char *short_name = ps_tty_short_name(tty);
- for (i = 0; i < num_tty_names; i++)
- if ((name && strcmp (tty_names[i], name) == 0)
- || (short_name && strcmp (tty_names[i], short_name) == 0))
+ while (try = argz_next (tty_names, num_tty_names, try))
+ if ((name && strcmp (try, name) == 0)
+ || (short_name && strcmp (try, short_name) == 0))
return TRUE;
}
}
@@ -504,44 +461,29 @@ main(int argc, char *argv[])
parse_numlist(arg, add_pid, NULL, NULL, "PID");
break;
- case 'a':
- filter_mask &= ~(FILTER_OWNER | FILTER_NSESSLDR); break;
- case 'd':
- filter_mask &= ~(FILTER_OWNER | FILTER_UNORPHANED); break;
- case 'e':
- filter_mask = 0; break;
- case 'g':
- filter_mask &= ~FILTER_NSESSLDR; break;
- case 'x':
- filter_mask &= ~FILTER_UNORPHANED; break;
- case 'P':
- filter_mask &= ~FILTER_PARENTED; break;
- case 'f':
- fmt_string = "full"; break;
- case 'u':
- fmt_string = "user"; break;
- case 'v':
- fmt_string = "vmem"; break;
- case 'j':
- fmt_string = "jobc"; break;
- case 'l':
- fmt_string = "long"; break;
- case 'M':
- no_msg_port = TRUE; break;
- case 'H':
- print_heading = FALSE; break;
- case 'Q':
- squash_bogus_fields = squash_nominal_fields = FALSE; break;
- case 'n':
- squash_nominal_fields = FALSE; break;
- case 's':
- show_threads = TRUE; break;
- case OPT_FMT:
- fmt_string = arg; break;
- case OPT_SORT:
- sort_key_name = arg; break;
- case 'r':
- sort_reverse = TRUE; break;
+ case 'a': filter_mask &= ~(FILTER_OWNER | FILTER_NOT_LEADER); break;
+ case 'd': filter_mask &= ~(FILTER_OWNER | FILTER_UNORPHANED); break;
+ case 'e': filter_mask = 0; break;
+ case 'g': filter_mask &= ~FILTER_NOT_LEADER; break;
+ case 'x': filter_mask &= ~FILTER_UNORPHANED; break;
+ case 'P': filter_mask &= ~FILTER_PARENTED; break;
+ case 'f': fmt_string = "full"; break;
+ case 'u': fmt_string = "user"; break;
+ case 'v': fmt_string = "vmem"; break;
+ case 'j': fmt_string = "jobc"; break;
+ case 'l': fmt_string = "long"; break;
+ case 'M': no_msg_port = TRUE; break;
+ case 'H': print_heading = FALSE; break;
+ case 'Q': squash_bogus_fields = squash_nominal_fields = FALSE; break;
+ case 'n': squash_nominal_fields = FALSE; break;
+ case 's': show_threads = TRUE; break;
+ case OPT_FMT: fmt_string = arg; break;
+ case OPT_SORT: sort_key_name = arg; break;
+ case 'r': sort_reverse = TRUE; break;
+
+ case 'w':
+ output_width = arg ? atoi (arg) : 0; /* 0 means `unlimited'. */
+ break;
case 't':
parse_strlist(arg, add_tty_name, current_tty_name, "tty");
@@ -562,10 +504,6 @@ main(int argc, char *argv[])
parse_numlist(arg, add_pgrp, NULL, NULL, "process group");
break;
- case 'w':
- output_width = arg ? atoi (arg) : 0; /* 0 means `unlimited'. */
- break;
-
default:
return EINVAL;
}
@@ -588,7 +526,14 @@ main(int argc, char *argv[])
argp_parse (&argp, argc, argv, 0, 0);
if (only_uids->num == 0 && (filter_mask & FILTER_OWNER))
- add_uid (getuid ());
+ /* Restrict the output to only our own processes. */
+ {
+ int uid = getuid ();
+ if (uid >= 0)
+ add_uid (uid);
+ else
+ filter_mask &= ~FILTER_OWNER; /* Must be an anonymous process. */
+ }
{
int fmt_index = parse_enum(fmt_string, fmt_names, "format type", 1);
@@ -600,6 +545,12 @@ main(int argc, char *argv[])
sort_key_name = fmt_sortkeys[fmt_index];
sort_reverse = fmt_sortrev[fmt_index];
}
+ else if (*sort_key_name == '-')
+ /* Sort in reverse. */
+ {
+ sort_reverse = 1;
+ sort_key_name++;
+ }
}
}
@@ -616,7 +567,7 @@ main(int argc, char *argv[])
/* Filter out any processes that we don't want to show. */
if (only_uids->num || not_uids->num)
proc_stat_list_filter1 (procset, proc_stat_owner_ok,
- PSTAT_PROC_INFO, FALSE);
+ PSTAT_OWNER_UID, FALSE);
if (num_tty_names > 0)
{
/* We set the PSTAT_TTY flag separately so that our filter function
@@ -624,8 +575,8 @@ main(int argc, char *argv[])
proc_stat_list_set_flags(procset, PSTAT_TTY);
proc_stat_list_filter1(procset, proc_stat_has_ctty, 0, FALSE);
}
- if (filter_mask & FILTER_NSESSLDR)
- proc_stat_list_filter(procset, &ps_not_sess_leader_filter, FALSE);
+ if (filter_mask & FILTER_NOT_LEADER)
+ proc_stat_list_filter(procset, &ps_not_leader_filter, FALSE);
if (filter_mask & FILTER_UNORPHANED)
proc_stat_list_filter(procset, &ps_unorphaned_filter, FALSE);
if (filter_mask & FILTER_PARENTED)
@@ -638,7 +589,7 @@ main(int argc, char *argv[])
if (show_threads)
proc_stat_list_add_threads(procset);
- if (sort_key_name != NULL)
+ if (sort_key_name)
/* Sort on the given field; we look in both the user-named fields and
the system named fields for the name given, as the user may only know
the printed title and not the official name. */
@@ -711,6 +662,7 @@ main(int argc, char *argv[])
error(0, 0, "No applicable processes");
if (output_width)
+ /* Try and restrict the number of output columns. */
{
int deduce_term_size (int fd, char *type, int *width, int *height);
struct ps_fmt_field *field = ps_fmt_fields (fmt);
@@ -721,8 +673,9 @@ main(int argc, char *argv[])
if (! deduce_term_size (1, getenv ("TERM"), &output_width, 0))
output_width = 80; /* common default */
- /* We're not very clever about this -- just see if the last field is
- `varying' (as it usually is), then set it to the proper max width. */
+ /* We're not very clever about this -- just add up the width of all the
+ fields but the last, and if the last has no existing width (as is
+ the case in most output formats), give it whatever is left over. */
while (--nfields > 0)
{
int fw = field->width;
@@ -733,6 +686,7 @@ main(int argc, char *argv[])
field->width = output_width - field->pfx_len - 1; /* 1 for the CR. */
}
+ /* Finally, output all the processes! */
err = proc_stat_list_fmt (procset, fmt, output);
if (err)
error (5, err, "Couldn't output process status");