ps: Support -o option to customize team info columns

* Add option -o to customize team info columns output;
* Fixes #10156.

- GCI 2013
This commit is contained in:
Thomas Schmidt
2013-12-10 21:25:15 +01:00
committed by Siarzhuk Zharski
parent f43a6c9aab
commit ab967391f4
+108 -39
View File
@@ -6,6 +6,7 @@
* Francois Revol (mmu_man) * Francois Revol (mmu_man)
* Salvatore Benedetto <[email protected]> * Salvatore Benedetto <[email protected]>
* Bjoern Herzig (xRaich[o]2x) * Bjoern Herzig (xRaich[o]2x)
* Thomas Schmidt <[email protected]>
*/ */
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@@ -13,34 +14,82 @@
#include <OS.h> #include <OS.h>
#define SNOOZE_TIME 100000
char *sStates[] = {"run", "rdy", "msg", "zzz", "sus", "wait" }; enum {
Team = 0,
Id,
Threads,
Gid,
Uid
};
struct ColumnIndo {
const char* name;
const char* header;
const char* format;
} Infos[] = {
{ "Team", "%-50s", "%-50s" },
{ "Id", "%5s", "%5" B_PRId32 },
{ "Threads", "#%7s", "%8" B_PRId32 },
{ "Gid", "%4s", "%4d" },
{ "Uid", "%4s", "%4d" }
};
#define maxColumns 10
int Columns[maxColumns] = { Team, Id, Threads, Gid, Uid, 0 };
int ColumnsCount = 5;
const char* sStates[] = {"run", "rdy", "msg", "zzz", "sus", "wait"};
static void printTeamThreads(team_info* teamInfo, bool printSemaphoreInfo);
static void printTeamInfo(team_info* teamInfo, bool printHeader);
static void printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo);
static void printTeamInfo(team_info *teamInfo, bool printHeader);
static void static void
printTeamInfo(team_info *teamInfo, bool printHeader) printTeamInfo(team_info* teamInfo, bool printHeader)
{ {
// Print team info int i = 0;
if (printHeader) if (printHeader) {
printf("%-50s %5s %8s %4s %4s\n", "Team", "Id", "#Threads", "Gid", \ for (i = 0; i < ColumnsCount; i++) {
"Uid"); printf(Infos[Columns[i]].header, Infos[Columns[i]].name);
putchar(' ');
printf("%-50s %5" B_PRId32 " %8" B_PRId32 " %4d %4d\n", teamInfo->args, }
teamInfo->team, teamInfo->thread_count, teamInfo->gid, teamInfo->uid); puts("");
}
for (i = 0; i < ColumnsCount; i++) {
switch (Columns[i]) {
case Team:
printf(Infos[Team].format, teamInfo->args);
break;
case Id:
printf(Infos[Id].format, teamInfo->team);
break;
case Threads:
printf(Infos[Threads].format, teamInfo->thread_count);
break;
case Gid:
printf(Infos[Gid].format, teamInfo->gid);
break;
case Uid:
printf(Infos[Uid].format, teamInfo->uid);
break;
}
putchar(' ');
}
puts("");
} }
static void static void
printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo) printTeamThreads(team_info* teamInfo, bool printSemaphoreInfo)
{ {
char *threadState; const char* threadState;
int32 threadCookie = 0; int32 threadCookie = 0;
sem_info semaphoreInfo; sem_info semaphoreInfo;
thread_info threadInfo; thread_info threadInfo;
// Print all info about its threads too // Print all info about its threads too
while (get_next_thread_info(teamInfo->team, &threadCookie, &threadInfo) while (get_next_thread_info(teamInfo->team, &threadCookie, &threadInfo)
>= B_OK) { >= B_OK) {
@@ -73,8 +122,9 @@ printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo)
} }
} }
int int
main(int argc, char **argv) main(int argc, char** argv)
{ {
team_info teamInfo; team_info teamInfo;
int32 teamCookie = 0; int32 teamCookie = 0;
@@ -83,23 +133,25 @@ main(int argc, char **argv)
bool printThreads = false; bool printThreads = false;
bool printHeader = true; bool printHeader = true;
bool printSemaphoreInfo = false; bool printSemaphoreInfo = false;
bool customizeColumns = false;
// match this in team name // match this in team name
char *string_to_match; char* string_to_match;
int c; int c;
while ((c = getopt(argc, argv,"ihas")) != EOF) { while ((c = getopt(argc, argv, "-ihaso:")) != EOF) {
switch(c) { switch (c) {
case 'i': case 'i':
printSystemInfo = true; printSystemInfo = true;
break; break;
case 'h': case 'h':
printf( "usage: ps [-hais] [team]\n" printf( "usage: ps [-hais] [-o columns list] [team]\n"
"-h : show help\n" "-h : show help\n"
"-i : show system info\n" "-i : show system info\n"
"-s : show semaphore info\n" "-s : show semaphore info\n"
"-a : show threads too (by default only teams are " \ "-o : display team info associated with the list\n"
"displayed)\n"); "-a : show threads too (by default only teams are "
"displayed)\n");
return 0; return 0;
break; break;
case 'a': case 'a':
@@ -108,27 +160,45 @@ main(int argc, char **argv)
case 's': case 's':
printSemaphoreInfo = true; printSemaphoreInfo = true;
break; break;
case 'o':
if (!customizeColumns)
ColumnsCount = 0;
customizeColumns = true;
/* fallthrough */
case 1:
{
size_t i = 0;
if (c == 1 && !customizeColumns)
break;
for (i = 0; i < sizeof(Infos) / sizeof(Infos[0]); i++)
if (strcmp(optarg, Infos[i].name) == 0
&& ColumnsCount < maxColumns) {
Columns[ColumnsCount++] = i;
continue;
}
break;
}
} }
} }
// TODO: parse command line // TODO: parse command line
// Possible command line options: // Possible command line options:
// -t pstree like output // -t pstree like output
if (argc == 2 && (printSystemInfo||printThreads)) if (argc == 2 && (printSystemInfo || printThreads))
string_to_match = NULL; string_to_match = NULL;
else else
string_to_match = (argc >= 2) ? argv[argc-1] : NULL; string_to_match = (argc >= 2 && !customizeColumns)
? argv[argc - 1] : NULL;
if (!string_to_match) { if (!string_to_match) {
while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) { while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
printTeamInfo(&teamInfo, printHeader);
printTeamInfo(&teamInfo,printHeader);
printHeader = false; printHeader = false;
if (printThreads) { if (printThreads) {
printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", \ printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", \
"State", "Prio", "UTime", "KTime"); "State", "Prio", "UTime", "KTime");
printTeamThreads(&teamInfo,printSemaphoreInfo); printTeamThreads(&teamInfo, printSemaphoreInfo);
printf("----------------------------------------------" \ printf("----------------------------------------------" \
"-----------------------------\n"); "-----------------------------\n");
printHeader = true; printHeader = true;
@@ -136,8 +206,7 @@ main(int argc, char **argv)
} }
} else { } else {
while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) { while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
char *p; char* p = teamInfo.args;
p = teamInfo.args;
if ((p = strchr(p, ' '))) if ((p = strchr(p, ' ')))
*p = '\0'; /* remove arguments, keep only argv[0] */ *p = '\0'; /* remove arguments, keep only argv[0] */
p = strrchr(teamInfo.args, '/'); /* forget the path */ p = strrchr(teamInfo.args, '/'); /* forget the path */
@@ -145,10 +214,10 @@ main(int argc, char **argv)
p = teamInfo.args; p = teamInfo.args;
if (strstr(p, string_to_match) == NULL) if (strstr(p, string_to_match) == NULL)
continue; continue;
printTeamInfo(&teamInfo,true); printTeamInfo(&teamInfo, true);
printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", "State", \ printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", "State", \
"Prio", "UTime", "KTime"); "Prio", "UTime", "KTime");
printTeamThreads(&teamInfo,printSemaphoreInfo); printTeamThreads(&teamInfo, printSemaphoreInfo);
} }
} }