Rosetta Stone API

Last update: June 2003
I figured out most of this by using strace/truss on system tools. I looked at what they called then researched those functions. Check out the rosetta stone for UNIX for a great reference for UNIX commands.

The following are the states of the supported platforms.

Linux - Up to date.
AIX - Got the new hardware (5.1L), info coming soon
Tru64 - Up to date.
HP-UX - Up to date.
Solaris - Up to date.


Good overall information getters:
Alpha:
getsysinfo() -- some documentation, but not complete. Lots more in the .h files and such than in the man page.
table() -- lots of other good stuff, like boot time, and memory info -- but I've had trouble using the memory info so far.. seems to be either wrong or uninteresting

Linux:
Most everything is in /proc. This is good and bad. It's good because everything is there and is easy to see. It's bad because it's all in text, which makes it hard to parse and get into a program, and because the format changes regularly. For what I'm trying to do, it absolutely stinks :( I'm considering writing a library for extracting this information, but I'm not sure yet. Solaris: kstat. You see if you can figure it out, because I can't.. even with the examples I found, it's still a mystery to me.


Determining platform, operating system, and other things in uname(1)

All platforms

#include <sys/utsname.h>
struct utsname {
    char sysname  [ SYS_NMLN ]; // operating system name
    char nodename [ SYS_NMLN ]; // hostname of the machine
    char release  [ SYS_NMLN ]; // version of the operating system
    char version  [ SYS_NMLN ]; // build version of OS -- not version of OS
    char machine  [ SYS_NMLN ]; // platform (alpha, x86, sparc, etc)
};

int uname ( struct utsname * buf );

CPU Info

Alpha

Determining number of CPU's:

#include <sys/sysinfo.h>
#include <machine/hal_sysinfo.h>
int nCpus = -1;
getsysinfo ( GSI_CPUS_IN_BOX,
             (caddr_t) &nCpus,
             sizeof ( nCpus ),
             NULL,
             NULL,
             NULL );
printf ( "System has %d CPUs\n", nCpus );

Determining processor speed

This gives you the speed in MHz of the processor and some other processor-related information. Use in conjunction with determining the number of CPUs to get all CPUs -- just change the 4th parameter in the table() call to what you get back from getsysinfo, and make sure to allocate enough memory to hold all the data.
#include <sys/table.h>
struct tbl_processor oProcessor;
table ( TBL_PROCESSOR_INFO, 0, & oProcessor, 1, sizeof ( oProcessor ) );
printf ( "Speed of processor (0) is %d\n", oProcessor.mhz );

Linux (2.4/2.5)

It appears that 2.4 and 2.5 have identical /proc/cpuinfo files, which is handy for us. Pretty much all CPU info is available in the cpuinfo file. `cat /proc/cpuinfo` to what information is available.

C++ Implementation

Here is a C++ implementation that gives the contents of /proc/cpuinfo in an easy-to-use std::map.

Solaris

Kstat is the holy grail of system information on Solaris, but it's nearly impossible to figure out, as far as I can tell. There's a very limited amount of documentation available. I've managed to find an example that does some good stuff, that will suffice for here, but it's too big to put inline here. Here's what it prints out, though:

CPU Type=sparcv9
CPU Speed=200
Number of cpus=1
1 minute load average=66 ( 0.26)
5 minute load average=43 ( 0.17)
15 minute load average=27 ( 0.11)
Total physical memory: pages=127808 (bytes=1047003136)
Free physical memory: pages=25228 (bytes=206667776)
Here is the sample. Compile as cc cpuinfo.c -lkstat. Note that there's an easier way to get load average information that is presented later on this page. Also, this isn't my code. I found it somehwere, because I couldn't figure out kstat (still can't -- I just use that sample code for what it can do)

HP-UX

#include <sys/param.h>
#include <sys/pstat.h>

struct pst_dynamic psd; // dynamic system info -- stuff that change change

pstat_getdynamic ( &psd, sizeof ( psd ), (size_t)1 );
printf ( "There are %ld processors\n", psd.psd_proc_cnt );
Here is a big program that prints out a bunch of stuff.

Determining boot time:

Alpha:

#include <sys/table.h>
struct tbl_sysinfo oSystemInfo; // complete desc of tbl_sysinfo is in /usr/include/sys/table.h
table ( TBL_SYSINFO, 0, & oSystemInfo, 1, sizeof ( oSystemInfo ) ); 
printf ( "System was booted %d seconds after the epoch\n", oSystemInfo.si_boottime );

Linux (2.4/2.5)

I believe again that 2.4 and 2.5 have the same format for /proc/uptime.

When you look at /proc/uptime, you'll see two numbers. The first is the uptime in seconds of the system. The second is the total idle time of the system since boot. I verified this by running a simple program that takes 100% CPU and verified that the second number in /proc/uptime stopped changing.

C++ Implementation

Here is a C++ implementation that gives the uptime and total idle time in a structure with raw seconds and broken down days/hours/minutes/seconds for uptime and idle time. Whatever.

Solaris

utmpx is your friend here.

struct utmpx *getutxent(void);

a utmpx structure looks like this:

     char                 ut_user[32];   /* user login name */
     char                 ut_id[4];      /* /etc/inittab id (usually line #) */
     char                 ut_line[32];   /* device name (console, lnxx) */
     pid_t                ut_pid;        /* process id */
     short                ut_type;       /* type of entry */
     struct exit_status   ut_exit;       /* exit status of a process */
                                         /* marked as DEAD_PROCESS */
     struct timeval       ut_tv;         /* time entry was made */
     long                 ut_session;    /* session ID, used for windowing */
     long                 pad[5];        /* reserved for future use */
     short                ut_syslen;     /* significant length of ut_host */
                                         /* including terminating null */
     char                 ut_host[257];  /* host name, if remote */
Here's a sample program to get the boot time out of utmpx
#include <utmpx.h>
int main ( )
{
  
  int nBootTime = 0;
  int nCurrentTime = time ( NULL );

  struct utmpx * ent;

  while ( ( ent = getutxent ( ) ) ) {

    if ( !strcmp ( "system boot", ent->ut_line ) ) {

      nBootTime = ent->ut_tv.tv_sec;

    }      

  }

  printf ( "System was booted %d seconds ago\n", nCurrentTime - nBootTime );

}
Here is the total output of printing out each entry in the table..

HP-UX

#include <sys/param.h>
#include <sys/pstat.h>

struct pst_static pst; // data that can't change between boots

pstat_getstatic ( &Pst, sizeof ( pst ), (size_t) 1, 0 );
printf ( "System booted %d seconds ago\n",
         time(NULL) - pst.boot_time );
Here is a program that prints out a bunch of stuff including boot time.

Memory Info

Alpha:

Total Memory

This gives you the memory installed in bytes. Full info for the struct tbl_pmemstats is in /usr/include/sys/table.h
struct tbl_pmemstats oMemStats;
table ( TBL_PMEMSTATS, 0, & oMemStats, 1, sizeof ( oMemStats ) );
printf ( "Total memory on system: %ld\n", oMemStats.physmem ); // note it's a 64-bit signed

Linux 2.4.x

All memory info is in /proc/meminfo. This format has changed in 2.5, though. Here's how to do it in 2.4.x.

Here's the format for /proc/meminfo in 2.4.x

        total:    used:    free:  shared: buffers:  cached:
Mem:  1580699648 1568923648 11776000 231284736 146837504 982405120
Swap: 2146787328        0 2146787328
MemTotal:      1543652 kB
MemFree:         11500 kB
MemShared:      225864 kB
Buffers:        143396 kB
Cached:         959380 kB
SwapCached:          0 kB
Active:          75932 kB
Inact_dirty:    785916 kB
Inact_clean:    466792 kB
Inact_target:      124 kB
HighTotal:      654528 kB
HighFree:         4532 kB
LowTotal:       889124 kB
LowFree:          6968 kB
SwapTotal:     2096472 kB
SwapFree:      2096472 kB
NrSwapPages:    524118 pages

C++ Implementation:

Here is a sample read implementation for getting memory info from Linux.

Solaris

_sysconfig comes through in a pinch. This one's easy.


#include <sys/sysconfig.h>

int main ( )
{

    printf ( "Total memory installed is %d bytes\n",
    _sysconfig(_CONFIG_PAGESIZE) *
    _sysconfig(_CONFIG_PHYS_PAGES) );

}

HP-UX

#include <sys/param.h>
#include <sys/pstat.h>

struct pst_static pst; // data that can't change between boots

pstat_getstatic ( &Pst, sizeof ( pst ), (size_t) 1, 0 );
printf ( "System has %d KB of memory\n",
         pst.physical_memory * pst.page_size );
Here is a big program that prints out a bunch of stuff.

Getting the Load Average

Load average is a number representing how busy the computer is. People seem to be constantly arguing over exactly what it means. Here's what I know: If the load is greater than the number of processors, the machine is probably pretty busy. Now, some computers behave better under load than others. If a Linux box says it has a load of one on a single processor box, you're not going to get much done. However, a single processor SUN box can have a load of ten and still be useable. Not sure exactly how that works out.

Alpha

struct tbl_loadavg oLoadAverage;

table ( TBL_LOADAVG, 0, & oLoadAverage, 1, sizeof ( struct tbl_loadavg ) );

// if tl_scale is non-zero, it's in been multiplied out to make an int
printf ( "1-minute avg: %lf", oLoadAverage.tl_lscale == 0 ? 
         oLoadAverage.tl_avenrun.d [ 0 ] : 
         (double) ( oLoadAverage.tl_avenrun.l [ 0 ] / ( (double) oLoadAverage.tl_lscale ) ) );
	
// if tl_scale is non-zero, it's in been multiplied out to make an int
printf ( "5-minute avg: %lf", oLoadAverage.tl_lscale == 0 ? 
         oLoadAverage.tl_avenrun.d [ 1 ] : 
         (double) ( oLoadAverage.tl_avenrun.l [ 1 ] / ( (double) oLoadAverage.tl_lscale ) ) );
		
// if tl_scale is non-zero, it's in been multiplied out to make an int
printf ( "15-minute avg: %lf", oLoadAverage.tl_lscale == 0 ? 
         oLoadAverage.tl_avenrun.d [ 2 ] : 
         (double) ( oLoadAverage.tl_avenrun.l [ 2 ] / ( (double) oLoadAverage.tl_lscale ) ) );

Linux

The load information on Linux can be found in /proc/loadavg. The first three entries are the one, five, and fifteen minute load averages. The fourth number is the number of running processes / total number of processes. The fifth number is the highest PID used.
#include <iostream>
#include <fstream>
#include <stdio.h>

int main()
{

    std::ifstream loadavg ( "/proc/loadavg" );

    double oneminute;
    double fiveminute;
    double fifteenminute;
    int running;
    char slash;
    int total;
    int highpid;

    loadavg >> oneminute >> fiveminute >> fifteenminute >> running >> slash >>
               total >> highpid;

    printf ( "1-minute avg: %lf\n5-minute avg: %lf\n15-minute avg: %lf\n"
             "running processes: %d\ntotal processes: %d\nhigh PID: %d\n",
             oneminute, fiveminute, fifteenminute, running, total, highpid );

}

Solaris

getloadavg. Simple as that.
#include 

int getloadavg(double loadavg[], int nelem);
Just make an array of 3 doubles, pass that in as the first argument, and send in "3" as the second argument, saying that you're giving it 3 doubles worth of space and *presto* you've got your 1,5, and 15 minute averages. Sun docs here

HP-UX

HP-UX

#include <sys/param.h>
#include <sys/pstat.h>

struct pst_dynamic psd; // dynamic system info -- stuff that change change

pstat_getdynamic ( &psd, sizeof ( psd ), (size_t)1 );
printf ( "1-minute: %lf, 5-minute: %lf, 15-minute: %lf\n",
         psd.psd_avg_1_min,
         psd.psd_avg_5_min,
         psd.psd_avg_15_min );
Here is a big program that prints out a bunch of stuff.
Thank you for reading the Rosetta Stone API. Have a nice day.