Tuesday, April 27, 2010

Reading from the commandline in C

What's the best way to read the output from a commandline command in C? If you use the int system(char*) function you receive back a return code, not the output. Not much use. To receive the output you could call freopen on STDOUT, then read from the file you redirected it to. But when you close the file (which you must), STDOUT is left in a broken state. There has to be a better way, and there is. You use popen, instead of system. Then, the output of the command is supplied via the FILE handle returned by popen. Here's an example that finds out the memory usage of the firefox process under Linux:

#include <stdio.h>
#include <string.h>
static char sysCmd[256];
 * Issue a system command to get memory usage
 * @return the percent value times 100
int get_memory()
    int res = 0;
    float percent;
    sysCmd[0] = 0;
    strcat( sysCmd, "ps aux | awk '{if ($11 ~ /" );
    strcat( sysCmd, "firefox" );
    strcat( sysCmd, "/&& !/awk/) {print $4}}'" );
    FILE *CONSOLE = popen( sysCmd, "r" );
    if ( CONSOLE != NULL )
        res = fscanf( CONSOLE, "%f", &percent );
        if ( res <=0 )
            syslog(LOG_ALERT,"Failed to parse result of %s\n",sysCmd);
        pclose( CONSOLE );
        res = (int)(percent * 100.0f);
        syslog(LOG_ALERT,"Failed to open pipe for %s\n",sysCmd);
    return res;

Monday, April 12, 2010

Adding or removing portlets from a page programmatically in Pluto

What I wanted to do in the dosTF portal was to add or remove portlets, which in my case were monitoring applets, in response to the contents of the loaded scenario. If an experiment called for monitoring of a particular SNMP parameter, I wanted to be able to automatically add the monitoring portlet and configure it to monitor the correct parameter on the correct target. But it seems that Pluto is designed rather simply to prevent that. You are supposed to add portlets in the GUI, which kind of defeats the whole purpose of saving the experiment in an XML file. I needed to restore the state of the experiment from the XML and to do that I needed to add or remove portlets from the page programmatically.

Pluto has an undocumented way to do this. There is the PageConfig class used by the Pluto Page Admin portlet. It gets the correct instance of this class from the portlet context:

PortletContext pc = getPortletContext();
DriverConfiguration driverConfig = 
    (DriverConfiguration) pc.getAttribute("driverConfig");
PageConfig config = driverConfig.getPageConfig( "About Apache Pluto" );

The problem with this code is that only the Pluto application has access to the relevant portlet context. You can't get access to it from another application containing another portlet. So, to get around this, I simply copied my ScenarioEditor portlet into the pluto application and hey presto, it works! Removing a portlet is a bit harder. You have to get the portlet ids on the page from the PageConfig and then note the differences before and after. Then record the portlet id of the newly added portlet. It would make more sense if addPortlet just returned the portlet id.

However, configuring the portlet before display seems to be hard with this method. Maybe there is some way but PageConfig doesn't seem to have any knowledge of the 'portlet' itself, just its portlet id. But I'll leave that problem for the next post.