static char sbuf[1024]; // buffer for stat,statm
unsigned flags = PT->flags;
+//printf("hhh\n");
if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */
goto next_task;
t->euid = sb.st_uid; /* need a way to get real uid */
t->egid = sb.st_gid; /* need a way to get real gid */
+//printf("iii\n");
if (flags & PROC_FILLSTAT) { /* read, parse /proc/#/stat */
if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 ))
goto next_task; /* error reading /proc/#/stat */
// Return non-zero on success.
static int simple_nexttid(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t, char *restrict const path) {
static struct direct *ent; /* dirent handle */
- (void)p;
- if(!PT->taskdir){
+ if(PT->taskdir_user != p->tgid){
+ if(PT->taskdir){
+ closedir(PT->taskdir);
+ }
// use "path" as some tmp space
snprintf(path, PROCPATHLEN, "%s/task", PT->path);
PT->taskdir = opendir(path);
if(!PT->taskdir) return 0;
+ PT->taskdir_user = p->tgid;
}
for (;;) {
ent = readdir(PT->taskdir);
proc_t *saved_p;
if (PT->did_fake) PT->did_fake=0;
- if (PT->taskdir) {
- closedir(PT->taskdir);
- PT->taskdir = NULL;
- }
+// if (PT->taskdir) {
+// closedir(PT->taskdir);
+// PT->taskdir = NULL;
+// PT->taskdir_user = -1;
+// }
saved_p = p;
if(!p) p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */
did_stat = 1;
}
PT->taskdir = NULL;
+ PT->taskdir_user = -1;
PT->taskfinder = simple_nexttid;
PT->taskreader = simple_readtask;
if (PT){
if (PT->procfs) closedir(PT->procfs);
if (PT->taskdir) closedir(PT->taskdir);
+ memset(PT,'#',sizeof(PROCTAB));
free(PT);
}
}
}
// Try again, this time with threads and selection.
-proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), int flags, ...) {
- PROCTAB* PT = NULL;
+proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT) {
proc_t** ptab = NULL;
- proc_t** ttab = NULL;
- proc_t* data = NULL;
- unsigned n_alloc = 0;
- unsigned n_used = 0;
unsigned n_proc_alloc = 0;
unsigned n_proc = 0;
- unsigned n_task = 0;
+
+ proc_t** ttab = NULL;
unsigned n_task_alloc = 0;
- va_list ap;
- proc_data_t *pd;
+ unsigned n_task = 0;
- va_start(ap, flags);
- if (flags & PROC_UID) {
- // temporary variables ensure that va_arg() instances
- // are called in the right order
- uid_t* u;
- int i;
+ proc_t* data = NULL;
+ unsigned n_alloc = 0;
+ unsigned long n_used = 0;
- u = va_arg(ap, uid_t*);
- i = va_arg(ap, int);
- PT = openproc(flags, u, i);
- }
- else if (flags & PROC_PID)
- PT = openproc(flags, va_arg(ap, void*));
- else
- PT = openproc(flags);
- va_end(ap);
+ proc_data_t *pd;
for(;;){
proc_t *tmp;
tmp = readproc_direct(PT, data+n_used);
if(!tmp) break;
if(!want_proc(tmp)) continue;
- ptab[n_proc++] = tmp;
- n_used++;
+ ptab[n_proc++] = (proc_t*)(n_used++);
if(!( PT->flags & PROC_LOOSE_TASKS )) continue;
for(;;){
proc_t *t;
t = readtask_direct(PT, tmp, data+n_used);
if(!t) break;
if(!want_task(t)) continue;
- ttab[n_task++] = t;
- n_used++;
+ ttab[n_task++] = (proc_t*)(n_used++);
}
}
- closeproc(PT);
-
pd = malloc(sizeof(proc_data_t));
pd->proc = ptab;
pd->task = ttab;
pd->nproc = n_proc;
pd->ntask = n_task;
- if(flags & PROC_LOOSE_TASKS){
+ if(PT->flags & PROC_LOOSE_TASKS){
pd->tab = ttab;
pd->n = n_task;
}else{
pd->tab = ptab;
pd->n = n_proc;
}
+ // change array indexes to pointers
+ while(n_proc--) ptab[n_proc] = data+(long)(ptab[n_proc]);
+ while(n_task--) ttab[n_task] = data+(long)(ttab[n_task]);
return pd;
}
typedef struct PROCTAB {
DIR* procfs;
+// char deBug0[64];
DIR* taskdir; // for threads
+// char deBug1[64];
+ pid_t taskdir_user; // for threads
int did_fake; // used when taskdir is missing
int(*finder)(struct PROCTAB *restrict const, proc_t *restrict const);
proc_t*(*reader)(struct PROCTAB *restrict const, proc_t *restrict const);
int ntask;
} proc_data_t;
-extern proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), int flags, ... /* same as openproc */ );
+extern proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT);
// Convenient wrapper around openproc and readproc to slurp in the whole process
// table subset satisfying the constraints of flags and the optional PID list.
/***** fill in %CPU; not in libproc because of include_dead_children */
/* Note: for sorting, not display, so 0..0x7fffffff would be OK */
-static void fill_pcpu(proc_t *buf){
+static int want_this_proc_pcpu(proc_t *buf){
unsigned long long used_jiffies;
unsigned long pcpu = 0;
unsigned long long avail_jiffies;
+ if(!want_this_proc(buf)) return 0;
+
used_jiffies = buf->utime + buf->stime;
if(include_dead_children) used_jiffies += (buf->cutime + buf->cstime);
if(avail_jiffies) pcpu = (used_jiffies << 24) / avail_jiffies;
buf->pcpu = pcpu; // fits in an int, summing children on 128 CPUs
+
+ return 1;
}
/***** just display */
/* don't free the array because it takes time and ps will exit anyway */
}
+static int want_this_proc_nop(proc_t *dummy){
+ (void)dummy;
+ return 1;
+}
+
/***** sorted or forest */
static void fancy_spew(void){
proc_t *retbuf = NULL;
fprintf(stderr, "can't have threads with sorting or forest output\n");
exit(49);
}
+#endif
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);
}
+#if 0
while((retbuf = readproc(ptp,retbuf))){
- if(want_this_proc(retbuf)){
- fill_pcpu(retbuf); // in case we might sort by %cpu
+ if(want_this_proc_pcpu(retbuf)){
+// fill_pcpu(retbuf); // in case we might sort by %cpu
processes[n++] = retbuf;
retbuf = NULL; // NULL asks readproc to allocate
}
}
if(retbuf) free(retbuf);
- closeproc(ptp);
#else
- // FIXME: need pcpu
- pd = readproctab2(want_this_proc, want_this_proc, needs_for_format | needs_for_sort | needs_for_select | needs_for_threads);
+ if(thread_flags & TF_loose_tasks){
+ pd = readproctab2(want_this_proc_nop, want_this_proc_pcpu, ptp);
+ }else{
+ pd = readproctab2(want_this_proc_pcpu, (void*)0xdeadbeaful, ptp);
+ }
n = pd->n;
processes = pd->tab;
#endif
qsort(processes, n, sizeof(proc_t*), compare_two_procs);
if(forest_type) show_forest(n);
else show_proc_array(ptp,n);
+ closeproc(ptp);
}