ps: conditionally support additional -o FIELDs

function                                             old     new   delta
procps_scan                                         1409    1642    +233
out_spec                                             220     300     +80
func_ruser                                             -      36     +36
func_rgroup                                            -      36     +36
func_group                                            13      49     +36
func_nice                                              -      29     +29
buffer_fill_and_print                                179     196     +17
send_tree                                            355     360      +5
mkfs_vfat_main                                      1604    1609      +5
display_speed                                         85      90      +5
scriptreplay_main                                    194     197      +3
find_out_spec                                         55      58      +3
changepath                                           192     195      +3
sha1_process_block64                                 497     484     -13
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 10/1 up/down: 491/-13)          Total: 478 bytes

Signed-off-by: David Krakov <krakov@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2009-07-03 22:16:17 +02:00
parent c5d07fba29
commit fca70a8cce
5 changed files with 92 additions and 18 deletions

View File

@ -1276,6 +1276,11 @@ typedef struct procps_status_t {
unsigned sid; unsigned sid;
unsigned uid; unsigned uid;
unsigned gid; unsigned gid;
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
unsigned ruid;
unsigned rgid;
int niceness;
#endif
unsigned tty_major,tty_minor; unsigned tty_major,tty_minor;
#if ENABLE_FEATURE_TOPMEM #if ENABLE_FEATURE_TOPMEM
unsigned long mapped_rw; unsigned long mapped_rw;
@ -1296,6 +1301,7 @@ typedef struct procps_status_t {
int last_seen_on_cpu; int last_seen_on_cpu;
#endif #endif
} procps_status_t; } procps_status_t;
/* flag bits for procps_scan(xx, flags) calls */
enum { enum {
PSSCAN_PID = 1 << 0, PSSCAN_PID = 1 << 0,
PSSCAN_PPID = 1 << 1, PSSCAN_PPID = 1 << 1,
@ -1322,16 +1328,16 @@ enum {
), ),
IF_SELINUX(PSSCAN_CONTEXT = 1 << 17,) IF_SELINUX(PSSCAN_CONTEXT = 1 << 17,)
PSSCAN_START_TIME = 1 << 18, PSSCAN_START_TIME = 1 << 18,
PSSCAN_CPU = 1 << 19, PSSCAN_CPU = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
PSSCAN_NICE = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
PSSCAN_RUIDGID = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
/* These are all retrieved from proc/NN/stat in one go: */ /* These are all retrieved from proc/NN/stat in one go: */
PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
/**/ | PSSCAN_COMM | PSSCAN_STATE /**/ | PSSCAN_COMM | PSSCAN_STATE
/**/ | PSSCAN_VSZ | PSSCAN_RSS /**/ | PSSCAN_VSZ | PSSCAN_RSS
/**/ | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME /**/ | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
/**/ | PSSCAN_TTY /**/ | PSSCAN_TTY | PSSCAN_NICE
#if ENABLE_FEATURE_TOP_SMP_PROCESS
/**/ | PSSCAN_CPU /**/ | PSSCAN_CPU
#endif
}; };
//procps_status_t* alloc_procps_scan(void) FAST_FUNC; //procps_status_t* alloc_procps_scan(void) FAST_FUNC;
void free_procps_scan(procps_status_t* sp) FAST_FUNC; void free_procps_scan(procps_status_t* sp) FAST_FUNC;

View File

@ -151,6 +151,16 @@ static unsigned long fast_strtoul_10(char **endptr)
*endptr = str + 1; /* We skip trailing space! */ *endptr = str + 1; /* We skip trailing space! */
return n; return n;
} }
static long fast_strtol_10(char **endptr)
{
if (**endptr != '-')
return fast_strtoul_10(endptr);
(*endptr)++;
return - (long)fast_strtoul_10(endptr);
}
static char *skip_fields(char *str, int count) static char *skip_fields(char *str, int count)
{ {
do { do {
@ -208,7 +218,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
if (flags & PSSCAN_UIDGID) { if (flags & PSSCAN_UIDGID) {
if (stat(filename, &sb)) if (stat(filename, &sb))
break; break;
/* Need comment - is this effective or real UID/GID? */ /* Effective UID/GID, not real */
sp->uid = sb.st_uid; sp->uid = sb.st_uid;
sp->gid = sb.st_gid; sp->gid = sb.st_gid;
} }
@ -293,7 +303,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
sp->utime = fast_strtoul_10(&cp); sp->utime = fast_strtoul_10(&cp);
sp->stime = fast_strtoul_10(&cp); sp->stime = fast_strtoul_10(&cp);
cp = skip_fields(cp, 3); /* cutime, cstime, priority */ cp = skip_fields(cp, 3); /* cutime, cstime, priority */
tasknice = fast_strtoul_10(&cp); tasknice = fast_strtol_10(&cp);
cp = skip_fields(cp, 2); /* timeout, it_real_value */ cp = skip_fields(cp, 2); /* timeout, it_real_value */
sp->start_time = fast_strtoul_10(&cp); sp->start_time = fast_strtoul_10(&cp);
/* vsz is in bytes and we want kb */ /* vsz is in bytes and we want kb */
@ -310,6 +320,10 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
#endif #endif
#endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */ #endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
sp->niceness = tasknice;
#endif
if (sp->vsz == 0 && sp->state[0] != 'Z') if (sp->vsz == 0 && sp->state[0] != 'Z')
sp->state[1] = 'W'; sp->state[1] = 'W';
else else
@ -372,7 +386,29 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
fclose(file); fclose(file);
} }
#endif /* TOPMEM */ #endif /* TOPMEM */
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
if (flags & PSSCAN_RUIDGID) {
FILE *file;
strcpy(filename_tail, "/status");
file = fopen_for_read(filename);
if (!file)
break;
while (fgets(buf, sizeof(buf), file)) {
char *tp;
#define SCAN_TWO(str, name, statement) \
if (strncmp(buf, str, sizeof(str)-1) == 0) { \
tp = skip_whitespace(buf + sizeof(str)-1); \
sscanf(tp, "%u", &sp->name); \
statement; \
}
SCAN_TWO("Uid:", ruid, continue);
SCAN_TWO("Gid:", rgid, break);
#undef SCAN_TWO
}
fclose(file);
}
#endif /* PS_ADDITIONAL_COLUMNS */
#if 0 /* PSSCAN_CMD is not used */ #if 0 /* PSSCAN_CMD is not used */
if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
free(sp->argv0); free(sp->argv0);

View File

@ -91,13 +91,13 @@ config PS
ps gives a snapshot of the current processes. ps gives a snapshot of the current processes.
config FEATURE_PS_WIDE config FEATURE_PS_WIDE
bool "Enable argument for wide output (-w)" bool "Enable wide output option (-w)"
default n default n
depends on PS depends on PS
help help
Support argument 'w' for wide output. Support argument 'w' for wide output.
If given once, 132 chars are printed and given more than If given once, 132 chars are printed, and if given more
one, the length is unlimited. than once, the length is unlimited.
config FEATURE_PS_TIME config FEATURE_PS_TIME
bool "Enable time and elapsed time output" bool "Enable time and elapsed time output"
@ -106,6 +106,13 @@ config FEATURE_PS_TIME
help help
Support -o time and -o etime output specifiers. Support -o time and -o etime output specifiers.
config FEATURE_PS_ADDITIONAL_COLUMNS
bool "Enable additional ps columns"
default n
depends on PS && DESKTOP
help
Support -o rgroup, -o ruser, -o nice output specifiers.
config FEATURE_PS_UNUSUAL_SYSTEMS config FEATURE_PS_UNUSUAL_SYSTEMS
bool "Support Linux prior to 2.4.0 and non-ELF systems" bool "Support Linux prior to 2.4.0 and non-ELF systems"
default n default n

View File

@ -32,7 +32,7 @@ enum { MAX_WIDTH = 2*1024 };
typedef struct { typedef struct {
uint16_t width; uint16_t width;
char name[6]; char name6[6];
const char *header; const char *header;
void (*f)(char *buf, int size, const procps_status_t *ps); void (*f)(char *buf, int size, const procps_status_t *ps);
int ps_flags; int ps_flags;
@ -174,6 +174,11 @@ static void func_user(char *buf, int size, const procps_status_t *ps)
#endif #endif
} }
static void func_group(char *buf, int size, const procps_status_t *ps)
{
safe_strncpy(buf, get_cached_groupname(ps->gid), size+1);
}
static void func_comm(char *buf, int size, const procps_status_t *ps) static void func_comm(char *buf, int size, const procps_status_t *ps)
{ {
safe_strncpy(buf, ps->comm, size+1); safe_strncpy(buf, ps->comm, size+1);
@ -227,6 +232,26 @@ static void func_tty(char *buf, int size, const procps_status_t *ps)
snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor); snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
} }
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
static void func_rgroup(char *buf, int size, const procps_status_t *ps)
{
safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1);
}
static void func_ruser(char *buf, int size, const procps_status_t *ps)
{
safe_strncpy(buf, get_cached_username(ps->ruid), size+1);
}
static void func_nice(char *buf, int size, const procps_status_t *ps)
{
sprintf(buf, "%*d", size, ps->niceness);
}
#endif /* FEATURE_PS_ADDITIONAL_COLUMNS */
#if ENABLE_FEATURE_PS_TIME #if ENABLE_FEATURE_PS_TIME
static void func_etime(char *buf, int size, const procps_status_t *ps) static void func_etime(char *buf, int size, const procps_status_t *ps)
{ {
@ -276,6 +301,7 @@ static void func_pcpu(char *buf, int size, const procps_status_t *ps)
static const ps_out_t out_spec[] = { static const ps_out_t out_spec[] = {
// Mandated by POSIX: // Mandated by POSIX:
{ 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID },
{ 8 , "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID },
{ 16 , "comm" ,"COMMAND",func_comm ,PSSCAN_COMM }, { 16 , "comm" ,"COMMAND",func_comm ,PSSCAN_COMM },
{ 256 , "args" ,"COMMAND",func_args ,PSSCAN_COMM }, { 256 , "args" ,"COMMAND",func_args ,PSSCAN_COMM },
{ 5 , "pid" ,"PID" ,func_pid ,PSSCAN_PID }, { 5 , "pid" ,"PID" ,func_pid ,PSSCAN_PID },
@ -284,11 +310,12 @@ static const ps_out_t out_spec[] = {
#if ENABLE_FEATURE_PS_TIME #if ENABLE_FEATURE_PS_TIME
{ sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME }, { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },
#endif #endif
// { sizeof("GROUP" )-1, "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
// { sizeof("NI" )-1, "nice" ,"NI" ,func_nice ,PSSCAN_ }, { 5 , "nice" ,"NI" ,func_nice ,PSSCAN_NICE },
// { sizeof("%CPU" )-1, "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ }, { 8 , "rgroup","RGROUP" ,func_rgroup,PSSCAN_RUIDGID },
// { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID }, { 8 , "ruser" ,"RUSER" ,func_ruser ,PSSCAN_RUIDGID },
// { sizeof("RUSER" )-1, "ruser" ,"RUSER" ,func_ruser ,PSSCAN_UIDGID }, // { 5 , "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ },
#endif
#if ENABLE_FEATURE_PS_TIME #if ENABLE_FEATURE_PS_TIME
{ 6 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME }, { 6 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME },
#endif #endif
@ -311,7 +338,7 @@ static const ps_out_t* find_out_spec(const char *name)
{ {
unsigned i; unsigned i;
for (i = 0; i < ARRAY_SIZE(out_spec); i++) { for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
if (!strcmp(name, out_spec[i].name)) if (!strncmp(name, out_spec[i].name6, 6))
return &out_spec[i]; return &out_spec[i];
} }
bb_error_msg_and_die("bad -o argument '%s'", name); bb_error_msg_and_die("bad -o argument '%s'", name);

View File

@ -871,9 +871,7 @@ enum {
| PSSCAN_UTIME | PSSCAN_UTIME
| PSSCAN_STATE | PSSCAN_STATE
| PSSCAN_COMM | PSSCAN_COMM
#if ENABLE_FEATURE_TOP_SMP_PROCESS
| PSSCAN_CPU | PSSCAN_CPU
#endif
| PSSCAN_UIDGID, | PSSCAN_UIDGID,
TOPMEM_MASK = 0 TOPMEM_MASK = 0
| PSSCAN_PID | PSSCAN_PID