2 * Copyright 1998-2002 by Albert Cahalan; all rights resered.
3 * This file may be used subject to the terms and conditions of the
4 * GNU Library General Public License Version 2, or any later version
5 * at your option, as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU Library General Public License for more details.
15 #include "../include/nls.h"
16 #include "../proc/procps.h"
17 #include "../proc/escape.h"
18 #include "../proc/readproc.h"
21 #define trace(...) printf(## __VA_ARGS__)
27 /***************** GENERAL DEFINE ********************/
44 #define SEL_PID_QUICK 15
46 /* Since an enum could be smashed by a #define, it would be bad. */
47 #define U98 0 /* Unix98 standard */ /* This must be 0 */
48 #define XXX 1 /* Common extension */
49 #define DEC 2 /* Digital Unix */
50 #define AIX 3 /* AIX */
51 #define SCO 4 /* SCO */
52 #define LNX 5 /* Linux original :-) */
53 #define BSD 6 /* FreeBSD and OpenBSD */
54 #define SUN 7 /* SunOS 5 (Solaris) */
55 #define HPU 8 /* HP-UX */
56 #define SGI 9 /* Irix */
57 #define SOE 10 /* IBM's S/390 OpenEdition */
58 #define TST 11 /* test code */
61 * Try not to overflow the output buffer:
62 * 32 pages for env+cmd
63 * 64 kB pages on IA-64
64 * 4 chars for "\377", or 1 when mangling to '?' (ESC_STRETCH)
65 * plus some slack for other stuff
66 * That is about 8.5 MB on IA-64, or 0.6 MB on i386
68 * Sadly, current kernels only supply one page of env/command data.
69 * The buffer is now protected with a guard page, and via other means
70 * to avoid hitting the guard page.
73 /* output buffer size */
74 #define OUTBUF_SIZE (2 * 64*1024 * ESC_STRETCH)
76 /******************* PS DEFINE *******************/
79 // Justification control for flags field comes first.
80 #define CF_JUST_MASK 0x0f
82 #define CF_USER 1 // left if text, right if numeric
85 #define CF_UNLIMITED 4
86 #define CF_WCHAN 5 // left if text, right if numeric
87 #define CF_SIGNAL 6 // right in 9, or 16 if screen_cols>107
88 // Then the other flags
89 #define CF_PIDMAX 0x00000010 // react to pid_max
90 // Only one allowed; use separate bits to catch errors.
91 #define CF_PRINT_THREAD_ONLY 0x10000000
92 #define CF_PRINT_PROCESS_ONLY 0x20000000
93 #define CF_PRINT_EVERY_TIME 0x40000000
94 #define CF_PRINT_AS_NEEDED 0x80000000 // means we have no clue, so assume EVERY TIME
95 #define CF_PRINT_MASK 0xf0000000
97 #define needs_for_select (PROC_FILLSTAT | PROC_FILLSTATUS)
100 #define TF_B_H 0x0001
101 #define TF_B_m 0x0002
102 #define TF_U_m 0x0004
103 #define TF_U_T 0x0008
104 #define TF_U_L 0x0010
105 #define TF_show_proc 0x0100 // show the summary line
106 #define TF_show_task 0x0200 // show the per-thread lines
107 #define TF_show_both 0x0400 // distinct proc/task format lists
108 #define TF_loose_tasks 0x0800 // let sorting break up task groups (BSDish)
109 #define TF_no_sort 0x1000 // don't know if thread-grouping should survive a sort
110 #define TF_no_forest 0x2000 // don't see how to do threads w/ forest option
111 #define TF_must_use 0x4000 // options only make sense if LWP/SPID column added
113 /* personality control flags */
114 #define PER_BROKEN_o 0x0001
115 #define PER_BSD_h 0x0002
116 #define PER_BSD_m 0x0004
117 #define PER_IRIX_l 0x0008
118 #define PER_FORCE_BSD 0x0010
119 #define PER_GOOD_o 0x0020
120 #define PER_OLD_m 0x0040
121 #define PER_NO_DEFAULT_g 0x0080
122 #define PER_ZAP_ADDR 0x0100
123 #define PER_SANE_USER 0x0200
124 #define PER_HPUX_x 0x0400
125 #define PER_SVR4_x 0x0800
126 #define PER_BSD_COLS 0x1000
127 #define PER_UNIX_COLS 0x2000
129 /* Simple selections by bit mask */
136 /* predefined format flags such as: -l -f l u s -j */
137 #define FF_Uf 0x0001 /* -f */
138 #define FF_Uj 0x0002 /* -j */
139 #define FF_Ul 0x0004 /* -l */
140 #define FF_Bj 0x0008 /* j */
141 #define FF_Bl 0x0010 /* l */
142 #define FF_Bs 0x0020 /* s */
143 #define FF_Bu 0x0040 /* u */
144 #define FF_Bv 0x0080 /* v */
145 #define FF_LX 0x0100 /* X */
146 #define FF_Lm 0x0200 /* m */ /* overloaded: threads, sort, format */
147 #define FF_Fc 0x0400 /* --context */ /* Flask security context format */
149 /* predefined format modifier flags such as: -l -f l u s -j */
150 #define FM_c 0x0001 /* -c */
151 #define FM_j 0x0002 /* -j */ /* only set when !sysv_j_format */
152 #define FM_y 0x0004 /* -y */
153 //#define FM_L 0x0008 /* -L */
154 #define FM_P 0x0010 /* -P */
155 #define FM_M 0x0020 /* -M */
156 //#define FM_T 0x0040 /* -T */
157 #define FM_F 0x0080 /* -F */ /* -F also sets the regular -f flags */
159 /* sorting & formatting */
160 /* U,B,G is Unix,BSD,Gnu and then there is the option itself */
165 #define SF_B_m 5 /* overloaded: threads, sort, format */
167 #define SF_G_format 7
170 #define HEAD_SINGLE 0 /* default, must be 0 */
175 /********************** GENERAL TYPEDEF *******************/
177 /* Other fields that might be useful:
179 * char *name; user-defined column name (format specification)
180 * int reverse; sorting in reverse (sort specification)
183 * reverse in place of n
186 typedef union sel_union {
192 char cmd[16]; /* this is _not_ \0 terminated */
195 typedef struct selection_node {
196 struct selection_node *next;
197 sel_union *u; /* used if selection type has a list of values */
198 int n; /* used if selection type has a list of values */
202 typedef struct sort_node {
203 struct sort_node *next;
204 int (*sr)(const proc_t* P, const proc_t* Q); /* sort function */
205 int reverse; /* can sort backwards */
210 typedef struct format_node {
211 struct format_node *next;
212 char *name; /* user can override default name */
213 int (*pr)(char *restrict const outbuf, const proc_t *restrict const pp); // print function
214 /* int (* const sr)(const proc_t* P, const proc_t* Q); */ /* sort function */
217 int vendor; /* Vendor that invented this */
222 typedef struct format_struct {
223 const char *spec; /* format specifier */
224 const char *head; /* default header in the POSIX locale */
225 int (* const pr)(char *restrict const outbuf, const proc_t *restrict const pp); // print function
226 int (* const sr)(const proc_t* P, const proc_t* Q); /* sort function */
228 const int need; /* data we will need (files to read, etc.) */
229 const int vendor; /* Where does this come from? */
233 /* though ps-specific, needed by general file */
234 typedef struct macro_struct {
235 const char *spec; /* format specifier */
236 const char *head; /* default header in the POSIX locale */
239 /**************** PS TYPEDEF ***********************/
241 typedef struct aix_struct {
242 const int desc; /* 1-character format code */
243 const char *spec; /* format specifier */
244 const char *head; /* default header in the POSIX locale */
247 typedef struct shortsort_struct {
248 const int desc; /* 1-character format code */
249 const char *spec; /* format specifier */
252 /* Save these options for later: -o o -O O --format --sort */
253 typedef struct sf_node {
254 struct sf_node *next; /* next arg */
255 format_node *f_cooked; /* convert each arg alone, then merge */
256 sort_node *s_cooked; /* convert each arg alone, then merge */
261 /********************* UNDECIDED GLOBALS **************/
264 extern void show_one_proc(const proc_t *restrict const p, const format_node *restrict fmt);
265 extern void print_format_specifiers(void);
266 extern const aix_struct *search_aix_array(const int findme);
267 extern const shortsort_struct *search_shortsort_array(const int findme);
268 extern const format_struct *search_format_array(const char *findme);
269 extern const macro_struct *search_macro_array(const char *findme);
270 extern void init_output(void);
271 extern int pr_nop(char *restrict const outbuf, const proc_t *restrict const pp);
274 extern void reset_global(void);
277 extern int all_processes;
278 extern const char *bsd_j_format;
279 extern const char *bsd_l_format;
280 extern const char *bsd_s_format;
281 extern const char *bsd_u_format;
282 extern const char *bsd_v_format;
283 extern int bsd_c_option;
284 extern int bsd_e_option;
285 extern uid_t cached_euid;
286 extern dev_t cached_tty;
287 extern char forest_prefix[4 * 32*1024 + 100];
288 extern int forest_type;
289 extern unsigned format_flags; /* -l -f l u s -j... */
290 extern format_node *format_list; /* digested formatting options */
291 extern unsigned format_modifiers; /* -c -j -y -P -L... */
292 extern int header_gap;
293 extern int header_type; /* none, single, multi... */
294 extern int include_dead_children;
295 extern int lines_to_next_header;
296 extern int max_line_width;
297 extern int negate_selection;
298 extern int page_size; // "int" for math reasons?
299 extern unsigned personality;
300 extern int prefer_bsd_defaults;
301 extern int running_only;
302 extern int screen_cols;
303 extern int screen_rows;
304 extern time_t seconds_since_boot;
305 extern selection_node *selection_list;
306 extern unsigned simple_select;
307 extern sort_node *sort_list;
308 extern const char *sysv_f_format;
309 extern const char *sysv_fl_format;
310 extern const char *sysv_j_format;
311 extern const char *sysv_l_format;
312 extern unsigned thread_flags;
313 extern int unix_f_option;
314 extern int user_is_number;
315 extern int wchan_is_number;
316 extern const char *the_word_help;
318 /************************* PS GLOBALS *********************/
324 extern int defer_sf_option(const char *arg, int source);
325 extern const char *process_sf_options();
326 extern void reset_sortformat(void);
329 extern int want_this_proc(proc_t *buf);
330 extern const char *select_bits_setup(void);
333 extern void do_help(const char *opt, int rc) NORETURN;
336 extern void self_info(void);
337 extern void catastrophic_failure(const char *filename, unsigned int linenum,
338 const char *message);
341 extern int arg_parse(int argc, char *argv[]);