--- procps-3.2.7/ps/display.c +++ procps-3.2.7/ps/display.c 2008-03-06 09:48:59.000000000 +0100 @@ -223,8 +223,7 @@ #define needs_for_format (proc_format_needs|task_format_needs) -#define PROC_ONLY_FLAGS (PROC_FILLENV|PROC_FILLARG|PROC_FILLCOM|PROC_FILLMEM) - +#define PROC_ONLY_FLAGS (PROC_FILLENV|PROC_FILLARG|PROC_FILLCOM|PROC_FILLMEM|PROC_FILLCGROUP) /***** munge lists and determine openproc() flags */ static void lists_and_needs(void){ check_headers(); @@ -342,6 +341,7 @@ } if(buf.cmdline) free((void*)*buf.cmdline); // ought to reuse if(buf.environ) free((void*)*buf.environ); // ought to reuse + if(buf.cgroup) free((void*)*buf.cgroup); } break; case TF_show_proc|TF_loose_tasks: // H option @@ -354,6 +354,7 @@ } if(buf.cmdline) free((void*)*buf.cmdline); // ought to reuse if(buf.environ) free((void*)*buf.environ); // ought to reuse + if(buf.cgroup) free((void*)*buf.cgroup); } break; case TF_show_proc|TF_show_task: // m and -m options @@ -366,7 +367,8 @@ } if(buf.cmdline) free((void*)*buf.cmdline); // ought to reuse if(buf.environ) free((void*)*buf.environ); // ought to reuse - } + if(buf.cgroup) free((void*)*buf.cgroup); + } break; case TF_show_task: // -L and -T options while(readproc(ptp,&buf)){ @@ -377,7 +379,8 @@ } if(buf.cmdline) free((void*)*buf.cmdline); // ought to reuse if(buf.environ) free((void*)*buf.environ); // ought to reuse - } + if(buf.cgroup) free((void*)*buf.cgroup); + } break; } closeproc(ptp); --- procps-3.2.7/ps/output.c +++ procps-3.2.7/ps/output.c 2008-03-06 09:47:21.000000000 +0100 @@ -359,6 +359,26 @@ return max_rightward-rightward; } +static int pr_cgroup(char *restrict const outbuf,const proc_t *restrict const pp) { + if(pp->cgroup && *pp->cgroup) { + char *endp = outbuf; + int rightward=max_rightward; + if(forest_prefix){ + int fh = forest_helper(outbuf); + endp += fh; + rightward -= fh; + } + if(rightward>1){ + *endp++ = ' '; + rightward--; + endp += escape_str(endp, *pp->cgroup, OUTBUF_SIZE, &rightward); + } + return max_rightward-rightward; + } + else + return pr_nop(outbuf,pp); +} + /* "ucomm" is the same thing: short unless -f */ static int pr_comm(char *restrict const outbuf, const proc_t *restrict const pp){ char *endp = outbuf; @@ -1248,7 +1268,7 @@ #define GRP PROC_FILLGRP /* gid_t -> group names */ #define WCH PROC_FILLWCHAN /* do WCHAN lookup */ - +#define CGRP PROC_FILLCGROUP /* read cgroup */ /* TODO * pull out annoying BSD aliases into another table (to macro table?) * add sorting functions here (to unify names) @@ -1284,6 +1304,7 @@ {"bsdtime", "TIME", pr_bsdtime, sr_nop, 6, 0, LNX, ET|RIGHT}, {"c", "C", pr_c, sr_pcpu, 2, 0, SUN, ET|RIGHT}, {"caught", "CAUGHT", pr_sigcatch, sr_nop, 9, 0, BSD, TO|SIGNAL}, /*sigcatch*/ +{"cgroup", "CGROUP", pr_cgroup, sr_nop, 27, CGRP, LNX, PO|UNLIMITED}, {"class", "CLS", pr_class, sr_sched, 3, 0, XXX, TO|LEFT}, {"cls", "CLS", pr_class, sr_sched, 3, 0, HPU, TO|RIGHT}, /*says HPUX or RT*/ {"cmaj_flt", "-", pr_nop, sr_cmaj_flt, 1, 0, LNX, AN|RIGHT}, --- procps-3.2.7/proc/readproc.c +++ procps-3.2.7/proc/readproc.c 2008-03-06 10:05:49.000000000 +0100 @@ -598,6 +598,17 @@ p->environ = file2strvec(path, "environ"); else p->environ = NULL; + + if(linux_version_code>=LINUX_VERSION(2,6,24) && (flags & PROC_FILLCGROUP)) { + p->cgroup = file2strvec(path, "cgroup"); /* read /proc/#/cgroup */ + if(p->cgroup && *p->cgroup) { + int i = strlen(*p->cgroup); + if( (*p->cgroup)[i-1]=='\n' ) + (*p->cgroup)[i-1] = ' '; //little hack to remove trailing \n + } + } + else + p->cgroup = NULL; return p; next_proc: @@ -686,7 +697,7 @@ t->cmdline = p->cmdline; // better not free these until done with all threads! t->environ = p->environ; #endif - + t->cgroup = p->cgroup; t->ppid = p->ppid; // ought to put the per-task ppid somewhere return t; @@ -896,6 +907,8 @@ free((void*)*p->cmdline); if (p->environ) free((void*)*p->environ); + if (p->cgroup) + free((void*)*p->cgroup); free(p); } --- procps-3.2.7/proc/readproc.h +++ procps-3.2.7/proc/readproc.h 2008-03-06 10:07:48.000000000 +0100 @@ -139,6 +139,7 @@ tpgid, // stat terminal process group id exit_signal, // stat might not be SIGCHLD processor; // stat current (or most recent?) CPU + char **cgroup; // cgroup current cgroup, looks like a classic filepath } proc_t; // PROCTAB: data structure holding the persistent information readproc needs @@ -239,6 +240,8 @@ #define PROC_LOOSE_TASKS 0x0200 // threat threads as if they were processes +#define PROC_FILLCGROUP 0x0400 // alloc and fill in `cgroup` + // Obsolete, consider only processes with one of the passed: #define PROC_PID 0x1000 // process id numbers ( 0 terminated) #define PROC_UID 0x4000 // user id numbers ( length needed )