File: | obj-scan-build/libps/../../libps/spec.c |
Location: | line 418, column 5 |
Description: | Value stored to 'value_len' is never read |
1 | /* Access, formatting, & comparison routines for printing process info. |
2 | |
3 | Copyright (C) 1995,96,97,99,2001,02 Free Software Foundation, Inc. |
4 | |
5 | Written by Miles Bader <miles@gnu.org> |
6 | |
7 | This program is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU General Public License as |
9 | published by the Free Software Foundation; either version 2, or (at |
10 | your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, but |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
20 | |
21 | #include <hurd.h> |
22 | #include <stdio.h> |
23 | #include <stdlib.h> |
24 | #include <assert.h> |
25 | #include <pwd.h> |
26 | #include <hurd/resource.h> |
27 | #include <unistd.h> |
28 | #include <string.h> |
29 | #include <timefmt.h> |
30 | #include <sys/time.h> |
31 | |
32 | #include "ps.h" |
33 | #include "common.h" |
34 | |
35 | /* XXX */ |
36 | static char *get_syscall_name (int num) { return 0; } |
37 | static char *get_rpc_name (mach_msg_id_t it) { return 0; } |
38 | |
39 | /* ---------------------------------------------------------------- */ |
40 | /* Getter definitions */ |
41 | |
42 | typedef void (*vf)(); |
43 | |
44 | static int |
45 | ps_get_pid (struct proc_stat *ps) |
46 | { |
47 | return proc_stat_pid (ps)((ps)->pid); |
48 | } |
49 | const struct ps_getter ps_pid_getter = |
50 | {"pid", PSTAT_PID0x00001, (vf) ps_get_pid}; |
51 | |
52 | static int |
53 | ps_get_thread_index (struct proc_stat *ps) |
54 | { |
55 | return proc_stat_thread_index (ps)((ps)->thread_index); |
56 | } |
57 | const struct ps_getter ps_thread_index_getter = |
58 | {"thread_index", PSTAT_THREAD0x00002, (vf) ps_get_thread_index}; |
59 | |
60 | static struct ps_user * |
61 | ps_get_owner (struct proc_stat *ps) |
62 | { |
63 | return proc_stat_owner (ps)((ps)->owner); |
64 | } |
65 | const struct ps_getter ps_owner_getter = |
66 | {"owner", PSTAT_OWNER0x100000, (vf) ps_get_owner}; |
67 | |
68 | static int |
69 | ps_get_owner_uid (struct proc_stat *ps) |
70 | { |
71 | return proc_stat_owner_uid (ps)((ps)->owner_uid); |
72 | } |
73 | const struct ps_getter ps_owner_uid_getter = |
74 | {"uid", PSTAT_OWNER_UID0x200000, (vf) ps_get_owner_uid}; |
75 | |
76 | static int |
77 | ps_get_ppid (struct proc_stat *ps) |
78 | { |
79 | return proc_stat_proc_info (ps)((ps)->proc_info)->ppid; |
80 | } |
81 | const struct ps_getter ps_ppid_getter = |
82 | {"ppid", PSTAT_PROC_INFO0x00020, (vf) ps_get_ppid}; |
83 | |
84 | static int |
85 | ps_get_pgrp (struct proc_stat *ps) |
86 | { |
87 | return proc_stat_proc_info (ps)((ps)->proc_info)->pgrp; |
88 | } |
89 | const struct ps_getter ps_pgrp_getter = |
90 | {"pgrp", PSTAT_PROC_INFO0x00020, (vf) ps_get_pgrp}; |
91 | |
92 | static int |
93 | ps_get_session (struct proc_stat *ps) |
94 | { |
95 | return proc_stat_proc_info (ps)((ps)->proc_info)->session; |
96 | } |
97 | const struct ps_getter ps_session_getter = |
98 | {"session", PSTAT_PROC_INFO0x00020, (vf) ps_get_session}; |
99 | |
100 | static int |
101 | ps_get_login_col (struct proc_stat *ps) |
102 | { |
103 | return proc_stat_proc_info (ps)((ps)->proc_info)->logincollection; |
104 | } |
105 | const struct ps_getter ps_login_col_getter = |
106 | {"login_col", PSTAT_PROC_INFO0x00020, (vf) ps_get_login_col}; |
107 | |
108 | static int |
109 | ps_get_num_threads (struct proc_stat *ps) |
110 | { |
111 | return proc_stat_num_threads (ps)((ps)->num_threads); |
112 | } |
113 | const struct ps_getter ps_num_threads_getter = |
114 | {"num_threads", PSTAT_NUM_THREADS0x00100, (vf)ps_get_num_threads}; |
115 | |
116 | static void |
117 | ps_get_args (struct proc_stat *ps, char **args_p, int *args_len_p) |
118 | { |
119 | *args_p = proc_stat_args (ps)((ps)->args); |
120 | *args_len_p = proc_stat_args_len (ps)((ps)->args_len); |
121 | } |
122 | const struct ps_getter ps_args_getter = |
123 | {"args", PSTAT_ARGS0x02000, ps_get_args}; |
124 | |
125 | static void |
126 | ps_get_env (struct proc_stat *ps, char **env_p, int *env_len_p) |
127 | { |
128 | *env_p = proc_stat_env (ps)((ps)->env); |
129 | *env_len_p = proc_stat_env_len (ps)((ps)->env_len); |
130 | } |
131 | const struct ps_getter ps_env_getter = |
132 | {"env", PSTAT_ENV0x2000000, ps_get_env}; |
133 | |
134 | static int |
135 | ps_get_state (struct proc_stat *ps) |
136 | { |
137 | return proc_stat_state (ps)((ps)->state); |
138 | } |
139 | const struct ps_getter ps_state_getter = |
140 | {"state", PSTAT_STATE0x04000, (vf) ps_get_state}; |
141 | |
142 | static void |
143 | ps_get_wait (struct proc_stat *ps, char **wait, int *rpc) |
144 | { |
145 | *wait = ps->thread_wait; |
146 | *rpc = ps->thread_rpc; |
147 | } |
148 | const struct ps_getter ps_wait_getter = |
149 | {"wait", PSTAT_THREAD_WAIT0x00800, ps_get_wait}; |
150 | |
151 | static size_t |
152 | ps_get_vsize (struct proc_stat *ps) |
153 | { |
154 | return proc_stat_task_basic_info (ps)((ps)->task_basic_info)->virtual_size; |
155 | } |
156 | const struct ps_getter ps_vsize_getter = |
157 | {"vsize", PSTAT_TASK_BASIC0x00040, (vf) ps_get_vsize}; |
158 | |
159 | static size_t |
160 | ps_get_rsize (struct proc_stat *ps) |
161 | { |
162 | return proc_stat_task_basic_info (ps)((ps)->task_basic_info)->resident_size; |
163 | } |
164 | const struct ps_getter ps_rsize_getter = |
165 | {"rsize", PSTAT_TASK_BASIC0x00040, (vf) ps_get_rsize}; |
166 | |
167 | static int |
168 | ps_get_cur_priority (struct proc_stat *ps) |
169 | { |
170 | return proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->cur_priority; |
171 | } |
172 | const struct ps_getter ps_cur_priority_getter = |
173 | {"cur_priority", PSTAT_THREAD_BASIC0x00200, (vf) ps_get_cur_priority}; |
174 | |
175 | static int |
176 | ps_get_base_priority (struct proc_stat *ps) |
177 | { |
178 | return proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->base_priority; |
179 | } |
180 | const struct ps_getter ps_base_priority_getter = |
181 | {"base_priority", PSTAT_THREAD_BASIC0x00200, (vf) ps_get_base_priority}; |
182 | |
183 | static int |
184 | ps_get_max_priority (struct proc_stat *ps) |
185 | { |
186 | return proc_stat_thread_sched_info (ps)((ps)->thread_sched_info)->max_priority; |
187 | } |
188 | const struct ps_getter ps_max_priority_getter = |
189 | {"max_priority", PSTAT_THREAD_SCHED0x00400, (vf) ps_get_max_priority}; |
190 | |
191 | static void |
192 | ps_get_usr_time (struct proc_stat *ps, struct timeval *tv) |
193 | { |
194 | time_value_t tvt = proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->user_time; |
195 | tv->tv_sec = tvt.seconds; |
196 | tv->tv_usec = tvt.microseconds; |
197 | } |
198 | const struct ps_getter ps_usr_time_getter = |
199 | {"usr_time", PSTAT_THREAD_BASIC0x00200, ps_get_usr_time}; |
200 | |
201 | static void |
202 | ps_get_sys_time (struct proc_stat *ps, struct timeval *tv) |
203 | { |
204 | time_value_t tvt = proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->system_time; |
205 | tv->tv_sec = tvt.seconds; |
206 | tv->tv_usec = tvt.microseconds; |
207 | } |
208 | const struct ps_getter ps_sys_time_getter = |
209 | {"sys_time", PSTAT_THREAD_BASIC0x00200, ps_get_sys_time}; |
210 | |
211 | static void |
212 | ps_get_tot_time (struct proc_stat *ps, struct timeval *tv) |
213 | { |
214 | time_value_t tvt = proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->user_time; |
215 | time_value_add (&tvt, &proc_stat_thread_basic_info (ps)->system_time){ (&tvt)->microseconds += (&((ps)->thread_basic_info )->system_time)->microseconds; (&tvt)->seconds += (&((ps)->thread_basic_info)->system_time)->seconds ; if ((&tvt)->microseconds >= (1000000)) { (&tvt )->microseconds -= (1000000); (&tvt)->seconds++; } }; |
216 | tv->tv_sec = tvt.seconds; |
217 | tv->tv_usec = tvt.microseconds; |
218 | } |
219 | const struct ps_getter ps_tot_time_getter = |
220 | {"tot_time", PSTAT_THREAD_BASIC0x00200, ps_get_tot_time}; |
221 | |
222 | static void |
223 | ps_get_start_time (struct proc_stat *ps, struct timeval *tv) |
224 | { |
225 | time_value_t *const tvt = &proc_stat_task_basic_info (ps)((ps)->task_basic_info)->creation_time; |
226 | tv->tv_sec = tvt->seconds; |
227 | tv->tv_usec = tvt->microseconds; |
228 | } |
229 | const struct ps_getter ps_start_time_getter = |
230 | {"start_time", PSTAT_TASK_BASIC0x00040, ps_get_start_time}; |
231 | |
232 | static float |
233 | ps_get_rmem_frac (struct proc_stat *ps) |
234 | { |
235 | static size_t mem_size = 0; |
236 | |
237 | if (mem_size == 0) |
238 | { |
239 | host_basic_info_t info; |
240 | error_t err = ps_host_basic_info (&info); |
241 | if (err == 0) |
242 | mem_size = info->memory_size; |
243 | } |
244 | |
245 | if (mem_size > 0) |
246 | return |
247 | (float)proc_stat_task_basic_info (ps)((ps)->task_basic_info)->resident_size |
248 | / (float)mem_size; |
249 | else |
250 | return 0.0; |
251 | } |
252 | const struct ps_getter ps_rmem_frac_getter = |
253 | {"rmem_frac", PSTAT_TASK_BASIC0x00040, (vf) ps_get_rmem_frac}; |
254 | |
255 | static float |
256 | ps_get_cpu_frac (struct proc_stat *ps) |
257 | { |
258 | return (float) proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->cpu_usage |
259 | / (float) TH_USAGE_SCALE1000; |
260 | } |
261 | const struct ps_getter ps_cpu_frac_getter = |
262 | {"cpu_frac", PSTAT_THREAD_BASIC0x00200, (vf) ps_get_cpu_frac}; |
263 | |
264 | static int |
265 | ps_get_sleep (struct proc_stat *ps) |
266 | { |
267 | return proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->sleep_time; |
268 | } |
269 | const struct ps_getter ps_sleep_getter = |
270 | {"sleep", PSTAT_THREAD_BASIC0x00200, (vf) ps_get_sleep}; |
271 | |
272 | static int |
273 | ps_get_susp_count (struct proc_stat *ps) |
274 | { |
275 | return proc_stat_suspend_count (ps)((ps)->suspend_count); |
276 | } |
277 | const struct ps_getter ps_susp_count_getter = |
278 | {"susp_count", PSTAT_SUSPEND_COUNT0x08000, (vf) ps_get_susp_count}; |
279 | |
280 | static int |
281 | ps_get_proc_susp_count (struct proc_stat *ps) |
282 | { |
283 | return proc_stat_task_basic_info (ps)((ps)->task_basic_info)->suspend_count; |
284 | } |
285 | const struct ps_getter ps_proc_susp_count_getter = |
286 | {"proc_susp_count", PSTAT_TASK_BASIC0x00040, (vf) ps_get_proc_susp_count}; |
287 | |
288 | static int |
289 | ps_get_thread_susp_count (struct proc_stat *ps) |
290 | { |
291 | return proc_stat_thread_basic_info (ps)((ps)->thread_basic_info)->suspend_count; |
292 | } |
293 | const struct ps_getter ps_thread_susp_count_getter = |
294 | {"thread_susp_count", PSTAT_SUSPEND_COUNT0x08000, (vf) ps_get_thread_susp_count}; |
295 | |
296 | static struct ps_tty * |
297 | ps_get_tty (struct proc_stat *ps) |
298 | { |
299 | return proc_stat_tty (ps)((ps)->tty); |
300 | } |
301 | const struct ps_getter ps_tty_getter = |
302 | {"tty", PSTAT_TTY0x80000, (vf)ps_get_tty}; |
303 | |
304 | static int |
305 | ps_get_page_faults (struct proc_stat *ps) |
306 | { |
307 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->faults; |
308 | } |
309 | const struct ps_getter ps_page_faults_getter = |
310 | {"page_faults", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_page_faults}; |
311 | |
312 | static int |
313 | ps_get_cow_faults (struct proc_stat *ps) |
314 | { |
315 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->cow_faults; |
316 | } |
317 | const struct ps_getter ps_cow_faults_getter = |
318 | {"cow_faults", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_cow_faults}; |
319 | |
320 | static int |
321 | ps_get_pageins (struct proc_stat *ps) |
322 | { |
323 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->pageins; |
324 | } |
325 | const struct ps_getter ps_pageins_getter = |
326 | {"pageins", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_pageins}; |
327 | |
328 | static int |
329 | ps_get_msgs_sent (struct proc_stat *ps) |
330 | { |
331 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->messages_sent; |
332 | } |
333 | const struct ps_getter ps_msgs_sent_getter = |
334 | {"msgs_sent", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_msgs_sent}; |
335 | |
336 | static int |
337 | ps_get_msgs_rcvd (struct proc_stat *ps) |
338 | { |
339 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->messages_received; |
340 | } |
341 | const struct ps_getter ps_msgs_rcvd_getter = |
342 | {"msgs_rcvd", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_msgs_rcvd}; |
343 | |
344 | static int |
345 | ps_get_zero_fills (struct proc_stat *ps) |
346 | { |
347 | return proc_stat_task_events_info (ps)((ps)->task_events_info)->zero_fills; |
348 | } |
349 | const struct ps_getter ps_zero_fills_getter = |
350 | {"zero_fills", PSTAT_TASK_EVENTS0x00080, (vf) ps_get_zero_fills}; |
351 | |
352 | static int |
353 | ps_get_num_ports (struct proc_stat *ps) |
354 | { |
355 | return proc_stat_num_ports (ps)((ps)->num_ports); |
356 | } |
357 | const struct ps_getter ps_num_ports_getter = |
358 | {"num_ports", PSTAT_NUM_PORTS0x4000000, (vf) ps_get_num_ports}; |
359 | |
360 | /* ---------------------------------------------------------------- */ |
361 | /* some printing functions */ |
362 | |
363 | /* G () is a helpful macro that just returns the getter G's access function |
364 | cast into a function pointer returning TYPE, as how the function should be |
365 | called varies depending on the getter. */ |
366 | #define G(getter,type)((type (*)())((getter)->fn)) ((type (*)())((getter)->fn)) |
367 | |
368 | /* Similar to G, but takes a fmt field and uses its getter. */ |
369 | #define FG(field,type)((type (*)())((field->spec->getter)->fn)) G(field->spec->getter, type)((type (*)())((field->spec->getter)->fn)) |
370 | |
371 | error_t |
372 | ps_emit_int (struct proc_stat *ps, struct ps_fmt_field *field, |
373 | struct ps_stream *stream) |
374 | { |
375 | return ps_stream_write_int_field (stream, FG (field, int)((int (*)())((field->spec->getter)->fn))(ps), field->width); |
376 | } |
377 | |
378 | error_t |
379 | ps_emit_nz_int (struct proc_stat *ps, struct ps_fmt_field *field, |
380 | struct ps_stream *stream) |
381 | { |
382 | int value = FG (field, int)((int (*)())((field->spec->getter)->fn))(ps); |
383 | if (value) |
384 | return ps_stream_write_int_field (stream, value, field->width); |
385 | else |
386 | return ps_stream_write_field (stream, "-", field->width); |
387 | } |
388 | |
389 | error_t |
390 | ps_emit_priority (struct proc_stat *ps, struct ps_fmt_field *field, |
391 | struct ps_stream *stream) |
392 | { |
393 | return |
394 | ps_stream_write_int_field (stream, |
395 | MACH_PRIORITY_TO_NICE (FG (field, int)(ps))((((int (*)())((field->spec->getter)->fn))(ps)) - 25 ), |
396 | field->width); |
397 | } |
398 | |
399 | error_t |
400 | ps_emit_num_blocks (struct proc_stat *ps, struct ps_fmt_field *field, |
401 | struct ps_stream *stream) |
402 | { |
403 | char buf[20]; |
404 | sprintf(buf, "%d", FG (field, int)((int (*)())((field->spec->getter)->fn))(ps) / 1024); |
405 | return ps_stream_write_field (stream, buf, field->width); |
406 | } |
407 | |
408 | size_t |
409 | sprint_frac_value (char *buf, |
410 | size_t value, int min_value_len, |
411 | size_t frac, int frac_scale, |
412 | int width) |
413 | { |
414 | int value_len = 0; |
415 | int frac_len = 0; |
416 | |
417 | if (value >= 1000) /* the integer part */ |
418 | value_len = 4; /* values 1000-1023 */ |
Value stored to 'value_len' is never read | |
419 | if (value >= 100) |
420 | value_len = 3; |
421 | else if (value >= 10) |
422 | value_len = 2; |
423 | else |
424 | value_len = 1; |
425 | |
426 | while (value_len < min_value_len--) |
427 | *buf++ = '0'; |
428 | |
429 | for (frac_len = frac_scale |
430 | ; frac_len > 0 && (width < value_len + 1 + frac_len || frac % 10 == 0) |
431 | ; frac_len--) |
432 | frac /= 10; |
433 | |
434 | if (frac_len > 0) |
435 | sprintf (buf, "%zd.%0*zd", value, frac_len, frac); |
436 | else |
437 | sprintf (buf, "%zd", value); |
438 | |
439 | return strlen (buf); |
440 | } |
441 | |
442 | error_t |
443 | ps_emit_percent (struct proc_stat *ps, struct ps_fmt_field *field, |
444 | struct ps_stream *stream) |
445 | { |
446 | char buf[20]; |
447 | int width = field->width; |
448 | float perc = FG (field, float)((float (*)())((field->spec->getter)->fn))(ps) * 100; |
449 | |
450 | if (width == 0) |
451 | sprintf (buf, "%g", perc); |
452 | else if (ABS (width)((width) < 0 ? -(width) : (width)) > 3) |
453 | sprintf(buf, "%.*f", ABS (width)((width) < 0 ? -(width) : (width)) - 3, perc); |
454 | else |
455 | sprintf (buf, "%d", (int) perc); |
456 | |
457 | return ps_stream_write_field (stream, buf, width); |
458 | } |
459 | |
460 | /* prints its value nicely */ |
461 | error_t |
462 | ps_emit_nice_size_t (struct proc_stat *ps, struct ps_fmt_field *field, |
463 | struct ps_stream *stream) |
464 | { |
465 | char buf[20]; |
466 | size_t value = FG (field, size_t)((size_t (*)())((field->spec->getter)->fn))(ps); |
467 | char *sfx = " KMG"; |
468 | size_t frac = 0; |
469 | |
470 | while (value >= 1024) |
471 | { |
472 | frac = ((value & 0x3FF) * 1000) >> 10; |
473 | value >>= 10; |
474 | sfx++; |
475 | } |
476 | |
477 | sprintf(buf |
478 | + sprint_frac_value (buf, value, 1, frac, 3, ABS (field->width)((field->width) < 0 ? -(field->width) : (field->width )) - 1), |
479 | "%c", *sfx); |
480 | |
481 | return ps_stream_write_field (stream, buf, field->width); |
482 | } |
483 | |
484 | error_t |
485 | ps_emit_seconds (struct proc_stat *ps, struct ps_fmt_field *field, |
486 | struct ps_stream *stream) |
487 | { |
488 | char buf[20]; |
489 | struct timeval tv; |
490 | int width = field->width, prec = field->precision; |
491 | |
492 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &tv); |
493 | |
494 | if ((field->flags & PS_FMT_FIELD_COLON_MOD0x2) && tv.tv_sec == 0) |
495 | strcpy (buf, "-"); |
496 | else |
497 | fmt_seconds (&tv, !(field->flags & PS_FMT_FIELD_AT_MOD0x1), prec, ABS (width)((width) < 0 ? -(width) : (width)), |
498 | buf, sizeof (buf)); |
499 | |
500 | return ps_stream_write_field (stream, buf, width); |
501 | } |
502 | |
503 | error_t |
504 | ps_emit_minutes (struct proc_stat *ps, struct ps_fmt_field *field, |
505 | struct ps_stream *stream) |
506 | { |
507 | char buf[20]; |
508 | struct timeval tv; |
509 | int width = field->width; |
510 | |
511 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &tv); |
512 | |
513 | if ((field->flags & PS_FMT_FIELD_COLON_MOD0x2) && tv.tv_sec < 60) |
514 | strcpy (buf, "-"); |
515 | else |
516 | fmt_minutes (&tv, !(field->flags & PS_FMT_FIELD_AT_MOD0x1), ABS (width)((width) < 0 ? -(width) : (width)), |
517 | buf, sizeof (buf)); |
518 | |
519 | return ps_stream_write_field (stream, buf, width); |
520 | } |
521 | |
522 | error_t |
523 | ps_emit_past_time (struct proc_stat *ps, struct ps_fmt_field *field, |
524 | struct ps_stream *stream) |
525 | { |
526 | static struct timeval now; |
527 | char buf[20]; |
528 | struct timeval tv; |
529 | int width = field->width; |
530 | |
531 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &tv); |
532 | |
533 | if (now.tv_sec == 0 && gettimeofday (&now, 0) < 0) |
534 | return errno(*__errno_location ()); |
535 | |
536 | fmt_past_time (&tv, &now, ABS (width)((width) < 0 ? -(width) : (width)), buf, sizeof buf); |
537 | |
538 | return ps_stream_write_field (stream, buf, width); |
539 | } |
540 | |
541 | error_t |
542 | ps_emit_uid (struct proc_stat *ps, struct ps_fmt_field *field, |
543 | struct ps_stream *stream) |
544 | { |
545 | int uid = FG (field, int)((int (*)())((field->spec->getter)->fn))(ps); |
546 | if (uid < 0) |
547 | return ps_stream_write_field (stream, "-", field->width); |
548 | else |
549 | return ps_stream_write_int_field (stream, uid, field->width); |
550 | } |
551 | |
552 | error_t |
553 | ps_emit_uname (struct proc_stat *ps, struct ps_fmt_field *field, |
554 | struct ps_stream *stream) |
555 | { |
556 | int width = field->width; |
557 | struct ps_user *u = FG (field, struct ps_user *)((struct ps_user * (*)())((field->spec->getter)->fn) )(ps); |
558 | if (u) |
559 | { |
560 | struct passwd *pw = ps_user_passwd (u); |
561 | if (pw == NULL((void*)0)) |
562 | return ps_stream_write_int_field (stream, ps_user_uid (u)((u)->uid), width); |
563 | else |
564 | return ps_stream_write_field (stream, pw->pw_name, width); |
565 | } |
566 | else |
567 | return ps_stream_write_field (stream, "-", width); |
568 | } |
569 | |
570 | error_t |
571 | ps_emit_user_name (struct proc_stat *ps, struct ps_fmt_field *field, |
572 | struct ps_stream *stream) |
573 | { |
574 | int width = field->width; |
575 | struct ps_user *u = FG (field, struct ps_user *)((struct ps_user * (*)())((field->spec->getter)->fn) )(ps); |
576 | if (u) |
577 | { |
578 | struct passwd *pw = ps_user_passwd (u); |
579 | if (pw == NULL((void*)0)) |
580 | { |
581 | char buf[20]; |
582 | sprintf (buf, "(UID %d)", u->uid); |
583 | return ps_stream_write_field (stream, buf, width); |
584 | } |
585 | else |
586 | return ps_stream_write_field (stream, pw->pw_gecos, width); |
587 | } |
588 | else |
589 | return ps_stream_write_field (stream, "-", width); |
590 | } |
591 | |
592 | /* prints a string with embedded nuls as spaces */ |
593 | error_t |
594 | ps_emit_args (struct proc_stat *ps, struct ps_fmt_field *field, |
595 | struct ps_stream *stream) |
596 | { |
597 | char *s0, *p, *q; |
598 | int s0len; |
599 | int width = field->width; |
600 | int fwidth = ABS (width)((width) < 0 ? -(width) : (width)); |
601 | char static_buf[200]; |
602 | char *buf = static_buf; |
603 | |
604 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &s0, &s0len); |
605 | |
606 | if (!s0 || s0len == 0 ) |
607 | strcpy (buf, "-"); |
608 | else |
609 | { |
610 | if (s0len > sizeof static_buf) |
611 | { |
612 | buf = malloc (s0len + 1); |
613 | if (buf == NULL((void*)0)) |
614 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
615 | } |
616 | |
617 | if (fwidth == 0 || fwidth > s0len) |
618 | fwidth = s0len; |
619 | |
620 | for (p = buf, q = s0; fwidth-- > 0; p++, q++) |
621 | { |
622 | int ch = *q; |
623 | *p = (ch == '\0' ? ' ' : ch); |
624 | } |
625 | if (q > s0 && *(q - 1) == '\0') |
626 | *--p = '\0'; |
627 | else |
628 | *p = '\0'; |
629 | } |
630 | |
631 | { |
632 | error_t err = ps_stream_write_trunc_field (stream, buf, width); |
633 | if (buf != static_buf) |
634 | free (buf); |
635 | return err; |
636 | } |
637 | } |
638 | |
639 | error_t |
640 | ps_emit_string (struct proc_stat *ps, struct ps_fmt_field *field, |
641 | struct ps_stream *stream) |
642 | { |
643 | char *str; |
644 | int len; |
645 | |
646 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &str, &len); |
647 | |
648 | if (!str || len == 0) |
649 | str = "-"; |
650 | |
651 | return ps_stream_write_trunc_field (stream, str, field->width); |
652 | } |
653 | |
654 | error_t |
655 | ps_emit_tty_name (struct proc_stat *ps, struct ps_fmt_field *field, |
656 | struct ps_stream *stream) |
657 | { |
658 | const char *name = "-"; |
659 | struct ps_tty *tty = FG (field, struct ps_tty *)((struct ps_tty * (*)())((field->spec->getter)->fn))(ps); |
660 | |
661 | if (tty) |
662 | { |
663 | name = ps_tty_short_name (tty); |
664 | if (name == NULL((void*)0) || *name == '\0') |
665 | name = "?"; |
666 | } |
667 | |
668 | return ps_stream_write_field (stream, name, field->width); |
669 | } |
670 | |
671 | struct state_shadow |
672 | { |
673 | /* If any states in STATES are set, the states in shadow are suppressed. */ |
674 | int states; |
675 | int shadow; |
676 | }; |
677 | |
678 | static const struct state_shadow |
679 | state_shadows[] = { |
680 | /* If the process has no parent, it's not a hurd process, and various hurd |
681 | process bits are likely to be noise, so turn them off (but leave the |
682 | noparent bit on). */ |
683 | { PSTAT_STATE_P_NOPARENT0x08000, (PSTAT_STATE_P_ATTRS(0x00400 | 0x00800 | 0x01000 | 0x02000 | 0x04000 | 0x08000 | 0x10000 | 0x20000 | 0x40000 | 0x80000) & ~PSTAT_STATE_P_NOPARENT0x08000) }, |
684 | /* Don't show sleeping thread if one is running, or the process is stopped.*/ |
685 | { PSTAT_STATE_T_RUN0x00004 | PSTAT_STATE_P_STOP0x00001, |
686 | PSTAT_STATE_T_SLEEP0x00020 | PSTAT_STATE_T_IDLE0x00040 | PSTAT_STATE_T_WAIT0x00010 }, |
687 | /* Only show the longest sleep. */ |
688 | { PSTAT_STATE_T_IDLE0x00040, PSTAT_STATE_T_SLEEP0x00020 | PSTAT_STATE_T_WAIT0x00010 }, |
689 | { PSTAT_STATE_T_SLEEP0x00020, PSTAT_STATE_T_WAIT0x00010 }, |
690 | /* Turn off the thread stop bits if any thread is not stopped. This is |
691 | generally reasonable, as threads are often suspended to be frobed; if |
692 | they're all suspended, then something's odd (probably in the debugger, |
693 | or crashed). */ |
694 | { PSTAT_STATE_T_STATES(0x00004 | 0x00008 | 0x00010 | 0x00020 | 0x00040) & ~PSTAT_STATE_T_HALT0x00008, |
695 | PSTAT_STATE_T_HALT0x00008 | PSTAT_STATE_T_UNCLEAN0x00200 }, |
696 | { 0 } |
697 | }; |
698 | |
699 | error_t |
700 | ps_emit_state (struct proc_stat *ps, struct ps_fmt_field *field, |
701 | struct ps_stream *stream) |
702 | { |
703 | char *tags; |
704 | int raw_state = FG (field, int)((int (*)())((field->spec->getter)->fn))(ps); |
705 | int state = raw_state; |
706 | char buf[20], *p = buf; |
707 | const struct state_shadow *shadow = state_shadows; |
708 | |
709 | while (shadow->states) |
710 | { |
711 | if (raw_state & shadow->states) |
712 | state &= ~shadow->shadow; |
713 | shadow++; |
714 | } |
715 | |
716 | for (tags = proc_stat_state_tags |
717 | ; state != 0 && *tags != '\0' |
718 | ; state >>= 1, tags++) |
719 | if (state & 1) |
720 | *p++ = *tags; |
721 | |
722 | *p = '\0'; |
723 | |
724 | return ps_stream_write_field (stream, buf, field->width); |
725 | } |
726 | |
727 | error_t |
728 | ps_emit_wait (struct proc_stat *ps, struct ps_fmt_field *field, |
729 | struct ps_stream *stream) |
730 | { |
731 | int rpc; |
732 | char *wait; |
733 | char buf[80]; |
734 | |
735 | FG (field, void)((void (*)())((field->spec->getter)->fn))(ps, &wait, &rpc); |
736 | |
737 | if (wait == 0) |
738 | return ps_stream_write_field (stream, "?", field->width); |
739 | else if (*wait == 0) |
740 | return ps_stream_write_field (stream, "-", field->width); |
741 | else if (strcmp (wait, "kernel") == 0) |
742 | /* A syscall. RPC is actually the syscall number. */ |
743 | { |
744 | char *name = get_syscall_name (rpc); |
745 | if (! name) |
746 | { |
747 | sprintf (buf, "syscall:%d", -rpc); |
748 | name = buf; |
749 | } |
750 | return ps_stream_write_field (stream, name, field->width); |
751 | } |
752 | else if (rpc) |
753 | /* An rpc (with msg id RPC); WAIT describes the dest port. */ |
754 | { |
755 | char port_name_buf[20]; |
756 | char *name = get_rpc_name (rpc); |
757 | |
758 | /* See if we should give a more useful name for the port. */ |
759 | if (strcmp (wait, "init#0") == 0) |
760 | wait = "cwd"; /* Current directory */ |
761 | else if (strcmp (wait, "init#1") == 0) |
762 | wait = "root"; /* Root directory */ |
763 | else if (strcmp (wait, "init#2") == 0) |
764 | wait = "auth"; /* Auth port */ |
765 | else if (strcmp (wait, "init#3") == 0) |
766 | wait = "proc"; /* Proc port */ |
767 | else if (strcmp (wait, "init#4") == 0) |
768 | wait = "cttyid"; /* Ctty id port */ |
769 | else if (strcmp (wait, "init#5") == 0) |
770 | wait = "boot"; /* Bootstrap port */ |
771 | else |
772 | /* See if we can shorten the name to fit better. */ |
773 | { |
774 | char *abbrev = 0, *num = 0; |
775 | if (strncmp (wait, "fd#", 3) == 0) |
776 | abbrev = "fd", num = wait + 3; |
777 | else if (strncmp (wait, "bgfd#", 5) == 0) |
778 | abbrev = "bg", num = wait + 5; |
779 | else if (strncmp (wait, "port#", 5) == 0) |
780 | abbrev = "", num = wait + 5; |
781 | if (abbrev) |
782 | { |
783 | snprintf (port_name_buf, sizeof port_name_buf, |
784 | "%s%s", abbrev, num); |
785 | wait = port_name_buf; |
786 | } |
787 | } |
788 | |
789 | if (name) |
790 | snprintf (buf, sizeof buf, "%s:%s", wait, name); |
791 | else |
792 | snprintf (buf, sizeof buf, "%s:%d", wait, rpc); |
793 | |
794 | return ps_stream_write_field (stream, buf, field->width); |
795 | } |
796 | else |
797 | return ps_stream_write_field (stream, wait, field->width); |
798 | } |
799 | /* ---------------------------------------------------------------- */ |
800 | /* comparison functions */ |
801 | |
802 | /* Evaluates CALL if both s1 & s2 are non-NULL, and otherwise returns -1, 0, |
803 | or 1 ala strcmp, considering NULL to be less than non-NULL. */ |
804 | #define GUARDED_CMP(s1, s2, call)((s1) == ((void*)0) ? (((s2) == ((void*)0)) ? 0 : -1) : ((s2) == ((void*)0) ? 1 : (call))) \ |
805 | ((s1) == NULL((void*)0) ? (((s2) == NULL((void*)0)) ? 0 : -1) : ((s2) == NULL((void*)0) ? 1 : (call))) |
806 | |
807 | int |
808 | ps_cmp_ints (struct proc_stat *ps1, struct proc_stat *ps2, |
809 | const struct ps_getter *getter) |
810 | { |
811 | int (*gf)() = G (getter, int)((int (*)())((getter)->fn)); |
812 | int v1 = gf(ps1), v2 = gf (ps2); |
813 | return v1 == v2 ? 0 : v1 < v2 ? -1 : 1; |
814 | } |
815 | |
816 | int |
817 | ps_cmp_floats (struct proc_stat *ps1, struct proc_stat *ps2, |
818 | const struct ps_getter *getter) |
819 | { |
820 | float (*gf)() = G (getter, float)((float (*)())((getter)->fn)); |
821 | float v1 = gf(ps1), v2 = gf (ps2); |
822 | return v1 == v2 ? 0 : v1 < v2 ? -1 : 1; |
823 | } |
824 | |
825 | int |
826 | ps_cmp_size_ts (struct proc_stat *ps1, struct proc_stat *ps2, |
827 | const struct ps_getter *getter) |
828 | { |
829 | size_t (*gf)() = G (getter, size_t)((size_t (*)())((getter)->fn)); |
830 | size_t v1 = gf(ps1), v2 = gf (ps2); |
831 | return v1 == v2 ? 0 : v1 < v2 ? -1 : 1; |
832 | } |
833 | |
834 | int |
835 | ps_cmp_uids (struct proc_stat *ps1, struct proc_stat *ps2, |
836 | const struct ps_getter *getter) |
837 | { |
838 | struct ps_user *(*gf)() = G (getter, struct ps_user *)((struct ps_user * (*)())((getter)->fn)); |
839 | struct ps_user *u1 = gf (ps1), *u2 = gf (ps2); |
840 | return (u1 ? ps_user_uid (u1)((u1)->uid) : -1) - (u2 ? ps_user_uid (u2)((u2)->uid) : -1); |
841 | } |
842 | |
843 | int |
844 | ps_cmp_unames (struct proc_stat *ps1, struct proc_stat *ps2, |
845 | const struct ps_getter *getter) |
846 | { |
847 | struct ps_user *(*gf)() = G (getter, struct ps_user *)((struct ps_user * (*)())((getter)->fn)); |
848 | struct ps_user *u1 = gf (ps1), *u2 = gf (ps2); |
849 | struct passwd *pw1 = u1 ? ps_user_passwd (u1) : 0; |
850 | struct passwd *pw2 = u2 ? ps_user_passwd (u2) : 0; |
851 | return GUARDED_CMP (pw1, pw2, strcmp (pw1->pw_name, pw2->pw_name))((pw1) == ((void*)0) ? (((pw2) == ((void*)0)) ? 0 : -1) : ((pw2 ) == ((void*)0) ? 1 : (strcmp (pw1->pw_name, pw2->pw_name )))); |
852 | } |
853 | |
854 | int |
855 | ps_cmp_strings (struct proc_stat *ps1, struct proc_stat *ps2, |
856 | const struct ps_getter *getter) |
857 | { |
858 | void (*gf)() = G (getter, void)((void (*)())((getter)->fn)); |
859 | char *s1, *s2; |
860 | int s1len, s2len; |
861 | |
862 | /* Get both strings */ |
863 | gf (ps1, &s1, &s1len); |
864 | gf (ps2, &s2, &s2len); |
865 | |
866 | return GUARDED_CMP(s1, s2, strncmp(s1, s2, MIN (s1len, s2len)))((s1) == ((void*)0) ? (((s2) == ((void*)0)) ? 0 : -1) : ((s2) == ((void*)0) ? 1 : (strncmp(s1, s2, ((s1len) < (s2len) ? (s1len) : (s2len)))))); |
867 | } |
868 | |
869 | int |
870 | ps_cmp_times (struct proc_stat *ps1, struct proc_stat *ps2, |
871 | const struct ps_getter *getter) |
872 | { |
873 | void (*g)() = G (getter, void)((void (*)())((getter)->fn)); |
874 | struct timeval tv1, tv2; |
875 | |
876 | g (ps1, &tv1); |
877 | g (ps2, &tv2); |
878 | |
879 | return |
880 | tv1.tv_sec > tv2.tv_sec ? 1 |
881 | : tv1.tv_sec < tv2.tv_sec ? -1 |
882 | : tv1.tv_usec > tv2.tv_usec ? 1 |
883 | : tv2.tv_usec < tv2.tv_usec ? -1 |
884 | : 0; |
885 | } |
886 | |
887 | /* ---------------------------------------------------------------- */ |
888 | /* `Nominal' functions -- return true for `unexciting' values. */ |
889 | |
890 | /* For many things, zero is not so interesting. */ |
891 | int |
892 | ps_nominal_zint (struct proc_stat *ps, const struct ps_getter *getter) |
893 | { |
894 | return G (getter, int)((int (*)())((getter)->fn))(ps) == 0; |
895 | } |
896 | |
897 | /* Neither is an empty string. */ |
898 | int |
899 | ps_nominal_string (struct proc_stat *ps, const struct ps_getter *getter) |
900 | { |
901 | char *str; |
902 | size_t len; |
903 | G (getter, char *)((char * (*)())((getter)->fn))(ps, &str, &len); |
904 | return !str || len == 0 || (len == 1 && *str == '-'); |
905 | } |
906 | |
907 | /* Priorities are similar, but have to be converted to the unix nice scale |
908 | first. */ |
909 | int |
910 | ps_nominal_pri (struct proc_stat *ps, const struct ps_getter *getter) |
911 | { |
912 | return MACH_PRIORITY_TO_NICE(G (getter, int)(ps))((((int (*)())((getter)->fn))(ps)) - 25) == 0; |
913 | } |
914 | |
915 | /* Hurd processes usually have 2 threads; XXX is there someplace we get get |
916 | this number from? */ |
917 | int |
918 | ps_nominal_nth (struct proc_stat *ps, const struct ps_getter *getter) |
919 | { |
920 | return G (getter, int)((int (*)())((getter)->fn))(ps) == 2; |
921 | } |
922 | |
923 | static int own_uid = -2; /* -1 means no uid at all. */ |
924 | |
925 | /* A user is nominal if it's the current user. */ |
926 | int |
927 | ps_nominal_user (struct proc_stat *ps, const struct ps_getter *getter) |
928 | { |
929 | struct ps_user *u = G (getter, struct ps_user *)((struct ps_user * (*)())((getter)->fn))(ps); |
930 | if (own_uid == -2) |
931 | own_uid = getuid (); |
932 | return own_uid >= 0 && u && u->uid == own_uid; |
933 | } |
934 | |
935 | /* A uid is nominal if it's that of the current user. */ |
936 | int |
937 | ps_nominal_uid (struct proc_stat *ps, const struct ps_getter *getter) |
938 | { |
939 | uid_t uid = G (getter, uid_t)((uid_t (*)())((getter)->fn))(ps); |
940 | if (own_uid == -2) |
941 | own_uid = getuid (); |
942 | return own_uid >= 0 && uid == own_uid; |
943 | } |
944 | |
945 | /* ---------------------------------------------------------------- */ |
946 | |
947 | /* Returns the first entry called NAME in the vector of fmt_specs SPECS. If |
948 | the result is in fact an alias entry, returns in ALIASED_TO the name of |
949 | the desired source. */ |
950 | static const struct ps_fmt_spec * |
951 | specv_find (const struct ps_fmt_spec *specs, const char *name, |
952 | char **aliased_to) |
953 | { |
954 | while (! ps_fmt_spec_is_end (specs)((specs)->name == ((void*)0))) |
955 | { |
956 | char *alias = index (specs->name, '='); |
957 | if (alias) |
958 | { |
959 | unsigned name_len = strlen (name); |
960 | |
961 | if (name_len == alias - specs->name |
962 | && strncasecmp (name, specs->name, name_len) == 0) |
963 | /* SPECS is an alias, lookup what it refs to. */ |
964 | { |
965 | *aliased_to = alias + 1; |
966 | return specs; |
967 | } |
968 | } |
969 | else |
970 | if (strcasecmp (specs->name, name) == 0) |
971 | return specs; |
972 | specs++; |
973 | } |
974 | |
975 | return 0; |
976 | } |
977 | |
978 | /* Number of specs allocated in each block of expansions. */ |
979 | #define EXP_BLOCK_SIZE20 20 |
980 | |
981 | /* A node in a linked list of spec vectors. */ |
982 | struct ps_fmt_spec_block |
983 | { |
984 | struct ps_fmt_spec_block *next; |
985 | struct ps_fmt_spec specs[EXP_BLOCK_SIZE20]; |
986 | }; |
987 | |
988 | /* Adds a new alias expansion, using fields from ALIAS, where non-zero, |
989 | otherwise SRC, to SPECS. */ |
990 | struct ps_fmt_spec * |
991 | specs_add_alias (struct ps_fmt_specs *specs, |
992 | const struct ps_fmt_spec *alias, |
993 | const struct ps_fmt_spec *src) |
994 | { |
995 | struct ps_fmt_spec *exp; |
996 | struct ps_fmt_spec_block *block; |
997 | char *name_end = index (alias->name, '='); |
998 | size_t name_len = name_end ? name_end - alias->name : strlen (alias->name); |
999 | |
1000 | for (block = specs->expansions; block; block = block->next) |
1001 | { |
1002 | exp = block->specs; |
1003 | while (! ps_fmt_spec_is_end (exp)((exp)->name == ((void*)0))) |
1004 | exp++; |
1005 | if (exp + 1 < block->specs + EXP_BLOCK_SIZE20) |
1006 | /* Found some empty space at EXP. */ |
1007 | break; |
1008 | } |
1009 | |
1010 | if (! block) |
1011 | /* Ran out of blocks, we gotta make a new one. */ |
1012 | { |
1013 | block = malloc (sizeof (struct ps_fmt_spec_block)); |
1014 | if (! block) |
1015 | return 0; |
1016 | block->next = specs->expansions; |
1017 | specs->expansions = block; |
1018 | exp = block->specs; |
1019 | } |
1020 | |
1021 | /* EXP gets its name from ALIAS, but only the bit before the alias marker. */ |
1022 | exp->name = malloc (name_len + 1); |
1023 | if (! exp->name) |
1024 | return 0; |
1025 | bcopy ((char *)alias->name, (char *)exp->name, name_len); |
1026 | ((char *)exp->name)[name_len] = '\0'; |
1027 | |
1028 | /* Copy the rest of the fields from ALIAS, but defaulting to SRC. */ |
1029 | exp->title = alias->title ?: src->title; |
1030 | exp->width = alias->width ?: src->width; |
1031 | exp->precision = alias->precision >= 0 ? alias->precision : src->precision; |
1032 | exp->flags = src->flags ^ alias->flags; |
1033 | exp->getter = alias->getter ?: src->getter; |
1034 | exp->output_fn = alias->output_fn ?: src->output_fn; |
1035 | exp->cmp_fn = alias->cmp_fn ?: src->cmp_fn; |
1036 | exp->nominal_fn = alias->nominal_fn ?: src->nominal_fn; |
1037 | |
1038 | /* Now add the list-end marker. */ |
1039 | bzero (exp + 1, sizeof (*exp)); |
1040 | |
1041 | return exp; |
1042 | } |
1043 | |
1044 | const struct ps_fmt_spec * |
1045 | ps_fmt_specs_find (struct ps_fmt_specs *specs, const char *name) |
1046 | { |
1047 | if (specs) /* Allow NULL to make recursion more handy. */ |
1048 | { |
1049 | struct ps_fmt_spec_block *block; |
1050 | char *aliased_to = 0; |
1051 | const struct ps_fmt_spec *s = 0; |
1052 | |
1053 | /* If SPECS contains any alias expansions, look there first. */ |
1054 | for (block = specs->expansions; block && !s; block = block->next) |
1055 | s = specv_find (block->specs, name, &aliased_to); |
1056 | |
1057 | if (! s) |
1058 | /* Look in the local list of specs. */ |
1059 | s = specv_find (specs->specs, name, &aliased_to); |
1060 | |
1061 | if (s) |
1062 | { |
1063 | if (aliased_to) |
1064 | { |
1065 | const struct ps_fmt_spec *src; /* What S is an alias to. */ |
1066 | |
1067 | if (strcasecmp (name, aliased_to) == 0) |
1068 | /* An alias to the same name (useful to just change some |
1069 | property) -- start looking up in the parent. */ |
1070 | src = ps_fmt_specs_find (specs->parent, aliased_to); |
1071 | else |
1072 | src = ps_fmt_specs_find (specs, aliased_to); |
1073 | |
1074 | if (! src) |
1075 | return 0; |
1076 | |
1077 | s = specs_add_alias (specs, s, src); |
1078 | } |
1079 | } |
1080 | else |
1081 | /* Try again with our parent. */ |
1082 | s = ps_fmt_specs_find (specs->parent, name); |
1083 | |
1084 | return s; |
1085 | } |
1086 | else |
1087 | return 0; |
1088 | } |
1089 | |
1090 | /* ---------------------------------------------------------------- */ |
1091 | |
1092 | static const struct ps_fmt_spec specs[] = |
1093 | { |
1094 | {"PID", 0, -5, -1, 0, |
1095 | &ps_pid_getter, ps_emit_int, ps_cmp_ints, 0}, |
1096 | {"TH", "TH#", -2, -1, 0, |
1097 | &ps_thread_index_getter,ps_emit_int, ps_cmp_ints, 0}, |
1098 | {"PPID", 0, -5, -1, 0, |
1099 | &ps_ppid_getter, ps_emit_int, ps_cmp_ints, 0}, |
1100 | {"UID", 0, -4, -1, PS_FMT_FIELD_KEEP0x4, |
1101 | &ps_owner_uid_getter, ps_emit_uid, ps_cmp_ints, ps_nominal_uid}, |
1102 | {"User", 0, 8, -1, PS_FMT_FIELD_KEEP0x4, |
1103 | &ps_owner_getter, ps_emit_uname, ps_cmp_unames, ps_nominal_user}, |
1104 | {"NTh", 0, -2, -1, 0, |
1105 | &ps_num_threads_getter, ps_emit_int, ps_cmp_ints, ps_nominal_nth}, |
1106 | {"PGrp", 0, -5, -1, 0, |
1107 | &ps_pgrp_getter, ps_emit_int, ps_cmp_ints, 0}, |
1108 | {"Sess", 0, -5, -1, 0, |
1109 | &ps_session_getter, ps_emit_int, ps_cmp_ints, 0}, |
1110 | {"LColl", 0, -5, -1, 0, |
1111 | &ps_login_col_getter, ps_emit_int, ps_cmp_ints, 0}, |
1112 | {"Args", 0, 0, -1, 0, |
1113 | &ps_args_getter, ps_emit_args, ps_cmp_strings,ps_nominal_string}, |
1114 | {"Arg0", 0, 0, -1, 0, |
1115 | &ps_args_getter, ps_emit_string, ps_cmp_strings,ps_nominal_string}, |
1116 | {"Env", 0, 0, -1, 0, |
1117 | &ps_env_getter, ps_emit_args, ps_cmp_strings,ps_nominal_string}, |
1118 | {"Start", 0, -7, 1, 0, |
1119 | &ps_start_time_getter, ps_emit_past_time, ps_cmp_times,0}, |
1120 | {"Time", 0, -8, 2, 0, |
1121 | &ps_tot_time_getter, ps_emit_seconds, ps_cmp_times, 0}, |
1122 | {"UTime", 0, -8, 2, 0, |
1123 | &ps_usr_time_getter, ps_emit_seconds, ps_cmp_times, 0}, |
1124 | {"STime", 0, -8, 2, 0, |
1125 | &ps_sys_time_getter, ps_emit_seconds, ps_cmp_times, 0}, |
1126 | {"VSize", 0, -5, -1, 0, |
1127 | &ps_vsize_getter, ps_emit_nice_size_t,ps_cmp_size_ts, 0}, |
1128 | {"RSize", 0, -5, -1, 0, |
1129 | &ps_rsize_getter, ps_emit_nice_size_t,ps_cmp_size_ts, 0}, |
1130 | {"Pri", 0, -3, -1, 0, |
1131 | &ps_cur_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, |
1132 | {"BPri", 0, -3, -1, 0, |
1133 | &ps_base_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, |
1134 | {"MPri", 0, -3, -1, 0, |
1135 | &ps_max_priority_getter,ps_emit_priority,ps_cmp_ints, ps_nominal_pri}, |
1136 | {"Mem", "%Mem", -4, -1, 0, |
1137 | &ps_rmem_frac_getter, ps_emit_percent, ps_cmp_floats, 0}, |
1138 | {"CPU", "%CPU", -4, -1, 0, |
1139 | &ps_cpu_frac_getter, ps_emit_percent, ps_cmp_floats, 0}, |
1140 | {"State", 0, 4, -1, 0, |
1141 | &ps_state_getter, ps_emit_state, 0, 0}, |
1142 | {"Wait", 0, 10, -1, 0, |
1143 | &ps_wait_getter, ps_emit_wait, 0, 0}, |
1144 | {"Sleep", 0, -2, -1, 0, |
1145 | &ps_sleep_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1146 | {"Susp", 0, -2, -1, 0, |
1147 | &ps_susp_count_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1148 | {"PSusp", 0, -2, -1, 0, |
1149 | &ps_proc_susp_count_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1150 | {"TSusp", 0, -2, -1, 0, |
1151 | &ps_thread_susp_count_getter, ps_emit_int,ps_cmp_ints, ps_nominal_zint}, |
1152 | {"TTY", 0, -2, -1, 0, |
1153 | &ps_tty_getter, ps_emit_tty_name,ps_cmp_strings,0}, |
1154 | {"PgFlts", 0, -5, -1, 0, |
1155 | &ps_page_faults_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1156 | {"COWFlts", 0, -5, -1, 0, |
1157 | &ps_cow_faults_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1158 | {"PgIns", 0, -5, -1, 0, |
1159 | &ps_pageins_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1160 | {"MsgIn", 0, -5, -1, 0, |
1161 | &ps_msgs_rcvd_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1162 | {"MsgOut", 0, -5, -1, 0, |
1163 | &ps_msgs_sent_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1164 | {"ZFills", 0, -5, -1, 0, |
1165 | &ps_zero_fills_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint}, |
1166 | {"Ports", 0, -5, -1, 0, |
1167 | &ps_num_ports_getter, ps_emit_int, ps_cmp_ints, 0}, |
1168 | {0} |
1169 | }; |
1170 | |
1171 | struct ps_fmt_specs ps_std_fmt_specs = { specs, 0 }; |