ps: exploit those new <pids> task/threads capabilities
This commit represents the ps transition to the <pids> 'stacks' interface. While an effort to minimize impact on existing code was made (as with a disguised proc_t) the changes were still extensive. Along the way, a few modifications beyond simply conversion were also made. ------------------------------------------------------ Here's a brief overview the design of this conversion: . The need to satisfy relative enum requirements could not easily have been made table driven since any entry in the format_array might require several <pids> items in support. So I decided to allow every print function to contribute its own relative enums once the decision as to exactly what will be printed had been finalized. . A similar approach was taken for sorting, since it's possible to have sort keys that will not be displayed. Here, I relied on the existing print extensions above. . In summary, just prior to printing ps walks thru two lists one time (the format_list & sort_list) and calls each print function. That function does not print, but sets its required enum if necessary. Later, when those same functions are called repeatedly for every printed line, the only overhead will be an if test and branch. ------------------------------------------------------ Below is a summary of major changes beyond conversion: . Sorts are now the responsibility of the library. And therefore the total # of sortable fields substantially increased without effort. Additionally, several quirky fields remain as sortable, even though they can't ever be printed(?). Surely that must make sense to someone. [ while on this subject of sort, please do *not* try ] [ to sort old ps on 'args'. or better yet, if you do ] [ try that sort, see if you can determine his order, ] [ without peeking at the source. that one hurts yet! ] . All logic dealing with the old openproc flags and ps struct members known as 'need' have been whacked since that entire area was solely the new library's concern. . Remaining malloc/calloc calls to stdlib were changed to xmalloc/xcalloc from our own include/xalloc.h file. None of the replaced calls ever checked return values. [ be aware that 2 minor potential memory leaks exist ] [ depending on command line arguments. no attempt is ] [ made to free dynamically acquired format/sort node ] [ structures upon return; a conscious design choice. ] Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
468c15caa6
commit
584028dbe5
159
ps/common.h
159
ps/common.h
@ -13,9 +13,147 @@
|
||||
#define PROCPS_PS_H
|
||||
|
||||
#include "../include/nls.h"
|
||||
#include "../proc/procps.h"
|
||||
#include "../proc/escape.h"
|
||||
#include "../proc/readproc.h"
|
||||
|
||||
// --- <pids> interface begin |||||\||||||||||||||||||||||||||||||||||||||
|
||||
// -----------------------------------------------------------------------
|
||||
#include <proc/pids.h>
|
||||
|
||||
// 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) PROCPS_PIDS_VAL(rel_ ## E, T, S)
|
||||
|
||||
#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] = PROCPS_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; \
|
||||
} }
|
||||
|
||||
extern struct procps_pidsinfo *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_END_CODE)
|
||||
makEXT(ADDR_KSTK_EIP)
|
||||
makEXT(ADDR_KSTK_ESP)
|
||||
makEXT(ADDR_START_CODE)
|
||||
makEXT(ADDR_START_STACK)
|
||||
makEXT(ALARM)
|
||||
makEXT(CGROUP)
|
||||
makEXT(CMD)
|
||||
makEXT(CMDLINE)
|
||||
makEXT(ENVIRON)
|
||||
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_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(LXCNAME)
|
||||
makEXT(NICE)
|
||||
makEXT(NLWP)
|
||||
makEXT(NS_IPC)
|
||||
makEXT(NS_MNT)
|
||||
makEXT(NS_NET)
|
||||
makEXT(NS_PID)
|
||||
makEXT(NS_USER)
|
||||
makEXT(NS_UTS)
|
||||
makEXT(PRIORITY)
|
||||
makEXT(PROCESSOR)
|
||||
makEXT(RSS)
|
||||
makEXT(RSS_RLIM)
|
||||
makEXT(RTPRIO)
|
||||
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(STATE)
|
||||
makEXT(SUPGIDS)
|
||||
makEXT(SUPGROUPS)
|
||||
makEXT(TICS_ALL)
|
||||
makEXT(TICS_ALL_C)
|
||||
makEXT(TIME_ALL)
|
||||
makEXT(TIME_ELAPSED)
|
||||
makEXT(TIME_START)
|
||||
makEXT(TTY)
|
||||
makEXT(TTY_NAME)
|
||||
makEXT(TTY_NUMBER)
|
||||
makEXT(VM_DATA)
|
||||
makEXT(VM_LOCK)
|
||||
makEXT(VM_RSS)
|
||||
makEXT(VM_SIZE)
|
||||
makEXT(VM_STACK)
|
||||
makEXT(VSIZE_PGS)
|
||||
makEXT(WCHAN_ADDR)
|
||||
makEXT(WCHAN_NAME)
|
||||
makEXT(extra)
|
||||
makEXT(noop)
|
||||
// -----------------------------------------------------------------------
|
||||
// --- <pids> interface end ||||||||||||||||||||||||||||||||||||||||||||||
|
||||
|
||||
|
||||
#if 0
|
||||
#define trace(...) printf(## __VA_ARGS__)
|
||||
@ -94,8 +232,6 @@
|
||||
#define CF_PRINT_AS_NEEDED 0x80000000 // means we have no clue, so assume EVERY TIME
|
||||
#define CF_PRINT_MASK 0xf0000000
|
||||
|
||||
#define needs_for_select (PROC_FILLSTAT | PROC_FILLSTATUS)
|
||||
|
||||
/* thread_flags */
|
||||
#define TF_B_H 0x0001
|
||||
#define TF_B_m 0x0002
|
||||
@ -201,19 +337,17 @@ typedef struct selection_node {
|
||||
|
||||
typedef struct sort_node {
|
||||
struct sort_node *next;
|
||||
int (*sr)(const proc_t* P, const proc_t* Q); /* sort function */
|
||||
int reverse; /* can sort backwards */
|
||||
enum pids_item sr;
|
||||
int (*xe)(char *, proc_t *); // special format_node 'pr' guy
|
||||
enum pids_sort_order reverse;
|
||||
int typecode;
|
||||
int need;
|
||||
} 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 (* const sr)(const proc_t* P, const proc_t* Q); */ /* sort function */
|
||||
int width;
|
||||
int need;
|
||||
int vendor; /* Vendor that invented this */
|
||||
int flags;
|
||||
int typecode;
|
||||
@ -223,9 +357,8 @@ 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
|
||||
int (* const sr)(const proc_t* P, const proc_t* Q); /* sort function */
|
||||
enum pids_item sr;
|
||||
const int width;
|
||||
const int need; /* data we will need (files to read, etc.) */
|
||||
const int vendor; /* Where does this come from? */
|
||||
const int flags;
|
||||
} format_struct;
|
||||
@ -283,7 +416,7 @@ extern const char *bsd_v_format;
|
||||
extern int bsd_c_option;
|
||||
extern int bsd_e_option;
|
||||
extern uid_t cached_euid;
|
||||
extern dev_t cached_tty;
|
||||
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... */
|
||||
@ -330,7 +463,7 @@ extern int want_this_proc(proc_t *buf);
|
||||
extern const char *select_bits_setup(void);
|
||||
|
||||
/* help.c */
|
||||
extern void do_help(const char *opt, int rc) NORETURN;
|
||||
extern void __attribute__ ((__noreturn__)) do_help(const char *opt, int rc);
|
||||
|
||||
/* global.c */
|
||||
extern void self_info(void);
|
||||
|
360
ps/display.c
360
ps/display.c
@ -22,22 +22,20 @@
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../proc/alloc.h"
|
||||
#include "../proc/readproc.h"
|
||||
#include <proc/pids.h>
|
||||
#include "../proc/sysinfo.h"
|
||||
#include "../proc/version.h"
|
||||
#include "../proc/wchan.h"
|
||||
|
||||
#include "../include/fileutils.h"
|
||||
#include "../include/c.h"
|
||||
#include "../include/fileutils.h"
|
||||
#include "../include/signals.h"
|
||||
#include "../include/xalloc.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifndef SIGCHLD
|
||||
@ -208,41 +206,11 @@ static void check_headers(void){
|
||||
if(!head_normal) lines_to_next_header = -1; /* how UNIX does --noheader */
|
||||
}
|
||||
|
||||
/***** check sort needs */
|
||||
/* see what files need to be read, etc. */
|
||||
static unsigned check_sort_needs(sort_node *walk){
|
||||
unsigned needs = 0;
|
||||
while(walk){
|
||||
needs |= walk->need;
|
||||
walk = walk->next;
|
||||
}
|
||||
return needs;
|
||||
}
|
||||
|
||||
/***** check needs */
|
||||
/* see what files need to be read, etc. */
|
||||
static unsigned collect_format_needs(format_node *walk){
|
||||
unsigned needs = 0;
|
||||
while(walk){
|
||||
needs |= walk->need;
|
||||
walk = walk->next;
|
||||
}
|
||||
return needs;
|
||||
}
|
||||
|
||||
static format_node *proc_format_list;
|
||||
static format_node *task_format_list;
|
||||
|
||||
static unsigned needs_for_threads;
|
||||
static unsigned needs_for_sort;
|
||||
static unsigned proc_format_needs;
|
||||
static unsigned task_format_needs;
|
||||
|
||||
#define needs_for_format (proc_format_needs|task_format_needs)
|
||||
|
||||
#define PROC_ONLY_FLAGS (PROC_FILLENV|PROC_FILLARG|PROC_FILLCOM|PROC_FILLMEM|PROC_FILLCGROUP)
|
||||
|
||||
/***** munge lists and determine openproc() flags */
|
||||
/***** munge lists and determine final needs */
|
||||
static void lists_and_needs(void){
|
||||
check_headers();
|
||||
|
||||
@ -253,7 +221,7 @@ static void lists_and_needs(void){
|
||||
format_node *p_end = &pfn;
|
||||
format_node *t_end = &tfn;
|
||||
while(walk){
|
||||
format_node *new = malloc(sizeof(format_node));
|
||||
format_node *new = xmalloc(sizeof(format_node));
|
||||
memcpy(new,walk,sizeof(format_node));
|
||||
p_end->next = walk;
|
||||
t_end->next = new;
|
||||
@ -262,11 +230,9 @@ static void lists_and_needs(void){
|
||||
switch(walk->flags & CF_PRINT_MASK){
|
||||
case CF_PRINT_THREAD_ONLY:
|
||||
p_end->pr = pr_nop;
|
||||
p_end->need = 0;
|
||||
break;
|
||||
case CF_PRINT_PROCESS_ONLY:
|
||||
t_end->pr = pr_nop;
|
||||
t_end->need = 0;
|
||||
break;
|
||||
default:
|
||||
catastrophic_failure(__FILE__, __LINE__, _("please report this bug"));
|
||||
@ -285,184 +251,126 @@ static void lists_and_needs(void){
|
||||
proc_format_list = format_list;
|
||||
task_format_list = format_list;
|
||||
}
|
||||
|
||||
proc_format_needs = collect_format_needs(proc_format_list);
|
||||
task_format_needs = collect_format_needs(task_format_list);
|
||||
|
||||
needs_for_sort = check_sort_needs(sort_list);
|
||||
|
||||
// move process-only flags to the process
|
||||
proc_format_needs |= (task_format_needs &~ PROC_ONLY_FLAGS);
|
||||
task_format_needs &= ~PROC_ONLY_FLAGS;
|
||||
|
||||
if(bsd_c_option){
|
||||
proc_format_needs &= ~PROC_FILLARG;
|
||||
needs_for_sort &= ~PROC_FILLARG;
|
||||
}
|
||||
if(!unix_f_option){
|
||||
proc_format_needs &= ~PROC_FILLCOM;
|
||||
needs_for_sort &= ~PROC_FILLCOM;
|
||||
}
|
||||
// convert ARG to COM as a standard
|
||||
if(proc_format_needs & PROC_FILLARG){
|
||||
proc_format_needs |= (PROC_FILLCOM | PROC_EDITCMDLCVT);
|
||||
proc_format_needs &= ~PROC_FILLARG;
|
||||
}
|
||||
if(bsd_e_option){
|
||||
if(proc_format_needs&PROC_FILLCOM) proc_format_needs |= PROC_FILLENV;
|
||||
}
|
||||
|
||||
if(thread_flags&TF_loose_tasks) needs_for_threads |= PROC_LOOSE_TASKS;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***** fill in %CPU; not in libproc because of include_dead_children */
|
||||
/* Note: for sorting, not display, so 0..0x7fffffff would be OK */
|
||||
static int want_this_proc_pcpu(proc_t *buf){
|
||||
static void value_this_proc_pcpu(proc_t *buf){
|
||||
unsigned long long used_jiffies;
|
||||
unsigned long pcpu = 0;
|
||||
unsigned long long seconds;
|
||||
|
||||
if(want_this_proc(buf)) {
|
||||
|
||||
if(!want_this_proc(buf)) return 0;
|
||||
if(include_dead_children) used_jiffies = rSv(TICS_ALL_C, ull_int, buf);
|
||||
else used_jiffies = rSv(TICS_ALL, ull_int, buf);
|
||||
|
||||
used_jiffies = buf->utime + buf->stime;
|
||||
if(include_dead_children) used_jiffies += (buf->cutime + buf->cstime);
|
||||
seconds = rSv(TIME_ELAPSED, ull_int, buf);
|
||||
if(seconds) pcpu = (used_jiffies * 1000ULL / Hertz) / seconds;
|
||||
|
||||
seconds = seconds_since_boot - buf->start_time / Hertz;
|
||||
if(seconds) pcpu = (used_jiffies * 1000ULL / Hertz) / seconds;
|
||||
|
||||
buf->pcpu = pcpu; // fits in an int, summing children on 128 CPUs
|
||||
|
||||
return 1;
|
||||
rSv(extra, ul_int, buf) = pcpu;
|
||||
}
|
||||
}
|
||||
|
||||
/***** just display */
|
||||
static void simple_spew(void){
|
||||
static proc_t buf, buf2; // static avoids memset
|
||||
PROCTAB* ptp;
|
||||
pid_t* pidlist;
|
||||
int flags;
|
||||
struct pids_reap *pidreap;
|
||||
proc_t *buf;
|
||||
int i;
|
||||
|
||||
pidlist = NULL;
|
||||
flags = needs_for_format | needs_for_sort | needs_for_select | needs_for_threads;
|
||||
|
||||
// -q option (only single SEL_PID_QUICK typecode entry expected in the list, if present)
|
||||
if (selection_list && selection_list->typecode == SEL_PID_QUICK) {
|
||||
flags |= PROC_PID;
|
||||
|
||||
pidlist = (pid_t*) malloc(selection_list->n * sizeof(pid_t));
|
||||
if (!pidlist) {
|
||||
fprintf(stderr, _("error: not enough memory\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < selection_list->n; i++) {
|
||||
unsigned *pidlist = xcalloc(selection_list->n, sizeof(unsigned));
|
||||
for (i = 0; i < selection_list->n; i++)
|
||||
pidlist[i] = selection_list->u[selection_list->n-i-1].pid;
|
||||
}
|
||||
pidreap = procps_pids_select(Pids_info, pidlist, selection_list->n, PROCPS_FILL_PID);
|
||||
free(pidlist);
|
||||
} else {
|
||||
enum pids_reap_type which;
|
||||
which = (thread_flags & (TF_loose_tasks|TF_show_task))
|
||||
? PROCPS_REAP_THREADS_TOO : PROCPS_REAP_TASKS_ONLY;
|
||||
pidreap = procps_pids_reap(Pids_info, which);
|
||||
}
|
||||
if (!pidreap) {
|
||||
fprintf(stderr, _("fatal library error, reap\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ptp = openproc(flags, pidlist);
|
||||
if(!ptp) {
|
||||
fprintf(stderr, _("error: can not access /proc\n"));
|
||||
exit(1);
|
||||
}
|
||||
switch(thread_flags & (TF_show_proc|TF_loose_tasks|TF_show_task)){
|
||||
case TF_show_proc: // normal non-thread output
|
||||
while(readproc(ptp,&buf)){
|
||||
if(want_this_proc(&buf)){
|
||||
show_one_proc(&buf, proc_format_list);
|
||||
case TF_show_proc: // normal non-thread output
|
||||
for (i = 0; i < pidreap->counts.total; i++) {
|
||||
buf = pidreap->stacks[i];
|
||||
if (want_this_proc(buf))
|
||||
show_one_proc(buf, proc_format_list);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TF_show_proc|TF_loose_tasks: // H option
|
||||
while(readproc(ptp,&buf)){
|
||||
// must still have the process allocated
|
||||
while(readtask(ptp,&buf,&buf2)){
|
||||
if(!want_this_proc(&buf)) continue;
|
||||
show_one_proc(&buf2, task_format_list);
|
||||
break;
|
||||
case TF_show_task: // -L and -T options
|
||||
case TF_show_proc|TF_loose_tasks: // H option
|
||||
for (i = 0; i < pidreap->counts.total; i++) {
|
||||
buf = pidreap->stacks[i];
|
||||
if (want_this_proc(buf))
|
||||
show_one_proc(buf, task_format_list);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TF_show_proc|TF_show_task: // m and -m options
|
||||
while(readproc(ptp,&buf)){
|
||||
if(want_this_proc(&buf)){
|
||||
show_one_proc(&buf, proc_format_list);
|
||||
// must still have the process allocated
|
||||
while(readtask(ptp,&buf,&buf2)) show_one_proc(&buf2, task_format_list);
|
||||
break;
|
||||
case TF_show_proc|TF_show_task: // m and -m options
|
||||
procps_pids_stacks_sort(Pids_info, pidreap->stacks
|
||||
, pidreap->counts.total, PROCPS_PIDS_TIME_START, PROCPS_SORT_ASCEND);
|
||||
procps_pids_stacks_sort(Pids_info, pidreap->stacks
|
||||
, pidreap->counts.total, PROCPS_PIDS_ID_TGID, PROCPS_SORT_ASCEND);
|
||||
for (i = 0; i < pidreap->counts.total; i++) {
|
||||
buf = pidreap->stacks[i];
|
||||
next_proc:
|
||||
if (want_this_proc(buf)) {
|
||||
int self = rSv(ID_PID, s_int, buf);
|
||||
show_one_proc(buf, proc_format_list);
|
||||
for (; i < pidreap->counts.total; i++) {
|
||||
buf = pidreap->stacks[i];
|
||||
if (rSv(ID_TGID, s_int, buf) != self) goto next_proc;
|
||||
show_one_proc(buf, task_format_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TF_show_task: // -L and -T options
|
||||
while(readproc(ptp,&buf)){
|
||||
if(want_this_proc(&buf)){
|
||||
// must still have the process allocated
|
||||
while(readtask(ptp,&buf,&buf2)) show_one_proc(&buf2, task_format_list);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
closeproc(ptp);
|
||||
|
||||
if (pidlist) free(pidlist);
|
||||
}
|
||||
|
||||
|
||||
/***** forest output requires sorting by ppid; add start_time by default */
|
||||
static void prep_forest_sort(void){
|
||||
sort_node *tmp_list = sort_list;
|
||||
const format_struct *incoming;
|
||||
|
||||
if(!sort_list) { /* assume start time order */
|
||||
incoming = search_format_array("start_time");
|
||||
if(!incoming) { fprintf(stderr, _("could not find start_time\n")); exit(1); }
|
||||
tmp_list = malloc(sizeof(sort_node));
|
||||
tmp_list->reverse = 0;
|
||||
incoming = search_format_array("ppid");
|
||||
if(!incoming) { fprintf(stderr, _("could not find ppid\n")); exit(1); }
|
||||
tmp_list = xmalloc(sizeof(sort_node));
|
||||
tmp_list->reverse = PROCPS_SORT_ASCEND;
|
||||
tmp_list->typecode = '?'; /* what was this for? */
|
||||
tmp_list->sr = incoming->sr;
|
||||
tmp_list->need = incoming->need;
|
||||
tmp_list->next = sort_list;
|
||||
sort_list = tmp_list;
|
||||
}
|
||||
/* this is required for the forest option */
|
||||
incoming = search_format_array("ppid");
|
||||
if(!incoming) { fprintf(stderr, _("could not find ppid\n")); exit(1); }
|
||||
tmp_list = malloc(sizeof(sort_node));
|
||||
tmp_list->reverse = 0;
|
||||
incoming = search_format_array("start_time");
|
||||
if(!incoming) { fprintf(stderr, _("could not find start_time\n")); exit(1); }
|
||||
tmp_list = xmalloc(sizeof(sort_node));
|
||||
tmp_list->reverse = PROCPS_SORT_ASCEND;
|
||||
tmp_list->typecode = '?'; /* what was this for? */
|
||||
tmp_list->sr = incoming->sr;
|
||||
tmp_list->need = incoming->need;
|
||||
tmp_list->next = sort_list;
|
||||
sort_list = tmp_list;
|
||||
}
|
||||
|
||||
/* we rely on the POSIX requirement for zeroed memory */
|
||||
//static proc_t *processes[98*1024]; // FIXME
|
||||
static proc_t **processes;
|
||||
|
||||
/***** compare function for qsort */
|
||||
static int compare_two_procs(const void *a, const void *b){
|
||||
sort_node *tmp_list = sort_list;
|
||||
while(tmp_list){
|
||||
int result;
|
||||
result = (*tmp_list->sr)(*(const proc_t *const*)a, *(const proc_t *const*)b);
|
||||
if(result) return (tmp_list->reverse) ? -result : result;
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
return 0; /* no conclusion */
|
||||
}
|
||||
|
||||
/***** show pre-sorted array of process pointers */
|
||||
static void show_proc_array(PROCTAB *restrict ptp, int n){
|
||||
static void show_proc_array(int n){
|
||||
proc_t **p = processes;
|
||||
while(n--){
|
||||
if(thread_flags & TF_show_proc) show_one_proc(*p, proc_format_list);
|
||||
if(thread_flags & TF_show_task){
|
||||
static proc_t buf2; // static avoids memset
|
||||
// must still have the process allocated
|
||||
while(readtask(ptp,*p,&buf2)) show_one_proc(&buf2, task_format_list);
|
||||
}
|
||||
show_one_proc(*p, proc_format_list);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
@ -481,7 +389,7 @@ static void show_tree(const int self, const int n, const int level, const int ha
|
||||
show_one_proc(processes[self],format_list); /* first show self */
|
||||
for(;;){ /* look for children */
|
||||
if(i >= n) return; /* no children */
|
||||
if(processes[i]->ppid == processes[self]->XXXID) break;
|
||||
if(rSv(ID_PPID, s_int, processes[i]) == rSv(ID_PID, s_int, processes[self])) break;
|
||||
i++;
|
||||
}
|
||||
if(level){
|
||||
@ -494,11 +402,11 @@ static void show_tree(const int self, const int n, const int level, const int ha
|
||||
int self_pid;
|
||||
int more_children = 1;
|
||||
if(i >= n) break; /* over the edge */
|
||||
self_pid=processes[self]->XXXID;
|
||||
self_pid=rSv(ID_PID, s_int, processes[self]);
|
||||
if(i+1 >= n)
|
||||
more_children = 0;
|
||||
else
|
||||
if(processes[i+1]->ppid != self_pid) more_children = 0;
|
||||
if(rSv(ID_PPID, s_int, processes[i+1]) != self_pid) more_children = 0;
|
||||
if(self_pid==1 && ADOPTED(processes[i]) && forest_type!='u')
|
||||
show_tree(i++, n, level, more_children);
|
||||
else
|
||||
@ -507,7 +415,6 @@ static void show_tree(const int self, const int n, const int level, const int ha
|
||||
}
|
||||
/* chop prefix that children added -- do we need this? */
|
||||
forest_prefix[level] = '\0';
|
||||
// memset(processes[self], '$', sizeof(proc_t)); /* debug */
|
||||
}
|
||||
|
||||
/***** show forest */
|
||||
@ -517,7 +424,7 @@ static void show_forest(const int n){
|
||||
while(i--){ /* cover whole array looking for trees */
|
||||
j = n;
|
||||
while(j--){ /* search for parent: if none, i is a tree! */
|
||||
if(processes[j]->XXXID == processes[i]->ppid) goto not_root;
|
||||
if(rSv(ID_PID, s_int, processes[j]) == rSv(ID_PPID, s_int, processes[i])) goto not_root;
|
||||
}
|
||||
show_tree(i,n,0,0);
|
||||
not_root:
|
||||
@ -535,37 +442,42 @@ static int want_this_proc_nop(proc_t *dummy){
|
||||
|
||||
/***** sorted or forest */
|
||||
static void fancy_spew(void){
|
||||
proc_data_t *pd = NULL;
|
||||
PROCTAB *restrict ptp;
|
||||
int n = 0; /* number of processes & index into array */
|
||||
struct pids_reap *pidreap;
|
||||
enum pids_reap_type which;
|
||||
proc_t *buf;
|
||||
int i, n = 0;
|
||||
|
||||
ptp = openproc(needs_for_format | needs_for_sort | needs_for_select | needs_for_threads);
|
||||
if(!ptp) {
|
||||
fprintf(stderr, _("error: can not access /proc\n"));
|
||||
exit(1);
|
||||
which = (thread_flags & TF_loose_tasks)
|
||||
? PROCPS_REAP_THREADS_TOO : PROCPS_REAP_TASKS_ONLY;
|
||||
|
||||
pidreap = procps_pids_reap(Pids_info, which);
|
||||
if (!pidreap || !pidreap->counts.total) {
|
||||
fprintf(stderr, _("fatal library error, reap\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(thread_flags & TF_loose_tasks){
|
||||
pd = readproctab3(want_this_proc_pcpu, ptp);
|
||||
}else{
|
||||
pd = readproctab2(want_this_proc_pcpu, (void*)0xdeadbeaful, ptp);
|
||||
processes = xcalloc(pidreap->counts.total, sizeof(void*));
|
||||
for (i = 0; i < pidreap->counts.total; i++) {
|
||||
buf = pidreap->stacks[i];
|
||||
value_this_proc_pcpu(buf);
|
||||
if (want_this_proc(buf))
|
||||
processes[n++] = buf;
|
||||
}
|
||||
n = pd->n;
|
||||
processes = pd->tab;
|
||||
|
||||
if(!n) return; /* no processes */
|
||||
if(forest_type) prep_forest_sort();
|
||||
qsort(processes, n, sizeof(proc_t*), compare_two_procs);
|
||||
if(forest_type) show_forest(n);
|
||||
else show_proc_array(ptp,n);
|
||||
closeproc(ptp);
|
||||
if (n) {
|
||||
if(forest_type) prep_forest_sort();
|
||||
while(sort_list) {
|
||||
procps_pids_stacks_sort(Pids_info, processes, n, sort_list->sr, sort_list->reverse);
|
||||
sort_list = sort_list->next;
|
||||
}
|
||||
if(forest_type) show_forest(n);
|
||||
else show_proc_array(n);
|
||||
}
|
||||
free(processes);
|
||||
}
|
||||
|
||||
static void arg_check_conflicts(void)
|
||||
{
|
||||
int selection_list_len;
|
||||
int has_quick_pid;
|
||||
|
||||
selection_node *walk = selection_list;
|
||||
has_quick_pid = 0;
|
||||
selection_list_len = 0;
|
||||
@ -608,6 +520,71 @@ static void arg_check_conflicts(void)
|
||||
|
||||
}
|
||||
|
||||
static void finalize_stacks (void)
|
||||
{
|
||||
format_node *f_node;
|
||||
sort_node *s_node;
|
||||
|
||||
#if (PIDSITEMS < 60)
|
||||
# error PIDSITEMS (common.h) should be at least 60!
|
||||
#endif
|
||||
|
||||
/* first, ensure minimum result structures for items
|
||||
which may or may not actually be displayable ... */
|
||||
Pids_index = 0;
|
||||
|
||||
// needed by for selections
|
||||
chkREL(CMD)
|
||||
chkREL(ID_EGID)
|
||||
chkREL(ID_EUID)
|
||||
chkREL(ID_FGID)
|
||||
chkREL(ID_FUID)
|
||||
chkREL(ID_PID)
|
||||
chkREL(ID_PPID)
|
||||
chkREL(ID_RGID)
|
||||
chkREL(ID_RUID)
|
||||
chkREL(ID_SESSION)
|
||||
chkREL(ID_SGID)
|
||||
chkREL(ID_SUID)
|
||||
chkREL(ID_TGID)
|
||||
chkREL(STATE)
|
||||
chkREL(TIME_START)
|
||||
chkREL(TTY)
|
||||
// needed to creata an enhanced 'stat/state'
|
||||
chkREL(ID_PGRP)
|
||||
chkREL(ID_TPGID)
|
||||
chkREL(NICE)
|
||||
chkREL(NLWP)
|
||||
chkREL(RSS)
|
||||
chkREL(VM_LOCK)
|
||||
// needed with 's' switch, previously assured
|
||||
chkREL(SIGBLOCKED)
|
||||
chkREL(SIGCATCH)
|
||||
chkREL(SIGIGNORE)
|
||||
chkREL(SIGNALS)
|
||||
chkREL(SIGPENDING)
|
||||
// needed with loss of defunct 'cook_time' macros
|
||||
chkREL(TIME_ALL)
|
||||
chkREL(TIME_ELAPSED)
|
||||
// special items with 'extra' used as former pcpu
|
||||
chkREL(extra)
|
||||
chkREL(noop)
|
||||
|
||||
// now accommodate any results not yet satisfied
|
||||
f_node = format_list;
|
||||
while (f_node) {
|
||||
(*f_node->pr)(NULL, NULL);
|
||||
f_node = f_node->next;
|
||||
}
|
||||
s_node = sort_list;
|
||||
while (s_node) {
|
||||
if (s_node->xe) (*s_node->xe)(NULL, NULL);
|
||||
s_node = s_node->next;
|
||||
}
|
||||
|
||||
procps_pids_reset(Pids_info, Pids_index, Pids_items);
|
||||
}
|
||||
|
||||
/***** no comment */
|
||||
int main(int argc, char *argv[]){
|
||||
atexit(close_stdout);
|
||||
@ -660,9 +637,12 @@ int main(int argc, char *argv[]){
|
||||
init_output(); /* must be between parser and output */
|
||||
|
||||
lists_and_needs();
|
||||
finalize_stacks();
|
||||
|
||||
if(forest_type || sort_list) fancy_spew(); /* sort or forest */
|
||||
else simple_spew(); /* no sort, no forest */
|
||||
show_one_proc((proc_t *)-1,format_list); /* no output yet? */
|
||||
|
||||
procps_pids_unref(&Pids_info);
|
||||
return 0;
|
||||
}
|
||||
|
135
ps/global.c
135
ps/global.c
@ -31,12 +31,11 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../proc/wchan.h"
|
||||
#include "../proc/version.h"
|
||||
#include "../proc/sysinfo.h"
|
||||
#include <proc/uptime.h>
|
||||
|
||||
#include "../include/c.h"
|
||||
#include "../include/xalloc.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifndef __GNU_LIBRARY__
|
||||
@ -49,6 +48,102 @@
|
||||
#define __GLIBC_MINOR__ -1
|
||||
#endif
|
||||
|
||||
// --- <pids> interface begin |||||\||||||||||||||||||||||||||||||||||||||
|
||||
// -----------------------------------------------------------------------
|
||||
struct procps_pidsinfo *Pids_info = NULL; // our required <pids> context
|
||||
enum pids_item *Pids_items; // allocated as PIDSITEMS
|
||||
int Pids_index; // actual number of active enums
|
||||
|
||||
// most of these could be defined as static in the output.c module
|
||||
// (but for future flexibility, the easiest route has been chosen)
|
||||
makREL(ADDR_END_CODE)
|
||||
makREL(ADDR_KSTK_EIP)
|
||||
makREL(ADDR_KSTK_ESP)
|
||||
makREL(ADDR_START_CODE)
|
||||
makREL(ADDR_START_STACK)
|
||||
makREL(ALARM)
|
||||
makREL(CGROUP)
|
||||
makREL(CMD)
|
||||
makREL(CMDLINE)
|
||||
makREL(ENVIRON)
|
||||
makREL(FLAGS)
|
||||
makREL(FLT_MAJ)
|
||||
makREL(FLT_MAJ_C)
|
||||
makREL(FLT_MIN)
|
||||
makREL(FLT_MIN_C)
|
||||
makREL(ID_EGID)
|
||||
makREL(ID_EGROUP)
|
||||
makREL(ID_EUID)
|
||||
makREL(ID_EUSER)
|
||||
makREL(ID_FGID)
|
||||
makREL(ID_FGROUP)
|
||||
makREL(ID_FUID)
|
||||
makREL(ID_FUSER)
|
||||
makREL(ID_PGRP)
|
||||
makREL(ID_PID)
|
||||
makREL(ID_PPID)
|
||||
makREL(ID_RGID)
|
||||
makREL(ID_RGROUP)
|
||||
makREL(ID_RUID)
|
||||
makREL(ID_RUSER)
|
||||
makREL(ID_SESSION)
|
||||
makREL(ID_SGID)
|
||||
makREL(ID_SGROUP)
|
||||
makREL(ID_SUID)
|
||||
makREL(ID_SUSER)
|
||||
makREL(ID_TGID)
|
||||
makREL(ID_TPGID)
|
||||
makREL(LXCNAME)
|
||||
makREL(NICE)
|
||||
makREL(NLWP)
|
||||
makREL(NS_IPC)
|
||||
makREL(NS_MNT)
|
||||
makREL(NS_NET)
|
||||
makREL(NS_PID)
|
||||
makREL(NS_USER)
|
||||
makREL(NS_UTS)
|
||||
makREL(PRIORITY)
|
||||
makREL(PROCESSOR)
|
||||
makREL(RSS)
|
||||
makREL(RSS_RLIM)
|
||||
makREL(RTPRIO)
|
||||
makREL(SCHED_CLASS)
|
||||
makREL(SD_MACH)
|
||||
makREL(SD_OUID)
|
||||
makREL(SD_SEAT)
|
||||
makREL(SD_SESS)
|
||||
makREL(SD_SLICE)
|
||||
makREL(SD_UNIT)
|
||||
makREL(SD_UUNIT)
|
||||
makREL(SIGBLOCKED)
|
||||
makREL(SIGCATCH)
|
||||
makREL(SIGIGNORE)
|
||||
makREL(SIGNALS)
|
||||
makREL(SIGPENDING)
|
||||
makREL(STATE)
|
||||
makREL(SUPGIDS)
|
||||
makREL(SUPGROUPS)
|
||||
makREL(TICS_ALL)
|
||||
makREL(TICS_ALL_C)
|
||||
makREL(TIME_ALL)
|
||||
makREL(TIME_ELAPSED)
|
||||
makREL(TIME_START)
|
||||
makREL(TTY)
|
||||
makREL(TTY_NAME)
|
||||
makREL(TTY_NUMBER)
|
||||
makREL(VM_DATA)
|
||||
makREL(VM_LOCK)
|
||||
makREL(VM_RSS)
|
||||
makREL(VM_SIZE)
|
||||
makREL(VM_STACK)
|
||||
makREL(VSIZE_PGS)
|
||||
makREL(WCHAN_ADDR)
|
||||
makREL(WCHAN_NAME)
|
||||
makREL(extra)
|
||||
makREL(noop)
|
||||
// -----------------------------------------------------------------------
|
||||
// --- <pids> interface end |||||||\||||||||||||||||||||||||||||||||||||||
|
||||
|
||||
|
||||
static const char * saved_personality_text = "You found a bug!";
|
||||
|
||||
@ -60,8 +155,8 @@ const char *bsd_u_format = (const char *)0xdeadbeef;
|
||||
const char *bsd_v_format = (const char *)0xdeadbeef;
|
||||
int bsd_c_option = -1;
|
||||
int bsd_e_option = -1;
|
||||
uid_t cached_euid = -1;
|
||||
dev_t cached_tty = -1;
|
||||
unsigned cached_euid = 0xffffffff;
|
||||
int cached_tty = -1;
|
||||
char forest_prefix[4 * 32*1024 + 100]; // FIXME
|
||||
int forest_type = -1;
|
||||
unsigned format_flags = 0xffffffff; /* -l -f l u s -j... */
|
||||
@ -368,9 +463,33 @@ static const char *set_personality(void){
|
||||
|
||||
/************ Call this to reinitialize everything ***************/
|
||||
void reset_global(void){
|
||||
static proc_t p;
|
||||
proc_t *p;
|
||||
int i;
|
||||
|
||||
reset_selection_list();
|
||||
look_up_our_self(&p);
|
||||
|
||||
// --- <pids> interface --------------------------------------------------
|
||||
if (!Pids_items)
|
||||
Pids_items = xcalloc(PIDSITEMS, sizeof(enum pids_item));
|
||||
|
||||
for (i = 0; i < PIDSITEMS; i++)
|
||||
Pids_items[i] = PROCPS_PIDS_noop;
|
||||
|
||||
if (!Pids_info) {
|
||||
if (procps_pids_new(&Pids_info, i, Pids_items)) {
|
||||
fprintf(stderr, _("fatal library error, context\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
Pids_items[0] = PROCPS_PIDS_TTY;
|
||||
procps_pids_reset(Pids_info, 1, Pids_items);
|
||||
if (!(p = fatal_proc_unmounted(Pids_info, 1))) {
|
||||
fprintf(stderr, _("fatal library error, lookup self\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// --- <pids> interface --------------------------------------------------
|
||||
|
||||
set_screen_size();
|
||||
set_personality();
|
||||
|
||||
@ -378,7 +497,7 @@ void reset_global(void){
|
||||
bsd_c_option = 0;
|
||||
bsd_e_option = 0;
|
||||
cached_euid = geteuid();
|
||||
cached_tty = p.tty;
|
||||
cached_tty = PROCPS_PIDS_VAL(0, s_int, p);
|
||||
/* forest_prefix must be all zero because of POSIX */
|
||||
forest_type = 0;
|
||||
format_flags = 0; /* -l -f l u s -j... */
|
||||
|
1103
ps/output.c
1103
ps/output.c
File diff suppressed because it is too large
Load Diff
28
ps/parser.c
28
ps/parser.c
@ -31,10 +31,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../proc/alloc.h"
|
||||
#include "../include/c.h"
|
||||
#include "../include/xalloc.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "c.h"
|
||||
|
||||
#define ARG_GNU 0
|
||||
#define ARG_END 1
|
||||
@ -185,8 +185,8 @@ static const char *parse_list(const char *arg, const char *(*parse_fn)(char *, s
|
||||
int need_item;
|
||||
const char *err; /* error code that could or did happen */
|
||||
/*** prepare to operate ***/
|
||||
node = malloc(sizeof(selection_node));
|
||||
node->u = malloc(strlen(arg)*sizeof(sel_union)); /* waste is insignificant */
|
||||
node = xmalloc(sizeof(selection_node));
|
||||
node->u = xmalloc(strlen(arg)*sizeof(sel_union)); /* waste is insignificant */
|
||||
node->n = 0;
|
||||
buf = strdup(arg);
|
||||
/*** sanity check and count items ***/
|
||||
@ -583,8 +583,8 @@ static const char *parse_bsd_option(void){
|
||||
/* put our tty on a tiny list */
|
||||
{
|
||||
selection_node *node;
|
||||
node = malloc(sizeof(selection_node));
|
||||
node->u = malloc(sizeof(sel_union));
|
||||
node = xmalloc(sizeof(selection_node));
|
||||
node->u = xmalloc(sizeof(sel_union));
|
||||
node->u[0].tty = cached_tty;
|
||||
node->typecode = SEL_TTY;
|
||||
node->n = 1;
|
||||
@ -720,8 +720,8 @@ static const char *parse_bsd_option(void){
|
||||
if(!arg){
|
||||
/* Wow, obsolete BSD syntax. Put our tty on a tiny list. */
|
||||
selection_node *node;
|
||||
node = malloc(sizeof(selection_node));
|
||||
node->u = malloc(sizeof(sel_union));
|
||||
node = xmalloc(sizeof(selection_node));
|
||||
node->u = xmalloc(sizeof(sel_union));
|
||||
node->u[0].tty = cached_tty;
|
||||
node->typecode = SEL_TTY;
|
||||
node->n = 1;
|
||||
@ -1044,16 +1044,16 @@ static const char *parse_trailing_pids(void){
|
||||
argp = ps_argv + thisarg;
|
||||
thisarg = ps_argc - 1; /* we must be at the end now */
|
||||
|
||||
pidnode = malloc(sizeof(selection_node));
|
||||
pidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
pidnode = xmalloc(sizeof(selection_node));
|
||||
pidnode->u = xmalloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
pidnode->n = 0;
|
||||
|
||||
grpnode = malloc(sizeof(selection_node));
|
||||
grpnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
grpnode = xmalloc(sizeof(selection_node));
|
||||
grpnode->u = xmalloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
grpnode->n = 0;
|
||||
|
||||
sidnode = malloc(sizeof(selection_node));
|
||||
sidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
sidnode = xmalloc(sizeof(selection_node));
|
||||
sidnode->u = xmalloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
sidnode->n = 0;
|
||||
|
||||
while(i--){
|
||||
|
51
ps/select.c
51
ps/select.c
@ -21,18 +21,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../proc/procps.h"
|
||||
#include "../proc/readproc.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
//#define process_group_leader(p) ((p)->pgid == (p)->tgid)
|
||||
//#define some_other_user(p) ((p)->euid != cached_euid)
|
||||
#define has_our_euid(p) ((unsigned)(p)->euid == (unsigned)cached_euid)
|
||||
#define on_our_tty(p) ((unsigned)(p)->tty == (unsigned)cached_tty)
|
||||
#define running(p) (((p)->state=='R')||((p)->state=='D'))
|
||||
#define session_leader(p) ((p)->session == (p)->tgid)
|
||||
#define without_a_tty(p) (!(p)->tty)
|
||||
//#define process_group_leader(p) (rSv(ID_PID, s_int, p) == rSv(ID_TGID, s_int, p))
|
||||
//#define some_other_user(p) (rSv(ID_EUID, u_int, p) != cached_euid)
|
||||
#define has_our_euid(p) (rSv(ID_EUID, u_int, p) == cached_euid)
|
||||
#define on_our_tty(p) (rSv(TTY, s_int, p) == cached_tty)
|
||||
#define running(p) (rSv(STATE, s_ch, p) == 'R' || rSv(STATE, s_ch, p) == 'D')
|
||||
#define session_leader(p) (rSv(ID_SESSION, s_int, p) == rSv(ID_TGID, s_int, p))
|
||||
#define without_a_tty(p) (!rSv(TTY, s_int, p))
|
||||
|
||||
static unsigned long select_bits = 0;
|
||||
|
||||
@ -96,30 +93,28 @@ static int proc_was_listed(proc_t *buf){
|
||||
|
||||
#define return_if_match(foo,bar) \
|
||||
i=sn->n; while(i--) \
|
||||
if((unsigned)(buf->foo) == (unsigned)(*(sn->u+i)).bar) \
|
||||
if((unsigned)foo == (unsigned)(*(sn->u+i)).bar) \
|
||||
return 1
|
||||
|
||||
break; case SEL_RUID: return_if_match(ruid,uid);
|
||||
break; case SEL_EUID: return_if_match(euid,uid);
|
||||
break; case SEL_SUID: return_if_match(suid,uid);
|
||||
break; case SEL_FUID: return_if_match(fuid,uid);
|
||||
break; case SEL_RUID: return_if_match(rSv(ID_RUID, u_int, buf),uid);
|
||||
break; case SEL_EUID: return_if_match(rSv(ID_EUID, u_int, buf),uid);
|
||||
break; case SEL_SUID: return_if_match(rSv(ID_SUID, u_int, buf),uid);
|
||||
break; case SEL_FUID: return_if_match(rSv(ID_FUID, u_int, buf),uid);
|
||||
|
||||
break; case SEL_RGID: return_if_match(rgid,gid);
|
||||
break; case SEL_EGID: return_if_match(egid,gid);
|
||||
break; case SEL_SGID: return_if_match(sgid,gid);
|
||||
break; case SEL_FGID: return_if_match(fgid,gid);
|
||||
break; case SEL_RGID: return_if_match(rSv(ID_RGID, u_int, buf),gid);
|
||||
break; case SEL_EGID: return_if_match(rSv(ID_EGID, u_int, buf),gid);
|
||||
break; case SEL_SGID: return_if_match(rSv(ID_SGID, u_int, buf),gid);
|
||||
break; case SEL_FGID: return_if_match(rSv(ID_FGID, u_int, buf),gid);
|
||||
|
||||
break; case SEL_PGRP: return_if_match(pgrp,pid);
|
||||
break; case SEL_PID : return_if_match(tgid,pid);
|
||||
break; case SEL_PID_QUICK : return_if_match(tgid,pid);
|
||||
break; case SEL_PPID: return_if_match(ppid,ppid);
|
||||
break; case SEL_TTY : return_if_match(tty,tty);
|
||||
break; case SEL_SESS: return_if_match(session,pid);
|
||||
break; case SEL_PGRP: return_if_match(rSv(ID_PGRP, s_int, buf),pid);
|
||||
break; case SEL_PID : return_if_match(rSv(ID_TGID, s_int, buf),pid);
|
||||
break; case SEL_PID_QUICK : return_if_match(rSv(ID_TGID, s_int, buf),pid);
|
||||
break; case SEL_PPID: return_if_match(rSv(ID_PPID, s_int, buf),ppid);
|
||||
break; case SEL_TTY : return_if_match(rSv(TTY, s_int, buf),tty);
|
||||
break; case SEL_SESS: return_if_match(rSv(ID_SESSION, s_int, buf),pid);
|
||||
|
||||
break; case SEL_COMM: i=sn->n; while(i--)
|
||||
if(!strncmp( buf->cmd, (*(sn->u+i)).cmd, 15 )) return 1;
|
||||
|
||||
|
||||
if(!strncmp( rSv(CMD, str, buf), (*(sn->u+i)).cmd, 15 )) return 1;
|
||||
|
||||
#undef return_if_match
|
||||
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../proc/readproc.h"
|
||||
#include "../proc/sysinfo.h"
|
||||
#include "../include/xalloc.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@ -46,7 +46,7 @@ static format_node *do_one_spec(const char *spec, const char *override){
|
||||
if(fs){
|
||||
int w1, w2;
|
||||
format_node *thisnode;
|
||||
thisnode = malloc(sizeof(format_node));
|
||||
thisnode = xmalloc(sizeof(format_node));
|
||||
if(fs->flags & CF_PIDMAX){
|
||||
w1 = (int)get_pid_digits();
|
||||
w2 = strlen(fs->head);
|
||||
@ -63,7 +63,6 @@ static format_node *do_one_spec(const char *spec, const char *override){
|
||||
thisnode->name = strdup(fs->head);
|
||||
}
|
||||
thisnode->pr = fs->pr;
|
||||
thisnode->need = fs->need;
|
||||
thisnode->vendor = fs->vendor;
|
||||
thisnode->flags = fs->flags;
|
||||
thisnode->next = NULL;
|
||||
@ -183,11 +182,10 @@ double_percent:
|
||||
}
|
||||
buf[len] = '\0';
|
||||
walk += len;
|
||||
fnode = malloc(sizeof(format_node));
|
||||
fnode = xmalloc(sizeof(format_node));
|
||||
fnode->width = len;
|
||||
fnode->name = strdup(buf);
|
||||
fnode->pr = NULL; /* checked for */
|
||||
fnode->need = 0;
|
||||
fnode->vendor = AIX;
|
||||
fnode->flags = CF_PRINT_EVERY_TIME;
|
||||
fnode->next = NULL;
|
||||
@ -324,9 +322,9 @@ out:
|
||||
/**************** Parse single sort specifier *******************/
|
||||
static sort_node *do_one_sort_spec(const char *spec){
|
||||
const format_struct *fs;
|
||||
int reverse = 0;
|
||||
enum pids_sort_order reverse = PROCPS_SORT_ASCEND;
|
||||
if(*spec == '-'){
|
||||
reverse = 1;
|
||||
reverse = PROCPS_SORT_DESCEND;
|
||||
spec++;
|
||||
} else if(*spec == '+'){
|
||||
spec++;
|
||||
@ -334,9 +332,10 @@ static sort_node *do_one_sort_spec(const char *spec){
|
||||
fs = search_format_array(spec);
|
||||
if(fs){
|
||||
sort_node *thisnode;
|
||||
thisnode = malloc(sizeof(sort_node));
|
||||
thisnode = xmalloc(sizeof(sort_node));
|
||||
thisnode->sr = fs->sr;
|
||||
thisnode->need = fs->need;
|
||||
// next is a special pointer, called to help with rel enums
|
||||
thisnode->xe = (int(*)(char*,proc_t*))fs->pr;
|
||||
thisnode->reverse = reverse;
|
||||
thisnode->next = NULL;
|
||||
return thisnode;
|
||||
@ -458,7 +457,7 @@ static const char *verify_short_sort(const char *arg){
|
||||
|
||||
/************ parse short sorting option *************/
|
||||
static const char *short_sort_parse(sf_node *sfn){
|
||||
int direction = 0;
|
||||
enum pids_sort_order direction = PROCPS_SORT_ASCEND;
|
||||
const char *walk;
|
||||
int tmp;
|
||||
sort_node *snode;
|
||||
@ -472,10 +471,10 @@ static const char *short_sort_parse(sf_node *sfn){
|
||||
already_parsed_sort = 1;
|
||||
return NULL;
|
||||
case '+':
|
||||
direction = 0;
|
||||
direction = PROCPS_SORT_ASCEND;
|
||||
break;
|
||||
case '-':
|
||||
direction = 1;
|
||||
direction = PROCPS_SORT_DESCEND;
|
||||
break;
|
||||
default:
|
||||
ss = search_shortsort_array(tmp);
|
||||
@ -562,7 +561,7 @@ int defer_sf_option(const char *arg, int source){
|
||||
const format_struct *fs;
|
||||
int need_item = 1;
|
||||
|
||||
sfn = malloc(sizeof(sf_node));
|
||||
sfn = xmalloc(sizeof(sf_node));
|
||||
sfn->sf = strdup(arg);
|
||||
sfn->sf_code = source;
|
||||
sfn->s_cooked = NULL;
|
||||
@ -686,11 +685,10 @@ static const char *generate_sysv_list(void){
|
||||
if( (format_flags & FF_Ul) && !(format_modifiers & FM_y) ){
|
||||
if(personality & PER_IRIX_l){ /* add "rss" then ':' here */
|
||||
PUSH("sgi_rss");
|
||||
fn = malloc(sizeof(format_node));
|
||||
fn = xmalloc(sizeof(format_node));
|
||||
fn->width = 1;
|
||||
fn->name = strdup(":");
|
||||
fn->pr = NULL; /* checked for */
|
||||
fn->need = 0;
|
||||
fn->vendor = AIX; /* yes, for SGI weirdness */
|
||||
fn->flags = CF_PRINT_EVERY_TIME;
|
||||
fn->next = format_list;
|
||||
@ -786,12 +784,11 @@ const char *process_sf_options(int localbroken){
|
||||
sort_node *srt_walk;
|
||||
srt_walk = sf_walk->s_cooked;
|
||||
sf_walk->s_cooked = NULL;
|
||||
while(srt_walk){ /* put any nodes onto sort_list in opposite way */
|
||||
sort_node *travler;
|
||||
travler = srt_walk;
|
||||
srt_walk = srt_walk->next;
|
||||
if (srt_walk) {
|
||||
sort_node *travler = srt_walk;
|
||||
while (travler->next) travler = travler->next;
|
||||
travler->next = sort_list;
|
||||
sort_list = travler;
|
||||
sort_list = srt_walk;
|
||||
}
|
||||
sf_walk = sf_walk->next;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user