summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-11-02 23:31:48 +0000
committerMiles Bader <miles@gnu.org>1995-11-02 23:31:48 +0000
commitc14f2fe9c077d7f9d2d034294037b4cf2a2c5f90 (patch)
tree6db87b70d260a926df6b918c9ab097145dcd2ab4 /utils
parent6cff911567646a7c62f90887b58fc4ed5a0e94ef (diff)
(options): Add --not-owner/-O option.
(id_t, struct ids): New type. (make_ids, ids_add, ids_contains): New functions. (main): Use a struct ids instead of multiple variables to hold the wanted uids list, which renamed to ONLY_UIDS. Add the NOT_UIDS list to contain the opposite sense, and use it. (main): Use proc_stat_proc_info instead of proc_stat_info and PSTAT_PROC_INFO instead of PSTAT_INFO.
Diffstat (limited to 'utils')
-rw-r--r--utils/ps.c102
1 files changed, 75 insertions, 27 deletions
diff --git a/utils/ps.c b/utils/ps.c
index 9afffc3f..f604600b 100644
--- a/utils/ps.c
+++ b/utils/ps.c
@@ -66,7 +66,8 @@ static struct argp_option options[] =
" msg port"},
{"nominal-fields",'n', 0, 0, "Don't elide fields containing"
" `uninteresting' data"},
- {"owner", 'o', "USER", 0, "Show processes owned by USER"},
+ {"owner", 'o', "USER", 0, "Show only processes owned by USER"},
+ {"not-owner", 'O', "USER", 0, "Show only processes not owned by USER"},
{"pid", 'p', "PID", 0, "List the process PID"},
{"pgrp", OPT_PGRP,"PGRP", 0, "List processes in process group PGRP"},
{"no-parent", 'P', 0, 0, "Include processes without parents"},
@@ -303,6 +304,51 @@ 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 *= 2;
+ 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[])
{
@@ -312,10 +358,9 @@ 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;
- unsigned num_uids = 0, uids_alloced = 1;
- uid_t *uids = malloc(sizeof(uid_t) * num_uids);
- unsigned num_tty_names = 0, tty_names_alloced = 1;
- char **tty_names = malloc(sizeof(char *) * num_tty_names);
+ struct ids *only_uids = make_ids (), *not_uids = make_ids ();
+ char **tty_names = 0;
+ unsigned num_tty_names = 0, tty_names_alloced = 0;
proc_stat_list_t procset;
ps_context_t context;
ps_fmt_t fmt;
@@ -360,28 +405,27 @@ main(int argc, char *argv[])
if (err)
error(2, err, "Couldn't add process group");
}
-
+
/* Add a user who's processes should be printed out. */
- void add_uid (unsigned uid)
+ void add_uid (id_t uid)
{
- if (uids_alloced == num_uids)
- {
- uids_alloced *= 2;
- uids = realloc(uids, uids_alloced * sizeof(int));
- if (uids == NULL)
- error(8, ENOMEM, "Can't allocate uid list");
- }
- uids[num_uids++] = uid;
+ ids_add (only_uids, uid);
}
- /* Returns TRUE if PS is owned by any of the users in UIDS. */
- bool proc_stat_has_owner(struct proc_stat *ps)
+ /* Add a user who's processes should not be printed out. */
+ void add_not_uid (id_t uid)
{
- unsigned i;
- uid_t uid = proc_stat_info(ps)->owner;
- for (i = 0; i < num_uids; i++)
- if (uids[i] == uid)
- return TRUE;
- return FALSE;
+ ids_add (not_uids, 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))
+ return 0;
+ if (not_uids->num > 0 && ids_contains (not_uids, uid))
+ return 0;
+ return 1;
}
/* Add TTY_NAME to the list for which processes with those controlling
@@ -501,6 +545,9 @@ main(int argc, char *argv[])
case 'o':
parse_numlist(arg, add_uid, NULL, lookup_user, "user");
break;
+ case 'O':
+ parse_numlist (arg, add_not_uid, NULL, lookup_user, "user");
+ break;
case OPT_SESS:
parse_numlist(arg, add_sid, current_sid, NULL, "session id");
break;
@@ -536,8 +583,8 @@ main(int argc, char *argv[])
/* Parse our command line. This shouldn't ever return an error. */
argp_parse (&argp, argc, argv, 0, 0);
- if (num_uids == 0 && (filter_mask & FILTER_OWNER))
- add_uid(getuid());
+ if (only_uids->num == 0 && (filter_mask & FILTER_OWNER))
+ add_uid (getuid ());
{
int fmt_index = parse_enum(fmt_string, fmt_names, "format type", 1);
@@ -563,8 +610,9 @@ main(int argc, char *argv[])
proc_stat_list_set_flags(procset, PSTAT_NO_MSGPORT);
/* Filter out any processes that we don't want to show. */
- if (num_uids > 0)
- proc_stat_list_filter1(procset, proc_stat_has_owner, PSTAT_INFO, FALSE);
+ if (only_uids->num || not_uids->num)
+ proc_stat_list_filter1 (procset, proc_stat_owner_ok,
+ PSTAT_PROC_INFO, FALSE);
if (num_tty_names > 0)
{
/* We set the PSTAT_TTY flag separately so that our filter function