diff options
Diffstat (limited to 'utils/psout.c')
-rw-r--r-- | utils/psout.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/utils/psout.c b/utils/psout.c new file mode 100644 index 00000000..d3bde0cf --- /dev/null +++ b/utils/psout.c @@ -0,0 +1,144 @@ +/* Common output function for ps & w + + Copyright (C) 1995, 1996, 1998 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 <string.h> +#include <unistd.h> +#include <error.h> +#include <ps.h> + +void +psout (struct proc_stat_list *procs, + char *fmt_string, int posix_fmt, struct ps_fmt_specs *specs, + char *sort_key_name, int sort_reverse, + int output_width, int print_heading, + int squash_bogus_fields, int squash_nominal_fields, + int top) +{ + error_t err; + struct ps_stream *output; + struct ps_fmt *fmt; + + err = ps_fmt_create (fmt_string, posix_fmt, specs, &fmt); + if (err) + { + char *problem; + ps_fmt_creation_error (fmt_string, posix_fmt, specs, &problem); + error (4, 0, "%s", problem); + } + + if (squash_bogus_fields) + /* Remove any fields that we can't print anyway (because of system + bugs/protection violations?). */ + { + ps_flags_t bogus_flags = ps_fmt_needs (fmt); + + err = proc_stat_list_find_bogus_flags (procs, &bogus_flags); + if (err) + error (0, err, "Couldn't remove bogus fields"); + else + ps_fmt_squash_flags (fmt, bogus_flags); + } + + if (squash_nominal_fields) + /* Remove any fields that contain only `uninteresting' information. */ + { + int nominal (struct ps_fmt_field *field) + { + return !(field->flags & PS_FMT_FIELD_KEEP) + && proc_stat_list_spec_nominal (procs, field->spec); + } + ps_fmt_squash (fmt, nominal); + } + + if (sort_key_name) + /* Sort on the given field. */ + { + const struct ps_fmt_spec *sort_key; + + if (*sort_key_name == '-') + /* Sort in reverse. */ + { + sort_reverse = 1; + sort_key_name++; + } + + sort_key = ps_fmt_specs_find (specs, sort_key_name); + if (sort_key == NULL) + error (3, 0, "%s: bad sort key", sort_key_name); + + err = proc_stat_list_sort (procs, sort_key, sort_reverse); + if (err) + /* Give an error message, but don't exit. */ + error (0, err, "Couldn't sort processes"); + } + + err = ps_stream_create (stdout, &output); + if (err) + error (5, err, "Can't make output stream"); + + if (print_heading) + { + if (procs->num_procs > 0) + { + err = ps_fmt_write_titles (fmt, output); + if (err) + error (0, err, "Can't print titles"); + ps_stream_newline (output); + } + else + 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); + if (output_width < 0) + /* Have to figure it out! */ + if (! deduce_term_size (1, getenv ("TERM"), &output_width, 0)) + output_width = 80; /* common default */ + ps_fmt_set_output_width (fmt, output_width); + } + + if (top) + /* Restrict output to the top TOP entries, if TOP is positive, or the + bottom -TOP entries, if it is negative. */ + { + int filter (struct proc_stat *ps) + { + return --top >= 0; + } + if (top < 0) + { + top += procs->num_procs; + proc_stat_list_filter1 (procs, filter, 0, 1); + } + else + proc_stat_list_filter1 (procs, filter, 0, 0); + } + + /* Finally, output all the processes! */ + err = proc_stat_list_fmt (procs, fmt, output); + if (err) + error (5, err, "Couldn't output process status"); +} |