This program (rc-03) uses the Solaris interface to resource control.
It lists all the controls that are active to its running process.
Following the listing there's a sample output.
#include <rctl.h>
#include <alloca.h>
#include <cstdlib>
#include <cerrno>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <iostream>
#include <iomanip>
//
// Convenience "special" vector.
//
template< typename T >
struct vector : public std::vector< T >
{
};
//
// Convenience operator for just the "special" vector.
// For simplicity, not dealing with formatting or state issues.
//
template< typename T >
std::istream & operator >> ( std::istream & is, vector<T> & v )
{
typename vector<T>::value_type element;
if ( is >> element )
v.push_back( element );
return is;
}
//
// The main data structure for organization.
// Key: resource containment.
// Data: list of controls.
//
std::map< const std::string, vector< std::string > > resource;
//
// The resource walking routine.
//
int active( const char * name, void * )
{
std::istringstream iss( name );
std::string containment;
if ( std::getline( iss, containment, '.' ) )
iss >> resource[ containment ];
return 0;
}
const size_t size = ::rctlblk_size( );
typedef ::rctlblk_t * p_blk;
// May suffer from stream formatting issues...
void print_limit( const p_blk rl )
{
//
// Type
//
std::cout
<< "\t\t"
<< std::setw( 11 ) << std::left;
switch ( ::rctlblk_get_privilege( rl ) )
{
case RCPRIV_BASIC:
std::cout << "basic";
break;
case RCPRIV_PRIVILEGED:
std::cout << "privileged";
break;
case RCPRIV_SYSTEM:
std::cout << "system";
break;
}
//
// Value
//
std::cout
<< ":"
<< std::setw( 21 ) << std::right
<< ::rctlblk_get_value( rl );
std::cout
<< std::endl;
std::cout
<< std::setw( 0 ) << std::left;
}
// May suffer from stream formatting issues...
void print_control( std::string containment,
vector< std::string > & control_list )
{
p_blk rl = static_cast < p_blk >
(
// Never leaks memory
::alloca( size )
);
containment += ".";
std::sort( control_list.begin( ), control_list.end( ) );
for ( auto & control : control_list )
{
std::cout
<< "\t";
std::cout
<< std::setw( 32 ) << std::left
<< control;
const std::string name = containment + control;
p_blk p = 0; // Tracking pointer
int rv = ::getrctl( name.c_str(), p, rl, RCTL_FIRST );
const int gflags = ::rctlblk_get_global_flags( rl );
std::cout
<< std::setw( 9 ) << std::right
<<
(
gflags & RCTL_GLOBAL_BYTES ? "(bytes)" :
gflags & RCTL_GLOBAL_SECONDS ? "(seconds)" :
gflags & RCTL_GLOBAL_COUNT ? "(count)" :
"(?)"
)
<< std::endl;
std::cout
<< std::setw( 0 ) << std::left;
while ( rv == 0 )
{
print_limit( rl );
p = rl; // Smart(?) move...
rv = ::getrctl( name.c_str(), p, rl, RCTL_NEXT );
}
if ( errno != ENOENT )
std::cout
<< "\t\tError getting limits!"
<< std::endl;
std::cout
<< std::endl;
}
}
// May suffer from stream formatting issues...
void print( )
{
std::cout
<< std::endl
<< "Printing active resource controls..."
<< std::endl
<< std::endl;
// I want to list containments as ordered below
auto known = { "process", "task", "project", "zone" };
for ( auto & containment : known )
{
std::cout
<< containment
<< std::endl
<< std::endl;
print_control( containment, resource[ containment ] );
}
//
// In case new (currently unknown) containments appear
// in the future, just list them at the bottom.
//
for ( auto & r : resource )
{
auto c = r.first; // A containment
if ( std::none_of( known.begin( ), known.end( ),
[ &c ]( const char * s ) { return s == c; } ) )
{
std::cout
<< c // An unknown containment
<< std::endl
<< std::endl;
print_control( r.first, r.second );
}
}
}
// May suffer from stream formatting issues...
int main( )
{
std::cout
<< std::endl
<< "Gathering active resource controls..."
<< std::endl
<< std::endl;
std::cout
<< "\tRC walk starting..."
<< std::endl;
if ( ::rctl_walk( active, 0 ) == 0 )
std::cout
<< "\tRC walk completed successfuly!"
<< std::endl;
print( );
return EXIT_SUCCESS;
}
A possible output is:
$ ./rc-03
Gathering active resource controls...
RC walk starting...
RC walk completed successfuly!
Printing active resource controls...
process
max-address-space (bytes)
privileged : 18446744073709551615
system : 18446744073709551615
max-core-size (bytes)
privileged : 9223372036854775807
system : 9223372036854775807
max-cpu-time (seconds)
privileged : 18446744073709551615
system : 18446744073709551615
max-data-size (bytes)
privileged : 18446744073709551615
system : 18446744073709551615
max-deferred-posts (count)
basic : 32
privileged : 100
system : 8192
max-file-descriptor (count)
basic : 1024
privileged : 65536
system : 2147483647
max-file-size (bytes)
privileged : 9223372036854775807
system : 9223372036854775807
max-itimers (count)
privileged : 1000
system : 65536
max-msg-messages (count)
privileged : 8192
system : 4294967295
max-msg-qbytes (bytes)
privileged : 65536
system : 18446744073709551615
max-port-events (count)
privileged : 65536
system : 2147483647
max-sem-nsems (count)
privileged : 512
system : 32767
max-sem-ops (count)
privileged : 512
system : 2147483647
max-sigqueue-size (count)
basic : 128
privileged : 512
system : 8192
max-stack-size (bytes)
basic : 8388608
privileged : 1098437885952
system : 1098437885952
task
max-cpu-time (seconds)
system : 18446744073709551615
max-lwps (count)
system : 2147483647
max-processes (count)
system : 2147483647
project
cpu-cap (count)
system : 4294967295
cpu-shares (count)
privileged : 1
system : 65535
max-contracts (count)
privileged : 10000
system : 2147483647
max-crypto-memory (bytes)
privileged : 2143089664
system : 18446744073709551615
max-locked-memory (bytes)
system : 18446744073709551615
max-lwps (count)
system : 2147483647
max-mrp-ids (count)
privileged : 128
system : 16777216
max-msg-ids (count)
privileged : 128
system : 16777216
max-port-ids (count)
privileged : 8192
system : 65536
max-processes (count)
system : 2147483647
max-sem-ids (count)
privileged : 128
system : 16777216
max-shm-ids (count)
privileged : 128
system : 16777216
max-shm-memory (bytes)
privileged : 2143089664
system : 18446744073709551615
max-tasks (count)
system : 2147483647
zone
cpu-cap (count)
system : 4294967295
cpu-shares (count)
privileged : 1
system : 65535
max-locked-memory (bytes)
system : 18446744073709551615
max-lofi (count)
system : 18446744073709551615
max-lwps (count)
system : 2147483647
max-mrp-ids (count)
system : 16777216
max-msg-ids (count)
system : 16777216
max-processes (count)
system : 2147483647
max-sem-ids (count)
system : 16777216
max-shm-ids (count)
system : 16777216
max-shm-memory (bytes)
system : 18446744073709551615
max-swap (bytes)
system : 18446744073709551615