supgid/supgrp support, improved library interface

Library changes
   readproc
    . added support for supplementary groups
    . eliminated 2 potential mem leak sources
       . shortcut used for multi-threaded str
         vectors & ptrs was obsoleted
       . freeing of proc_t related dynamic
         memory now rests with the library
    . standardized/normalized many c comments
   sysinfo
    . corrected note regarding glibc & cpuinfo
   library.map
    . made the visible freeproc accessable
 Program changes
   pmap
    . initialized buffer for new readproc i/f
    . eliminated now obsolete free() call
   ps
    . added width aware supgrp support
    . initialized buffers for new readproc i/f
    . eliminated now obsolete free() calls
   top
    . added supgrp support as variable width
    . eliminated now obsolete free() calls
    . expoilted library freeproc function
    . corrected -h|v args text & spacing
    . updated some c comments
 Documentation changes
   ps.1
    . added supgid and supgrp
   top.1
    . added supgid and supgrp
    . addition of above required renumbering
      many fields in section 3a. DESCRIPTIONS
This commit is contained in:
Craig Small
2011-08-01 21:28:46 +10:00
parent 3f59ff5a16
commit 3ef4823f90
11 changed files with 306 additions and 217 deletions

View File

@ -327,61 +327,46 @@ static int want_this_proc_pcpu(proc_t *buf){
/***** just display */
static void simple_spew(void){
proc_t buf;
static proc_t buf, buf2; // static avoids memset
PROCTAB* ptp;
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);
}
memset(&buf, '#', sizeof(proc_t));
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);
}
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
while(readproc(ptp,&buf)){
proc_t buf2;
// must still have the process allocated
while(readtask(ptp,&buf,&buf2)){
if(!want_this_proc(&buf)) continue;
show_one_proc(&buf2, task_format_list);
}
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
while(readproc(ptp,&buf)){
if(want_this_proc(&buf)){
proc_t buf2;
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);
}
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)){
if(want_this_proc(&buf)){
proc_t buf2;
// must still have the process allocated
while(readtask(ptp,&buf,&buf2)) show_one_proc(&buf2, task_format_list);
}
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;
}
@ -438,16 +423,10 @@ static void show_proc_array(PROCTAB *restrict ptp, int n){
while(n--){
if(thread_flags & TF_show_proc) show_one_proc(*p, proc_format_list);
if(thread_flags & TF_show_task){
proc_t buf2;
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);
// must not attempt to free cmdline and environ
}
/* no point freeing any of this -- won't need more mem */
// if((*p)->cmdline) free((void*)*(*p)->cmdline);
// if((*p)->environ) free((void*)*(*p)->environ);
// memset(*p, '%', sizeof(proc_t)); /* debug */
// free(*p);
p++;
}
}
@ -464,9 +443,6 @@ static void show_tree(const int self, const int n, const int level, const int ha
forest_prefix[level] = '\0';
}
show_one_proc(processes[self],format_list); /* first show self */
/* no point freeing any of this -- won't need more mem */
// if(processes[self]->cmdline) free((void*)*processes[self]->cmdline);
// if(processes[self]->environ) free((void*)*processes[self]->environ);
for(;;){ /* look for children */
if(i >= n) return; /* no children */
if(processes[i]->ppid == processes[self]->XXXID) break;

View File

@ -38,7 +38,7 @@
*
* Table 5 could go in a file with the output functions.
*/
#include <ctype.h>
#include <fcntl.h>
#include <grp.h>
@ -360,7 +360,7 @@ static int pr_argcom(char *restrict const outbuf, const proc_t *restrict const p
static int pr_cgroup(char *restrict const outbuf,const proc_t *restrict const pp) {
int rightward = max_rightward;
if(pp->cgroup) {
escaped_copy(outbuf, *pp->cgroup, OUTBUF_SIZE, &rightward);
return max_rightward-rightward;
@ -373,7 +373,7 @@ static int pr_cgroup(char *restrict const outbuf,const proc_t *restrict const pp
static int pr_fname(char *restrict const outbuf, const proc_t *restrict const pp){
char *endp = outbuf;
int rightward = max_rightward;
if(forest_prefix){
int fh = forest_helper(outbuf);
endp += fh;
@ -381,7 +381,7 @@ static int pr_fname(char *restrict const outbuf, const proc_t *restrict const pp
}
if (rightward>8) /* 8=default, but forest maybe feeds more */
rightward = 8;
endp += escape_str(endp, pp->cmd, OUTBUF_SIZE, &rightward);
//return endp - outbuf;
return max_rightward-rightward;
@ -1022,10 +1022,10 @@ static int do_pr_name(char *restrict const outbuf, const char *restrict const na
if(!user_is_number){
int rightward = OUTBUF_SIZE; /* max cells */
int len; /* real cells */
escape_str(outbuf, name, OUTBUF_SIZE, &rightward);
len = OUTBUF_SIZE-rightward;
if(len <= (int)max_rightward)
return len; /* returns number of cells */
}
@ -1072,11 +1072,23 @@ static int pr_nlwp(char *restrict const outbuf, const proc_t *restrict const pp)
static int pr_sess(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%u", pp->session);
}
static int pr_supgid(char *restrict const outbuf, const proc_t *restrict const pp){
int rightward = max_rightward;
escaped_copy(outbuf, pp->supgid ? pp->supgid : "n/a", OUTBUF_SIZE, &rightward);
return max_rightward-rightward;
}
static int pr_supgrp(char *restrict const outbuf, const proc_t *restrict const pp){
int rightward = max_rightward;
escaped_copy(outbuf, pp->supgrp ? pp->supgrp : "n/a", OUTBUF_SIZE, &rightward);
return max_rightward-rightward;
}
static int pr_tpgid(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%d", pp->tpgid);
}
/* SGI uses "cpu" to print the processor ID with header "P" */
static int pr_sgi_p(char *restrict const outbuf, const proc_t *restrict const pp){ /* FIXME */
if(pp->state == 'R') return snprintf(outbuf, COLWID, "%d", pp->processor);
@ -1241,7 +1253,9 @@ static int pr_t_left2(char *restrict const outbuf, const proc_t *restrict const
#define GRP PROC_FILLGRP /* gid_t -> group names */
#define WCH PROC_FILLWCHAN /* do WCHAN lookup */
#define SGRP PROC_FILLSTATUS | PROC_FILLSUPGRP /* supgid -> supgrp (names) */
#define CGRP PROC_FILLCGROUP | PROC_EDITCGRPCVT /* read cgroup */
/* TODO
* pull out annoying BSD aliases into another table (to macro table?)
* add sorting functions here (to unify names)
@ -1437,6 +1451,8 @@ static const format_struct format_array[] = {
{"status", "STATUS", pr_nop, sr_nop, 6, 0, DEC, AN|RIGHT},
{"stime", "STIME", pr_stime, sr_stime, 5, 0, XXX, ET|RIGHT}, /* was 6 wide */
{"suid", "SUID", pr_suid, sr_suid, 5, 0, LNx, ET|RIGHT},
{"supgid", "SUPGID", pr_supgid, sr_nop, 20, 0, LNX, PO|UNLIMITED},
{"supgrp", "SUPGRP", pr_supgrp, sr_nop, 40,SGRP, LNX, PO|UNLIMITED},
{"suser", "SUSER", pr_suser, sr_suser, 8, USR, LNx, ET|USER},
{"svgid", "SVGID", pr_sgid, sr_sgid, 5, 0, XXX, ET|RIGHT},
{"svgroup", "SVGROUP", pr_sgroup, sr_sgroup, 8, GRP, LNX, ET|USER},
@ -1797,14 +1813,14 @@ void show_one_proc(const proc_t *restrict const p, const format_node *restrict f
}
}
max_leftward = fmt->width + actual - correct; /* TODO check this */
// fprintf(stderr, "cols: %d, max_rightward: %d, max_leftward: %d, actual: %d, correct: %d\n",
// active_cols, max_rightward, max_leftward, actual, correct);
/* prepare data and calculate leftpad */
if(likely(p) && likely(fmt->pr)) amount = (*fmt->pr)(outbuf,p);
else amount = strlen(strcpy(outbuf, fmt->name)); /* AIX or headers */
switch((fmt->flags) & CF_JUST_MASK){
case 0: /* for AIX, assigned outside this file */
leftpad = 0;
@ -1869,7 +1885,7 @@ void show_one_proc(const proc_t *restrict const p, const format_node *restrict f
/* real size -- don't forget in 'amount' is number of cells */
sz = strlen(outbuf);
/* print data, set x position stuff */
if(unlikely(!fmt->next)){
/* Last column. Write padding + data + newline all together. */

12
ps/ps.1
View File

@ -1321,6 +1321,18 @@ suid SUID T{
saved user\ ID. (alias\ \fBsvuid\fR).
T}
supgid SUPGID T{
group ids of supplementary groups, if any.
See
.BR getgroups (2).
T}
supgrp SUPGRP T{
group names of supplementary groups, if any.
See
.BR getgroups (2).
T}
suser SUSER T{
saved user name. This will be the textual user\ ID,
if\ it can be obtained and the field width permits,