[haiku-development] [PATCH] Enhanced ps

  • From: "xRaich[o]2x" <raichoo@xxxxxxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Tue, 17 Feb 2009 05:19:00 +0100

Hi, i've enhanced ps a little bit. added -a flag that outputs all teams
and their threads and help message. i also turned off semaphore and
system info by default (can be re-enabled with -s and -i as proposed in
the TODO list). dunno if this is useful. i just wanted to get used
coding for haiku a little bit. i also made the id field wider by one
character since output got a little awkward when IDs exceeded 4 digits.
(might need some more makeovers)

This is my very first patch, i hope i'm doing everything right.
otherwise i'd really like some pointers :)

Regards,
Björn


/*
 * Copyright 2002-2008, Haiku Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *              Francois Revol (mmu_man)
 *              Salvatore Benedetto <salvatore.benedetto@xxxxxxxxx>
 *              Bjoern Herzig (xRaich[o]2x)
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include <OS.h>

#define SNOOZE_TIME 100000

char *states[] = {"run", "rdy", "msg", "zzz", "sus", "wait" };

void printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo); 
void printTeamInfo(team_info *teamInfo, bool printHeader);

void printTeamInfo(team_info *teamInfo, bool printHeader)
{
        // Print team info
        if (printHeader)
                printf("%-49s %5s %8s %4s %4s\n", "Team", "Id", "#Threads", 
"Gid", "Uid");
                
        printf("%-49s %5ld %8ld %4d %4d\n", teamInfo->args, teamInfo->team,
                teamInfo->thread_count, teamInfo->uid, teamInfo->gid);
}

void printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo) {
        char *threadState;
        uint32 threadCookie = 0;
        sem_info semaphoreInfo;
        thread_info threadInfo;
        
        // Print all info about its threads too
        while (get_next_thread_info(teamInfo->team, &threadCookie, &threadInfo)
                >= B_OK) {
                if (threadInfo.state < B_THREAD_RUNNING
                        || threadInfo.state > B_THREAD_WAITING)
                        // This should never happen
                        threadState = "???";
                else
                        threadState = states[threadInfo.state - 1];

                printf("%-29s %5ld %8s %4ld %8llu %8llu ",
                        threadInfo.name, threadInfo.thread, threadState,
                        threadInfo.priority, (threadInfo.user_time / 1000),
                        (threadInfo.kernel_time / 1000));

                if (printSemaphoreInfo) {
                        if (threadInfo.state == B_THREAD_WAITING && 
threadInfo.sem != -1) {
                                status_t status = get_sem_info(threadInfo.sem, 
&semaphoreInfo);
                                if (status == B_OK)
                                        printf("%s(%ld)\n", semaphoreInfo.name, 
semaphoreInfo.sem);
                                else
                                        printf("%s(%ld)\n", strerror(status), 
threadInfo.sem);
                        } else
                                puts("");
                }
                else
                        puts("");
        }
}

int main(int argc, char **argv)
{
        team_info teamInfo;
        uint32 teamCookie = 0;
        system_info systemInfo;
        bool printSystemInfo = false;
        bool printThreads = false;
        bool printHeader = true;
        bool printSemaphoreInfo = false;
        // match this in team name
        char *string_to_match;
        
        int c;
        
        while ((c = getopt(argc, argv,"ihas")) != EOF) {
                switch(c) {
                        case 'i':
                                printSystemInfo = true;
                                break;
                        case 'h':
                                printf( "usage: ps [-hais] [team]\n"
                                                "-h : show help\n"
                                                "-i : show system info\n"
                                                "-s : show semaphore info\n"
                                                "-a : show threads too (by 
default only teams are displayed)\n");
                                return 0;
                                break;
                        case 'a':
                                printThreads = true;
                                break;
                        case 's':
                                printSemaphoreInfo = true;
                                break;
                }
        }

        // TODO: parse command line
        // Possible command line options:
        //              -h      show help
        //                      ps                      - by default it only 
shows all team info
        //                      ps [team]       - shows info about this team 
with all its threads
        //              -t      pstree like output
        //              -a      show threads too (by default only teams are 
displayed)
        //              -s      show semaphore info
        //              -i      show system info
        
        if (argc == 2 && (printSystemInfo||printThreads))
                string_to_match = NULL;
        else
                string_to_match = (argc >= 2) ? argv[argc-1] : NULL;
        
        if (!string_to_match) {
                while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
                        
                        printTeamInfo(&teamInfo,printHeader);
                        printHeader = false;
                        if (printThreads) {
                                printf("\n%-29s %5s %8s %4s %8s %8s\n", 
"Thread", "Id", "State","Prio", "UTime", "KTime");
                                printTeamThreads(&teamInfo,printSemaphoreInfo);
                                
printf("--------------------------------------------------------------------------\n");
                                printHeader = true;
                        }
                }
        }
        else {
                while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
                        char *p;
                        p = teamInfo.args;
                        if ((p = strchr(p, ' ')))
                                *p = '\0'; /* remove arguments, keep only 
argv[0] */
                        p = strrchr(teamInfo.args, '/'); /* forget the path */
                        if (p == NULL)
                                p = teamInfo.args;
                        if (strstr(p, string_to_match) == NULL)
                                continue;
                        printTeamInfo(&teamInfo,true);
                        printf("\n%-29s %5s %8s %4s %8s %8s\n", "Thread", "Id", 
"State","Prio", "UTime", "KTime");
                        printTeamThreads(&teamInfo,printSemaphoreInfo);
                }
        }

        if (printSystemInfo) {
                // system stats
                get_system_info(&systemInfo);
                printf("\nSystem Info\n");
                printf("%luk (%lu bytes) total memory\n",
                        (systemInfo.max_pages * B_PAGE_SIZE / 1024),
                        (systemInfo.max_pages * B_PAGE_SIZE));
                printf("%luk (%lu bytes) currently committed\n",
                        (systemInfo.used_pages * B_PAGE_SIZE / 1024),
                        (systemInfo.used_pages * B_PAGE_SIZE));
                printf("%luk (%lu bytes) currently available\n",
                        (systemInfo.max_pages - systemInfo.used_pages) * 
B_PAGE_SIZE / 1024,
                        (systemInfo.max_pages - systemInfo.used_pages) * 
B_PAGE_SIZE);
                printf("%2.1f%% memory utilisation\n",
                        (float)100 * systemInfo.used_pages / 
systemInfo.max_pages);
        }
        return 0;
}

Other related posts: