53917334d0
This commit just compliments a change referenced below
by providing the value which includes reaped children.
[ as an aside, it looks like ps only includes reaped ]
[ children values under an obscure BSD or GNU option ]
[ so, this change is possibly of even more relevance ]
Reference(s):
. Mar, 2022 - added %CUU
commit 2ac72e2e80
Signed-off-by: Jim Warner <james.warner@comcast.net>
499 lines
14 KiB
C
499 lines
14 KiB
C
/*
|
|
* Copyright 1998-2002 by Albert Cahalan; all rights resered.
|
|
* This file may be used subject to the terms and conditions of the
|
|
* GNU Library General Public License Version 2, or any later version
|
|
* at your option, as published by the Free Software Foundation.
|
|
* 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 Library General Public License for more details.
|
|
*/
|
|
|
|
#ifndef PROCPS_PS_H
|
|
#define PROCPS_PS_H
|
|
|
|
#include "../include/nls.h"
|
|
#include <proc/meminfo.h>
|
|
#include <proc/misc.h>
|
|
#include <proc/pids.h>
|
|
#include <proc/stat.h>
|
|
|
|
// --- <pids> interface begin ||||||||||||||||||||||||||||||||||||||||||||
|
|
// -----------------------------------------------------------------------
|
|
|
|
// hack to minimize code impact
|
|
#undef proc_t
|
|
#define proc_t struct pids_stack
|
|
|
|
/* this is for allocation of the Pids_items and represents a compromise.
|
|
we can't predict how many fields will actually be requested yet there
|
|
are numerous duplicate format_array entries. here are the statistics:
|
|
252 entries in the format_array
|
|
82 of those entries are unique
|
|
60 equals a former proc_t size
|
|
in reality, only a small portion of the stack depth will be occupied,
|
|
and the excess represents storage cost only, not a run-time cpu cost! */
|
|
#define PIDSITEMS 70
|
|
|
|
/* a 'results stack value' extractor macro
|
|
where: E=rel enum, T=data type, S=stack */
|
|
#define rSv(E,T,S) PIDS_VAL(rel_ ## E, T, S, Pids_info)
|
|
|
|
#define namREL(e) rel_ ## e
|
|
#define makEXT(e) extern int namREL(e);
|
|
#define makREL(e) int namREL(e) = -1;
|
|
#define chkREL(e) if (namREL(e) < 0) { \
|
|
Pids_items[Pids_index] = PIDS_ ## e; \
|
|
namREL(e) = (Pids_index < PIDSITEMS) ? Pids_index++ : rel_noop; }
|
|
|
|
#define setREL1(e) { \
|
|
if (!outbuf) { \
|
|
chkREL(e) \
|
|
return 0; \
|
|
} }
|
|
#define setREL2(e1,e2) { \
|
|
if (!outbuf) { \
|
|
chkREL(e1) chkREL(e2) \
|
|
return 0; \
|
|
} }
|
|
#define setREL3(e1,e2,e3) { \
|
|
if (!outbuf) { \
|
|
chkREL(e1) chkREL(e2) chkREL(e3) \
|
|
return 0; \
|
|
} }
|
|
#define setREL4(e1,e2,e3,e4) { \
|
|
if (!outbuf) { \
|
|
chkREL(e1) chkREL(e2) chkREL(e3) chkREL(e4) \
|
|
return 0; \
|
|
} }
|
|
|
|
extern struct pids_info *Pids_info;
|
|
extern enum pids_item *Pids_items;
|
|
extern int Pids_index;
|
|
|
|
// most of these need not be extern, they're unique to output.c
|
|
// (but for future flexibility the easiest path has been taken)
|
|
makEXT(ADDR_CODE_END)
|
|
makEXT(ADDR_CODE_START)
|
|
makEXT(ADDR_CURR_EIP)
|
|
makEXT(ADDR_CURR_ESP)
|
|
makEXT(ADDR_STACK_START)
|
|
makEXT(AUTOGRP_ID)
|
|
makEXT(AUTOGRP_NICE)
|
|
makEXT(CGNAME)
|
|
makEXT(CGROUP)
|
|
makEXT(CMD)
|
|
makEXT(CMDLINE)
|
|
makEXT(ENVIRON)
|
|
makEXT(EXE)
|
|
makEXT(FLAGS)
|
|
makEXT(FLT_MAJ)
|
|
makEXT(FLT_MAJ_C)
|
|
makEXT(FLT_MIN)
|
|
makEXT(FLT_MIN_C)
|
|
makEXT(ID_EGID)
|
|
makEXT(ID_EGROUP)
|
|
makEXT(ID_EUID)
|
|
makEXT(ID_EUSER)
|
|
makEXT(ID_FGID)
|
|
makEXT(ID_FGROUP)
|
|
makEXT(ID_FUID)
|
|
makEXT(ID_FUSER)
|
|
makEXT(ID_LOGIN)
|
|
makEXT(ID_PGRP)
|
|
makEXT(ID_PID)
|
|
makEXT(ID_PPID)
|
|
makEXT(ID_RGID)
|
|
makEXT(ID_RGROUP)
|
|
makEXT(ID_RUID)
|
|
makEXT(ID_RUSER)
|
|
makEXT(ID_SESSION)
|
|
makEXT(ID_SGID)
|
|
makEXT(ID_SGROUP)
|
|
makEXT(ID_SUID)
|
|
makEXT(ID_SUSER)
|
|
makEXT(ID_TGID)
|
|
makEXT(ID_TPGID)
|
|
makEXT(IO_READ_BYTES)
|
|
makEXT(IO_READ_CHARS)
|
|
makEXT(IO_READ_OPS)
|
|
makEXT(IO_WRITE_BYTES)
|
|
makEXT(IO_WRITE_CBYTES)
|
|
makEXT(IO_WRITE_CHARS)
|
|
makEXT(IO_WRITE_OPS)
|
|
makEXT(LXCNAME)
|
|
makEXT(NICE)
|
|
makEXT(NLWP)
|
|
makEXT(NS_IPC)
|
|
makEXT(NS_MNT)
|
|
makEXT(NS_NET)
|
|
makEXT(NS_PID)
|
|
makEXT(NS_USER)
|
|
makEXT(NS_UTS)
|
|
makEXT(OOM_ADJ)
|
|
makEXT(OOM_SCORE)
|
|
makEXT(PRIORITY)
|
|
makEXT(PRIORITY_RT)
|
|
makEXT(PROCESSOR)
|
|
makEXT(PROCESSOR_NODE)
|
|
makEXT(RSS)
|
|
makEXT(RSS_RLIM)
|
|
makEXT(SCHED_CLASS)
|
|
makEXT(SD_MACH)
|
|
makEXT(SD_OUID)
|
|
makEXT(SD_SEAT)
|
|
makEXT(SD_SESS)
|
|
makEXT(SD_SLICE)
|
|
makEXT(SD_UNIT)
|
|
makEXT(SD_UUNIT)
|
|
makEXT(SIGBLOCKED)
|
|
makEXT(SIGCATCH)
|
|
makEXT(SIGIGNORE)
|
|
makEXT(SIGNALS)
|
|
makEXT(SIGPENDING)
|
|
makEXT(SMAP_PRV_TOTAL)
|
|
makEXT(SMAP_PSS)
|
|
makEXT(STATE)
|
|
makEXT(SUPGIDS)
|
|
makEXT(SUPGROUPS)
|
|
makEXT(TICS_ALL)
|
|
makEXT(TICS_ALL_C)
|
|
makEXT(TIME_ALL)
|
|
makEXT(TIME_ELAPSED)
|
|
makEXT(TICS_BEGAN)
|
|
makEXT(TTY)
|
|
makEXT(TTY_NAME)
|
|
makEXT(TTY_NUMBER)
|
|
makEXT(UTILIZATION)
|
|
makEXT(UTILIZATION_C)
|
|
makEXT(VM_DATA)
|
|
makEXT(VM_RSS_LOCKED)
|
|
makEXT(VM_RSS)
|
|
makEXT(VM_SIZE)
|
|
makEXT(VM_STACK)
|
|
makEXT(VSIZE_PGS)
|
|
makEXT(WCHAN_NAME)
|
|
makEXT(extra)
|
|
makEXT(noop)
|
|
// -----------------------------------------------------------------------
|
|
// --- <pids> interface end ||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|
#if 0
|
|
#define trace(...) printf(## __VA_ARGS__)
|
|
#else
|
|
#define trace(...)
|
|
#endif
|
|
|
|
|
|
/***************** GENERAL DEFINE ********************/
|
|
|
|
/* selection list */
|
|
#define SEL_RUID 1
|
|
#define SEL_EUID 2
|
|
#define SEL_SUID 3
|
|
#define SEL_FUID 4
|
|
#define SEL_RGID 5
|
|
#define SEL_EGID 6
|
|
#define SEL_SGID 7
|
|
#define SEL_FGID 8
|
|
#define SEL_PGRP 9
|
|
#define SEL_PID 10
|
|
#define SEL_TTY 11
|
|
#define SEL_SESS 12
|
|
#define SEL_COMM 13
|
|
#define SEL_PPID 14
|
|
#define SEL_PID_QUICK 15
|
|
|
|
/* Since an enum could be smashed by a #define, it would be bad. */
|
|
#define U98 0 /* Unix98 standard */ /* This must be 0 */
|
|
#define XXX 1 /* Common extension */
|
|
#define DEC 2 /* Digital Unix */
|
|
#define AIX 3 /* AIX */
|
|
#define SCO 4 /* SCO */
|
|
#define LNX 5 /* Linux original :-) */
|
|
#define BSD 6 /* FreeBSD and OpenBSD */
|
|
#define SUN 7 /* SunOS 5 (Solaris) */
|
|
#define HPU 8 /* HP-UX */
|
|
#define SGI 9 /* Irix */
|
|
#define SOE 10 /* IBM's S/390 OpenEdition */
|
|
#define TST 11 /* test code */
|
|
|
|
/*
|
|
* Try not to overflow the output buffer:
|
|
* 32 pages for env+cmd
|
|
* 64 kB pages on IA-64
|
|
* plus some slack for other stuff
|
|
* That is about 8.5 MB on IA-64, or 0.6 MB on i386
|
|
*
|
|
* Sadly, current kernels only supply one page of env/command data.
|
|
* The buffer is now protected with a guard page, and via other means
|
|
* to avoid hitting the guard page.
|
|
*/
|
|
|
|
/* output buffer size */
|
|
#define OUTBUF_SIZE (2 * 64*1024)
|
|
|
|
/******************* PS DEFINE *******************/
|
|
|
|
// Column flags
|
|
// Justification control for flags field comes first.
|
|
#define CF_JUST_MASK 0x0f
|
|
// CF_AIXHACK 0
|
|
#define CF_USER 1 // left if text, right if numeric
|
|
#define CF_LEFT 2
|
|
#define CF_RIGHT 3
|
|
#define CF_UNLIMITED 4
|
|
#define CF_WCHAN 5 // left if text, right if numeric
|
|
#define CF_SIGNAL 6 // right in 9, or 16 if screen_cols>107
|
|
// Then the other flags
|
|
#define CF_PIDMAX 0x00000010 // react to pid_max
|
|
// Only one allowed; use separate bits to catch errors.
|
|
#define CF_PRINT_THREAD_ONLY 0x10000000
|
|
#define CF_PRINT_PROCESS_ONLY 0x20000000
|
|
#define CF_PRINT_EVERY_TIME 0x40000000
|
|
#define CF_PRINT_AS_NEEDED 0x80000000 // means we have no clue, so assume EVERY TIME
|
|
#define CF_PRINT_MASK 0xf0000000
|
|
|
|
/* thread_flags */
|
|
#define TF_B_H 0x0001
|
|
#define TF_B_m 0x0002
|
|
#define TF_U_m 0x0004
|
|
#define TF_U_T 0x0008
|
|
#define TF_U_L 0x0010
|
|
#define TF_show_proc 0x0100 // show the summary line
|
|
#define TF_show_task 0x0200 // show the per-thread lines
|
|
#define TF_show_both 0x0400 // distinct proc/task format lists
|
|
#define TF_loose_tasks 0x0800 // let sorting break up task groups (BSDish)
|
|
#define TF_no_sort 0x1000 // don't know if thread-grouping should survive a sort
|
|
#define TF_no_forest 0x2000 // don't see how to do threads w/ forest option
|
|
#define TF_must_use 0x4000 // options only make sense if LWP/SPID column added
|
|
|
|
/* personality control flags */
|
|
#define PER_BROKEN_o 0x0001
|
|
#define PER_BSD_h 0x0002
|
|
#define PER_BSD_m 0x0004
|
|
#define PER_IRIX_l 0x0008
|
|
#define PER_FORCE_BSD 0x0010
|
|
#define PER_GOOD_o 0x0020
|
|
#define PER_OLD_m 0x0040
|
|
#define PER_NO_DEFAULT_g 0x0080
|
|
#define PER_ZAP_ADDR 0x0100
|
|
#define PER_SANE_USER 0x0200
|
|
#define PER_HPUX_x 0x0400
|
|
#define PER_SVR4_x 0x0800
|
|
#define PER_BSD_COLS 0x1000
|
|
#define PER_UNIX_COLS 0x2000
|
|
|
|
/* Simple selections by bit mask */
|
|
#define SS_B_x 0x01
|
|
#define SS_B_g 0x02
|
|
#define SS_U_d 0x04
|
|
#define SS_U_a 0x08
|
|
#define SS_B_a 0x10
|
|
|
|
/* predefined format flags such as: -l -f l u s -j */
|
|
#define FF_Uf 0x0001 /* -f */
|
|
#define FF_Uj 0x0002 /* -j */
|
|
#define FF_Ul 0x0004 /* -l */
|
|
#define FF_Bj 0x0008 /* j */
|
|
#define FF_Bl 0x0010 /* l */
|
|
#define FF_Bs 0x0020 /* s */
|
|
#define FF_Bu 0x0040 /* u */
|
|
#define FF_Bv 0x0080 /* v */
|
|
#define FF_LX 0x0100 /* X */
|
|
#define FF_Lm 0x0200 /* m */ /* overloaded: threads, sort, format */
|
|
#define FF_Fc 0x0400 /* --context */ /* Flask security context format */
|
|
|
|
/* predefined format modifier flags such as: -l -f l u s -j */
|
|
#define FM_c 0x0001 /* -c */
|
|
#define FM_j 0x0002 /* -j */ /* only set when !sysv_j_format */
|
|
#define FM_y 0x0004 /* -y */
|
|
//#define FM_L 0x0008 /* -L */
|
|
#define FM_P 0x0010 /* -P */
|
|
#define FM_M 0x0020 /* -M */
|
|
//#define FM_T 0x0040 /* -T */
|
|
#define FM_F 0x0080 /* -F */ /* -F also sets the regular -f flags */
|
|
|
|
/* sorting & formatting */
|
|
/* U,B,G is Unix,BSD,Gnu and then there is the option itself */
|
|
#define SF_U_O 1
|
|
#define SF_U_o 2
|
|
#define SF_B_O 3
|
|
#define SF_B_o 4
|
|
#define SF_B_m 5 /* overloaded: threads, sort, format */
|
|
#define SF_G_sort 6
|
|
#define SF_G_format 7
|
|
|
|
/* headers */
|
|
#define HEAD_SINGLE 0 /* default, must be 0 */
|
|
#define HEAD_NONE 1
|
|
#define HEAD_MULTI 2
|
|
|
|
|
|
/********************** GENERAL TYPEDEF *******************/
|
|
|
|
/* Other fields that might be useful:
|
|
*
|
|
* char *name; user-defined column name (format specification)
|
|
* int reverse; sorting in reverse (sort specification)
|
|
*
|
|
* name in place of u
|
|
* reverse in place of n
|
|
*/
|
|
|
|
typedef union sel_union {
|
|
pid_t pid;
|
|
pid_t ppid;
|
|
uid_t uid;
|
|
gid_t gid;
|
|
dev_t tty;
|
|
char cmd[64]; /* this is _not_ \0 terminated */
|
|
} sel_union;
|
|
|
|
typedef struct selection_node {
|
|
struct selection_node *next;
|
|
sel_union *u; /* used if selection type has a list of values */
|
|
int n; /* used if selection type has a list of values */
|
|
int typecode;
|
|
} selection_node;
|
|
|
|
typedef struct sort_node {
|
|
struct sort_node *next;
|
|
enum pids_item sr;
|
|
int (*xe)(char *, proc_t *); // special format_node 'pr' guy
|
|
enum pids_sort_order reverse;
|
|
int typecode;
|
|
} sort_node;
|
|
|
|
typedef struct format_node {
|
|
struct format_node *next;
|
|
char *name; /* user can override default name */
|
|
int (*pr)(char *restrict const outbuf, const proc_t *restrict const pp); // print function
|
|
int width;
|
|
int vendor; /* Vendor that invented this */
|
|
int flags;
|
|
int typecode;
|
|
} format_node;
|
|
|
|
typedef struct format_struct {
|
|
const char *spec; /* format specifier */
|
|
const char *head; /* default header in the POSIX locale */
|
|
int (* const pr)(char *restrict const outbuf, const proc_t *restrict const pp); // print function
|
|
enum pids_item sr;
|
|
const int width;
|
|
const int vendor; /* Where does this come from? */
|
|
const int flags;
|
|
} format_struct;
|
|
|
|
/* though ps-specific, needed by general file */
|
|
typedef struct macro_struct {
|
|
const char *spec; /* format specifier */
|
|
const char *head; /* default header in the POSIX locale */
|
|
} macro_struct;
|
|
|
|
/**************** PS TYPEDEF ***********************/
|
|
|
|
typedef struct aix_struct {
|
|
const int desc; /* 1-character format code */
|
|
const char *spec; /* format specifier */
|
|
const char *head; /* default header in the POSIX locale */
|
|
} aix_struct;
|
|
|
|
typedef struct shortsort_struct {
|
|
const int desc; /* 1-character format code */
|
|
const char *spec; /* format specifier */
|
|
} shortsort_struct;
|
|
|
|
/* Save these options for later: -o o -O O --format --sort */
|
|
typedef struct sf_node {
|
|
struct sf_node *next; /* next arg */
|
|
format_node *f_cooked; /* convert each arg alone, then merge */
|
|
sort_node *s_cooked; /* convert each arg alone, then merge */
|
|
char *sf;
|
|
int sf_code;
|
|
} sf_node;
|
|
|
|
/********************* UNDECIDED GLOBALS **************/
|
|
|
|
/* output.c */
|
|
extern void show_one_proc(const proc_t *restrict const p, const format_node *restrict fmt);
|
|
extern void print_format_specifiers(void);
|
|
extern const aix_struct *search_aix_array(const int findme);
|
|
extern const shortsort_struct *search_shortsort_array(const int findme);
|
|
extern const format_struct *search_format_array(const char *findme);
|
|
extern const macro_struct *search_macro_array(const char *findme);
|
|
extern void init_output(void);
|
|
extern int pr_nop(char *restrict const outbuf, const proc_t *restrict const pp);
|
|
|
|
/* global.c */
|
|
extern void reset_global(void);
|
|
|
|
/* global.c */
|
|
extern int all_processes;
|
|
extern const char *bsd_j_format;
|
|
extern const char *bsd_l_format;
|
|
extern const char *bsd_s_format;
|
|
extern const char *bsd_u_format;
|
|
extern const char *bsd_v_format;
|
|
extern int bsd_c_option;
|
|
extern int bsd_e_option;
|
|
extern uid_t cached_euid;
|
|
extern int cached_tty;
|
|
extern char forest_prefix[4 * 32*1024 + 100];
|
|
extern int forest_type;
|
|
extern unsigned format_flags; /* -l -f l u s -j... */
|
|
extern format_node *format_list; /* digested formatting options */
|
|
extern unsigned format_modifiers; /* -c -j -y -P -L... */
|
|
extern int header_gap;
|
|
extern int header_type; /* none, single, multi... */
|
|
extern int include_dead_children;
|
|
extern int lines_to_next_header;
|
|
extern int max_line_width;
|
|
extern int negate_selection;
|
|
extern int page_size; // "int" for math reasons?
|
|
extern unsigned personality;
|
|
extern int prefer_bsd_defaults;
|
|
extern int running_only;
|
|
extern int screen_cols;
|
|
extern int screen_rows;
|
|
extern selection_node *selection_list;
|
|
extern unsigned simple_select;
|
|
extern sort_node *sort_list;
|
|
extern const char *sysv_f_format;
|
|
extern const char *sysv_fl_format;
|
|
extern const char *sysv_j_format;
|
|
extern const char *sysv_l_format;
|
|
extern unsigned thread_flags;
|
|
extern int unix_f_option;
|
|
extern int user_is_number;
|
|
extern int wchan_is_number;
|
|
extern const char *the_word_help;
|
|
|
|
/************************* PS GLOBALS *********************/
|
|
|
|
/* display.c */
|
|
extern char *myname;
|
|
|
|
/* sortformat.c */
|
|
extern int defer_sf_option(const char *arg, int source);
|
|
extern const char *process_sf_options();
|
|
extern void reset_sortformat(void);
|
|
|
|
/* select.c */
|
|
extern int want_this_proc(proc_t *buf);
|
|
extern const char *select_bits_setup(void);
|
|
|
|
/* help.c */
|
|
extern void __attribute__ ((__noreturn__)) do_help(const char *opt, int rc);
|
|
|
|
/* global.c */
|
|
extern void self_info(void);
|
|
extern void catastrophic_failure(const char *filename, unsigned int linenum,
|
|
const char *message);
|
|
|
|
/* parser.c */
|
|
extern int arg_parse(int argc, char *argv[]);
|
|
|
|
#endif
|