vpr Namespace Reference


Classes

class  LibraryFinder
 Helper class that will perform dynamic library discovery based on a file extension (e.g., .so or .dll) in a specific directory. More...
class  LibraryLoader
 A helper for loading a specific class of dynamic shared objects (DSOs). More...
class  LoaderError
 Error reporting class for dynamic library loading. More...
class  BlockIO
 Block-style (as opposed to streaming) I/O interface. More...
class  BufferObjectReader
 Object reader that reads out of a data buffer. More...
class  BufferObjectWriter
 Object writer for data buffers. More...
class  FileHandle_t
 Extension to the vpr::BlockIO interface defining a cross-platform file handle interface. More...
class  IOSysBase
 Base class for all for the IOSys class. More...
class  ObjectReader
 Interface used to read object data from a stream. More...
class  ObjectWriter
 Interface used to write object data to a stream. More...
class  Port
 A cross-platform interface to using a computer's I/O ports (serial, parallel, IR, etc. More...
class  SerialPort_t
 Cross-platform serial port interface. More...
class  Selector_t
 Cross-platform selection interface. More...
class  SelectorBase
 Common base for all selectors and implementations. More...
class  WriteableObject
 The abstract base class for all types that can be written to a stream. More...
class  ReadableObject
 The abstract base class for all types that can be read from a stream. More...
class  SerializableObject
 The abstract base class for all types that support serialization. More...
class  SerializableObjectMixin
 Mix-in type to add serialization capabilities to an existing type, usually one that is defined in third-party code and therefore cannot have its base type list modified. More...
struct  InetAddrHash
 Nice little helper class for hashing a vpr::InetAddr. More...
class  InetAddrBase
 Cross-platform abstraction to Internet address structures. More...
class  McastReq
 Multicast request wrapper. More...
class  Socket_t
 Cross-platform block-based socket interface. More...
class  SocketAcceptor
 Socket connection acceptor factory. More...
class  SocketBasicOpt
 Options common to all types of sockets. More...
class  SocketConnector
 Defines a factory for creating new connections both synchronously and asynchronously. More...
class  SocketDatagram_t
 Datagram socket interface. More...
class  SocketDatagramOpt
 Options for datagram sockets. More...
class  SocketIpOpt
 IP-level options for sockets. More...
class  SocketOptionWrapper
 Simple interface for setting and querying socket options. More...
class  SocketStream_t
 Cross-platform stream socket class. More...
class  SocketStreamOpt
 Options for stream sockets. More...
class  BandwidthIOStatsStrategy
 Strategy for collecting bandwidth data about the block I/O device. More...
class  BaseIOStatsStrategy
 Base interface for IO Stat collection. More...
class  NullIOStatsStrategy
 Null strategy. More...
class  IOStatsStrategyAdapter
 This is a template adapter that combines two I/O Stats strategies together into a single class. More...
class  XMLObjectReader
 Object reader that reads out of a data buffer. More...
class  XMLObjectWriter
 Object writer for data buffers. More...
class  LibraryDYLD
 Low-level class for loading symbols dynamically. More...
class  LibraryNSPR
 Low-level class for loading symbols dynamically. More...
class  IOSysNSPR
 Wrapper around NSPR file descriptors. More...
class  SelectorImplNSPR
 NSPR Implementation of cross-platform selection interface. More...
class  InetAddrNSPR
 Cross-platform abstraction to Internet address structures. More...
class  SocketDatagramImplNSPR
 NSPR implementation of the datagram socket interface. More...
class  SocketImplNSPR
 NSPR implementation of the base socket interface. More...
class  SocketStreamImplNSPR
 NSPR implementation of the stream-oriented socket interface. More...
class  CondVarNSPR
 Condition variable wrapper for NSPR condition variables. More...
class  MutexNSPR
 Mutex wrapper for NSPR locks. More...
class  RWMutexNSPR
 Read/write mutex implementation using NSPR read/write mutexes (PRRWLock). More...
class  SemaphoreNSPR
 Wrapper for semaphores implemented using condition variables. More...
class  SystemNSPR
 Low-level operating system feature abstractions using NSPR functionality. More...
class  ThreadKeyNSPR
 Wrapper around NSPR thread-specific data. More...
class  ThreadNSPR
 Threads implementation using the NSPR API. More...
class  ErrorImplNSPR
 NSPR Implementation of a cross-platform error reporting class. More...
class  LibraryUNIX
 Low-level class for loading symbols dynamically. More...
class  FileHandleImplUNIX
 Wrapper around UNIX file descriptors. More...
class  IOSysUnix
 Wrapper around UNIX file descriptors. More...
class  SerialPortImplTermios
 vpr::SerialPort implementation using termios. More...
class  SelectorImplBSD
 BSD Implementation of cross-platform selection interface. More...
class  InetAddrBSD
 Cross-platform abstraction to Internet address structures. More...
class  SocketDatagramImplBSD
 Implementation class for datagram sockets using the BSD sockets interface. More...
union  sockopt_data
 Define a simple union used as the optval argument to [gs]etsockopt(2). More...
class  SocketImplBSD
 Basic socket wrapper implementation for BSD sockets. More...
class  SocketStreamImplBSD
 Implementation of the stream socket wrapper using BSD sockets. More...
class  CondVarPosix
 Condition variable wrapper for POSIX-compliant systems using pthreads condition variables for the implementation. More...
class  MutexPosix
 Mutex wrapper for POSIX-compliant systems using pthreads mutex variables for the implementation. More...
class  RWMutexPosix
 RWMutex wrapper for POSIX-compliant systems using pthreads rw mutex variables for the implementation. More...
class  SemaphorePosix
 Semaphore wrapper for POSIX.4-compliant systems. More...
class  SystemPosix
 Low-level operating system feature abstractions using POSIX functionality. More...
class  ThreadKeyPosix
 Wrapper around pthread keys (thread-specific data). More...
class  ThreadPosix
 Threads implementation using POSIX threads (both Draft 4 and the "final" draft of the standard are supported). More...
class  ErrorImplPosix
 POSIX Implementation of cross-platform error reporting class. More...
class  IOSysSIM
 Wrapper around simulated file descriptors. More...
class  SelectorImplSIM
 Implementation of a selector for simulated sockets. More...
class  InetAddrSIM
 Simulated Internet address structures. More...
class  SocketDatagramImplSIM
 Implementation of datagram sockets using simulated sockets. More...
class  SocketImplSIM
 Implementation class for simulated sockets. More...
class  SocketStreamImplSIM
 Implementation of stream sockets using simulated sockets. More...
class  MemPool
 Shared memory pool. More...
class  MemPoolSGI
 Shared Memory pool on the SGI systems, used primarily for semaphores and mutexes. More...
class  BarrierSGI
 Barrier wrapper for SGI. More...
class  MutexSGI
 Mutex wrapper for the SGI systems. More...
class  SemaphoreSGI
 Semaphore wrapper for the SGI systems. More...
class  ThreadKeySGI
 Wrapper around SPROC thread-specific data. More...
class  ThreadSGI
 Threads implementation using multiple processes created with sproc(2). More...
class  SerialPortImplWin32
 vpr::SerialPort implementation for Win32. More...
class  ProfileIterator
 An iterator to navigate through the Profile tree. More...
class  ProfileManager
 Global static facade for using the profiling code. More...
class  ProfileSample
 ProfileSample is a guard style class for handle a single sample. More...
class  ProfileNode
 A node in the Profile Hierarchy Tree. More...
class  CondVarGeneric
 Condition Variable wrapper for the any system. More...
class  Guard
 Guard wrapper. More...
class  GuardedQueue
 A guarded queue. More...
class  NullMutex
 Null mutex wrapper. More...
class  ReadGuard
 Read Guard wrapper. More...
class  WriteGuard
 Write Guard wrapper. More...
struct  TimeVal
 A data structure for storing the time value returned by vpr::System::gettimeofday(). More...
struct  TimeZone
 A data structure for storing the time zone returned by vpr::System::gettimeofday(). More...
class  SystemBase
 vpr::SystemBase is a base class for vpr::System. More...
class  BaseThread
 Base class for all thread implementations. More...
class  SignalSet
 Wrapper class for a signal set. More...
class  SignalAction
 Wrapper class for a signal action. More...
class  SigHandler
 This class wraps the calls needed to register signal handlers with the operating system. More...
class  BaseThreadFunctor
 Converts a function into a functor that can be passed to a extern C type function to be called by a thread creation routine. More...
class  ThreadMemberFunctor
 Member functor class. More...
class  ThreadRunFunctor
 A variation on vpr::ThreadMemberFunctor that requires a class that implements the "runnable" concept. More...
class  ThreadNonMemberFunctor
 Nonmember functor class. More...
class  ThreadManager
 Holds list of all threads in system. More...
class  OneThread
 Helper class for vpr::ThreadPool. More...
class  ThreadPool
 A pool of threads to process user jobs. More...
class  TSBaseObject
 Base thread-specific object. More...
class  TSObject
 Wrapper template for storing thread-specific objects. More...
class  TSObjectProxyBase
 Base class for all thread-specific object proxies. More...
class  TSObjectProxy
 This is a smart pointer to a thread-specific object. More...
class  TSTable
 This class is the actual thread-specific table. More...
class  AttributeMapBase
 Basic interface for adding attributes to classes. More...
class  DateTime
 Simple wrapper around time since the UNIX Epoch (00:00 UTC January 1, 1970). More...
struct  DebugCategory
 Container for load-time extension of the debugging categories. More...
class  Debug
 Class to support debug output. More...
struct  DebugColumnGuard
 Helper class. More...
struct  DebugColorGuard
 Helper class. More...
class  DebugOutputGuard
 Helper class that outputs debug information at creation and destruction of the object. More...
class  DurationStatCollector
 Duration statistics collector class. More...
class  ErrorBase
 Common base for platform-specific error management. More...
struct  NullFactoryError
 
Parameters:
IdentifierType The factory identifier type.
More...
class  Factory
 Implements generic Factory pattern. More...
class  GUID
 A cross-platform implementation of globally unique identifiers, also known as GUIDs or UUIDs (universally unique identifiers). More...
class  Interval
 This class captures a high-resolution interval. More...
class  RefCountMemory
 Reference countable memory. More...
class  ReturnStatus
 Class used to represent the status of a function or method upon its return. More...
class  SampleLimitedStatCollector
 Statistics collection class. More...
class  Singleton
 You can use this coolio class to make a singleton, just inherit like so:. More...
class  StatCollector
 Statistics collection class. More...
class  StreamLock
 Class to lock a stream for multi-process output. More...
class  StreamUnLock
 Class to unlock a stream that has been previously locked. More...
class  Timer
 Simple class to take timings and give averages. More...
struct  SocketConfiguration
 Socket configuration for BSD sockets. More...
struct  Uint64Hash
 Nice little helper class for hashing a vpr::Uint64. More...

Namespaces

namespace  SerialTypes
 Serial I/O types.
namespace  SocketOptions
 Socket-level options.
namespace  SocketTypes
 Socket I/O types.
namespace  sim
namespace  prof
 Set of routines for allowing simplified access to profile monitoring API.

Typedefs

typedef LibraryUNIX Library
typedef boost::shared_ptr<
Library
LibraryPtr
typedef FileHandle_t< FileHandleImplUNIXFileHandle
typedef Socket_t< SocketConfigurationSocket
typedef SocketDatagram_t<
SocketConfiguration
SocketDatagram
typedef SocketStream_t< SocketConfigurationSocketStream
typedef PRThreadPrivateDTOR KeyDestructor
typedef PRInt8 Int8
typedef PRUint8 Uint8
typedef PRInt16 Int16
typedef PRUint16 Uint16
typedef PRInt32 Int32
typedef PRUint32 Uint32
typedef PRInt64 Int64
typedef PRUint64 Uint64
typedef void(*) KeyDestructor (void *)
typedef vpr::Uint32 thread_id_t
typedef void(*) KeyDestructor (void *)
typedef void(*) thread_func_t (void *)
 Typedef to help with cross-platform abilities.
typedef RETSIGTYPE(*) SignalHandler_t (int)
typedef InetAddrBSD InetAddr
typedef IOSysUnix IOSys
typedef Selector_t< class
SelectorImplBSD
Selector
typedef SerialPort_t< class
SerialPortImplTermios
SerialPort
typedef ErrorImplPosix Error
typedef SystemPosix System
typedef CondVarPosix CondVar
typedef MutexPosix Mutex
typedef RWMutexPosix RWMutex
typedef SemaphorePosix Semaphore
typedef int cancel_state_t
typedef ThreadPosix Thread
typedef ThreadKeyPosix KeyId

Functions

static const std::string DSO_NAME_EXT ("")
static const std::string PATH_SEP ("/")
static const std::string DSO_FILE_EXT (".so")
static std::string errorPrep (const std::string &who, const std::string &msg)
vpr::ReturnStatus getIfAddrs (std::vector< vpr::InetAddr > &hostAddrs, const bool withLoopback)
 Retrieves all the IPv4 addresses associated with the local machine, including the loopback address (127.0.0.1) if so indicated.
vpr::ReturnStatus getIfAddrs (std::vector< vpr::InetAddrNSPR > &hostAddrs, const bool withLoopback)
void NSPR_PrintError (const std::string &errorPrefixString, std::ostream &=std::cout)
 Prints the current NSPR error state to the given output stream.
PRIntervalTime NSPR_getInterval (const vpr::Interval &interval)
 Converts the given vpr::Interval object to an NSPR interval.
std::ostream & operator<< (std::ostream &out, ProfileIterator &iter)
std::ostream & operator<< (std::ostream &out, vpr::Thread *threadPtr)
void vprThreadFunctorFunction (void *args)
 vprSingletonImp (ThreadManager)
std::ostream & operator<< (std::ostream &outfile, vpr::OneThread &thread)
 vprSingletonImpWithInitFunc (Debug, init)
template<class AbstractProduct, class ConcreteProduct>
AbstractProduct * CreateProduct ()
 Implements a useful little template function usable as a Creator in factory.
 VPR_IMPLEMENT (std::string) replaceEnvVars(const std
std::ostream & operator<< (std::ostream &s, const vpr::StreamLock &streamLock)
std::ostream & operator<< (std::ostream &s, const vpr::StreamUnLock &streamUnLock)
 VPR_IMPLEMENT (vpr::Uint32) getVersionNumber()
 VPR_API (std::string) getVersionString()
 Returns the name of the threading subsystem used to compile VPR.
 VPR_API (vpr::Uint32) getVersionNumber()
 Returns the 9-digit VPR version integer.

Variables

static const vpr::Uint32 SOCK_MAX_BUFFER_SIZE = 65536
TSObjectProxy< std::vector<
int > > 
gVprDebugCurColumn
TSObjectProxy< std::vector<
std::string > > 
gVprDebugCurColor
vpr::GUID::StdGUID null_guid_struct


Typedef Documentation

typedef LibraryUNIX vpr::Library

Definition at line 79 of file Library.h.

typedef boost::shared_ptr<Library> vpr::LibraryPtr

Definition at line 86 of file Library.h.

typedef FileHandle_t<FileHandleImplUNIX> vpr::FileHandle

Definition at line 72 of file FileHandle.h.

typedef Socket_t<SocketConfiguration> vpr::Socket

Definition at line 67 of file Socket.h.

typedef SocketDatagram_t<SocketConfiguration> vpr::SocketDatagram

Definition at line 71 of file SocketDatagram.h.

typedef SocketStream_t<SocketConfiguration> vpr::SocketStream

Definition at line 70 of file SocketStream.h.

typedef PRThreadPrivateDTOR vpr::KeyDestructor

Definition at line 59 of file ThreadKeyNSPR.h.

typedef PRInt8 vpr::Int8

Definition at line 49 of file vprTypesNSPR.h.

typedef PRUint8 vpr::Uint8

Definition at line 50 of file vprTypesNSPR.h.

typedef PRInt16 vpr::Int16

Definition at line 51 of file vprTypesNSPR.h.

typedef PRUint16 vpr::Uint16

Definition at line 52 of file vprTypesNSPR.h.

typedef PRInt32 vpr::Int32

Definition at line 53 of file vprTypesNSPR.h.

typedef PRUint32 vpr::Uint32

Definition at line 54 of file vprTypesNSPR.h.

typedef PRInt64 vpr::Int64

Definition at line 55 of file vprTypesNSPR.h.

typedef PRUint64 vpr::Uint64

Definition at line 56 of file vprTypesNSPR.h.

typedef void(*) vpr::KeyDestructor(void *)

Definition at line 62 of file ThreadKeyPosix.h.

typedef vpr::Uint32 vpr::thread_id_t

Definition at line 68 of file ThreadPosix.h.

typedef void(*) vpr::KeyDestructor(void *)

Definition at line 61 of file ThreadKeySGI.h.

typedef void(*) vpr::thread_func_t(void *)

Typedef to help with cross-platform abilities.

This type is the basic function pointer type for all functions initially passed as code to execute within a separate thread of control.

Definition at line 59 of file BaseThread.h.

typedef RETSIGTYPE(*) vpr::SignalHandler_t(int)

Definition at line 70 of file Signal.h.

typedef class InetAddrBSD vpr::InetAddr

Definition at line 153 of file vprDomain.h.

typedef class IOSysUnix vpr::IOSys

Definition at line 154 of file vprDomain.h.

typedef class Selector_t< class SelectorImplBSD > vpr::Selector

Definition at line 156 of file vprDomain.h.

typedef class SerialPort_t< class SerialPortImplTermios > vpr::SerialPort

Definition at line 157 of file vprDomain.h.

typedef class ErrorImplPosix vpr::Error

Definition at line 183 of file vprDomain.h.

typedef class SystemPosix vpr::System

Definition at line 184 of file vprDomain.h.

typedef class CondVarPosix vpr::CondVar

Definition at line 200 of file vprDomain.h.

typedef class MutexPosix vpr::Mutex

Definition at line 201 of file vprDomain.h.

typedef class RWMutexPosix vpr::RWMutex

Definition at line 202 of file vprDomain.h.

typedef class SemaphorePosix vpr::Semaphore

Definition at line 203 of file vprDomain.h.

typedef int vpr::cancel_state_t

Definition at line 205 of file vprDomain.h.

typedef class ThreadPosix vpr::Thread

Definition at line 206 of file vprDomain.h.

typedef class ThreadKeyPosix vpr::KeyId

Definition at line 207 of file vprDomain.h.


Function Documentation

static const std::string vpr::DSO_NAME_EXT ( ""   )  [static]

Referenced by vpr::LibraryLoader::makeFullDSOName().

static const std::string vpr::PATH_SEP ( "/"   )  [static]

static const std::string vpr::DSO_FILE_EXT ( ".so"   )  [static]

Referenced by vpr::LibraryLoader::makeFullDSOName().

static std::string vpr::errorPrep ( const std::string &  who,
const std::string &  msg 
) [static]

Definition at line 50 of file LoaderError.cpp.

00051 {
00052    return who + ": " + msg;
00053 }

vpr::ReturnStatus vpr::getIfAddrs ( std::vector< vpr::InetAddr > &  hostAddrs,
const bool  withLoopback 
)

Retrieves all the IPv4 addresses associated with the local machine, including the loopback address (127.0.0.1) if so indicated.

This is an internal function that is not part of the public VPR interface.

This function exists in this form primarily because NSPR does not provide any wrapper that offerrs this functionality. Since the WinSock2 use of WSAIoctl() so closely mimics the use of ioctl(2) to get the interface addresses, much code duplication would be required between vpr::InetAddrBSD and vpr::InetAddrNSPR. Instead of duplicating complicated code, those classes call into this function.

Postcondition:
hostAddrs contains vpr::InetAddr objetcs holding all the local IPv4 addresses for the local machine.
Parameters:
hostAddrs Storage for the discovered local IPv4 addresses. The vector is cleared before the addresses are added, so any objects currently in the vector are lost.
withLoopback A flag indicating whether to include the loopback address (127.0.0.1) in hostAddrs.
Note:
This method currently supports only IPv4.
Returns:
vpr::ReturnStatus::Succeed is returned if the querying of all local addresses completes without error. Otherwise, vpr::ReturnStatus::Fail is returned.

Definition at line 102 of file InetAddrHelpers.cpp.

References clrOutBOLD, clrRED, errno, vpr::ReturnStatus::Fail, vpr::InetAddrBSD::setAddress(), vprDBG_ALL(), vprDBG_CRITICAL_LVL, vprDEBUG, and vprDEBUG_FLUSH.

Referenced by vpr::InetAddrNSPR::getAllLocalAddrs(), and vpr::InetAddrBSD::getAllLocalAddrs().

00104 {
00105 #if defined(VPR_OS_Windows)
00106    const unsigned long loop = ntohl(INADDR_LOOPBACK);
00107 #else
00108    const in_addr_t loop = ntohl(INADDR_LOOPBACK);
00109 #endif
00110 
00111    // Make sure hostAddrs is empty so that we can use push_back() below.
00112    hostAddrs.clear();
00113 
00114 #if defined(HAVE_GETIFADDRS)
00115    ifaddrs* addrs(NULL);
00116 
00117    int result = getifaddrs(&addrs);
00118 
00119    if ( result < 0 )
00120    {
00121       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00122          << clrOutBOLD(clrRED, "ERROR")
00123          << ": [vpr::getIfAddrs()] Failed to query interface addresses: "
00124          << strerror(errno) << std::endl << vprDEBUG_FLUSH;
00125       return vpr::ReturnStatus::Fail;
00126    }
00127    else
00128    {
00129       for ( ifaddrs* a = addrs; a != NULL; a = a->ifa_next )
00130       {
00131          sockaddr_in* addr_in = (sockaddr_in*) a->ifa_addr;
00132 
00133          // We only handle IPv4 addresses.
00134          if ( addr_in->sin_family != AF_INET )
00135          {
00136             continue;
00137          }
00138 
00139          // If we have the loopback address and withLoopback is false, then we
00140          // skip this address.
00141          if ( addr_in->sin_addr.s_addr == loop && ! withLoopback )
00142          {
00143             continue;
00144          }
00145 
00146          char netaddr[18];
00147          const char* temp_addr = inet_ntop(addr_in->sin_family,
00148                                            &addr_in->sin_addr, netaddr,
00149                                            sizeof(netaddr));
00150 
00151          if ( NULL != temp_addr )
00152          {
00153             vpr::InetAddr vpr_addr;
00154             vpr_addr.setAddress(netaddr, 0);
00155             hostAddrs.push_back(vpr_addr);
00156          }
00157       }
00158    }
00159 
00160    freeifaddrs(addrs);
00161 #else   /* ! HAVE_GETIFADDRS */
00162    // While the implementation of this method is long and rather complex
00163    // looking, the idea is simple:
00164    //
00165    //    1. Create an IPv4 socket.
00166    //    2. Use ioctl(2) or WSAIoctl() on the socket handle to query all the
00167    //       network interfaces.
00168    //    3. Iterate over the returned interface request objects and extract
00169    //       the valid IPv4 addresses.
00170    //    4. Store each IPv4 address in a new vpr::InetAddr object.
00171 #if defined(VPR_OS_Windows)
00172    typedef INTERFACE_INFO ifreq_t;
00173 
00174    SOCKET sock = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
00175 
00176    // Socket creation failed, so we cannot proceed.
00177    if ( sock == SOCKET_ERROR )
00178    {
00179       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00180          << clrOutBOLD(clrRED, "ERROR")
00181          << ": [vpr::getIfAddrs()] Socket creation failed (error code "
00182          << WSAGetLastError() << ")\n" << vprDEBUG_FLUSH;
00183       return vpr::ReturnStatus::Fail;
00184    }
00185 #else
00186    typedef ifreq ifreq_t;
00187 
00188    int sock = socket(AF_INET, SOCK_DGRAM, 0);
00189 
00190    // Socket creation failed, so we cannot proceed.
00191    if ( sock < 0 )
00192    {
00193       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00194          << clrOutBOLD(clrRED, "ERROR")
00195          << ": [vpr::getIfAddrs()] Socket creation failed: " << strerror(errno)
00196          << std::endl << vprDEBUG_FLUSH;
00197       return vpr::ReturnStatus::Fail;
00198    }
00199 #endif
00200 
00201    // Initial guess on the size of the buffer that will be returned by
00202    // ioctl(2) or WSAIoctl().
00203    unsigned int num_reqs(32);
00204 
00205    size_t lastlen(0);
00206    unsigned long bytes_returned(0);
00207 #if ! defined(VPR_OS_Windows)
00208    ifconf ifc;
00209 #endif
00210    ifreq_t* if_list(NULL);
00211 
00212    // Call ioctl(2) or WSAIoctl() iteratively to ensure that we get back all
00213    // the interface addresses. This is based on code from NSPR.
00214    for ( ; ; )
00215    {
00216       // Allocate storage for the data returned by ioctl(2) or WSAIoctl().
00217       if_list = new ifreq_t[num_reqs];
00218 
00219       if ( NULL == if_list )
00220       {
00221 #if defined(VPR_OS_Windows)
00222          closesocket(sock);
00223 #else
00224          close(sock);
00225 #endif
00226          vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00227             << clrOutBOLD(clrRED, "ERROR")
00228             << ": [vpr::getIfAddrs()] Out of memory" << std::endl
00229             << vprDEBUG_FLUSH;
00230          return vpr::ReturnStatus::Fail;
00231       }
00232 
00233       const size_t len = sizeof(ifreq_t) * num_reqs;
00234 #if defined(VPR_OS_Windows)
00235       int result = WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, if_list,
00236                             len, &bytes_returned, NULL, NULL);
00237 #else
00238       ifc.ifc_len = len;
00239       ifc.ifc_req = if_list;
00240 
00241       int result = ioctl(sock, SIOCGIFCONF, &ifc);
00242       bytes_returned = ifc.ifc_len;
00243 #endif
00244 
00245       // Ask the kernel for all the network interfaces to which sock could be
00246       // bound.
00247 #if defined(VPR_OS_Windows)
00248       if ( result == SOCKET_ERROR )
00249 #else
00250       if ( result < 0 )
00251 #endif
00252       {
00253 #if defined(VPR_OS_Windows)
00254          const int inval_err(WSAEINVAL);
00255          const int err_code(WSAGetLastError());
00256 #else
00257          const int inval_err(EINVAL);
00258          const int err_code(errno);
00259 #endif
00260 
00261          // If ioctl(2) or WSAIoctl() failed for reasons other than our buffer
00262          // being too small, then we cannot continue. We need to clean up after
00263          // ourselves before we return failure status.
00264          if ( err_code != inval_err || lastlen != 0 )
00265          {
00266 #if defined(VPR_OS_Windows)
00267             closesocket(sock);
00268 #else
00269             close(sock);
00270 #endif
00271             delete[] if_list;
00272 
00273             vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00274                << clrOutBOLD(clrRED, "ERROR") << ": [vpr::getIfAddrs()] "
00275 #if defined(VPR_OS_Windows)
00276                << "Bad ioctl (error code " << err_code << ")"
00277 #else
00278                << "Bad ioctl: " << strerror(errno)
00279 #endif
00280                << std::endl << vprDEBUG_FLUSH;
00281             return vpr::ReturnStatus::Fail;
00282          }
00283       }
00284       // If ioctl(2) or WSAIoctl() returned successfully, check the size of
00285       // the buffer that it returned.
00286       else
00287       {
00288          // If lastlen is the same as the size of the buffer returned by
00289          // ioctl(2) or WSAIoctl(), then we are done. If the size of the buffer
00290          // returned by ioctl(2) or WASIoctl() is no larger than what we
00291          // allocated, then we are done.
00292          if ( bytes_returned == lastlen || bytes_returned <= len )
00293          {
00294             break;
00295          }
00296          // Otherwise, we continue iterating.
00297          else
00298          {
00299             lastlen = bytes_returned;
00300          }
00301       }
00302 
00303       // Increment the size of the returned buffer by increasing the number of
00304       // allocated request structures.
00305       num_reqs += 10;
00306       delete[] if_list;
00307    }
00308 
00309    // We are done with the socket.
00310 #if defined(VPR_OS_Windows)
00311    closesocket(sock);
00312 #else
00313    close(sock);
00314 #endif
00315 
00316    // Figure out how many interfaces were returned.
00317    const size_t num = bytes_returned / sizeof(ifreq_t);
00318 
00319    // Iterate over the returned ifreq objects and pull out the valid IPv4
00320    // addresses.
00321    for ( size_t i = 0; i < num; ++i )
00322    {
00323 #if defined(VPR_OS_Windows)
00324       sockaddr_in* addr = (sockaddr_in*) &if_list[i].iiAddress;
00325 #else
00326       sockaddr_in* addr = (sockaddr_in*) &ifc.ifc_req[i].ifr_addr;
00327 #endif
00328 
00329       // Skip addresses that are not IPv4.
00330       // XXX: We should support IPv6 at some point.
00331       if ( addr->sin_family != AF_INET )
00332       {
00333          continue;
00334       }
00335 
00336       // If we have the loopback address and withLoopback is false, then we
00337       // skip this address.
00338       if ( addr->sin_addr.s_addr == loop && ! withLoopback )
00339       {
00340          continue;
00341       }
00342 
00343       std::ostringstream addr_stream;
00344 
00345 #if defined(VPR_OS_Windows)
00346       // inet_ntoa() returns a pointer to static memory, which means that
00347       // it is not reentrant. Unfortunately, WinSock2 does not provide
00348       // inet_ntop(). The memory returned is guaranteed to be valid until
00349       // the next socket call in this thread, so there should not be a
00350       // race condition here.
00351       const char* temp_addr = inet_ntoa(addr->sin_addr);
00352 
00353       if ( NULL != temp_addr )
00354       {
00355          addr_stream << temp_addr;
00356       }
00357 #else
00358       char netaddr[18];
00359       const char* temp_addr = inet_ntop(addr->sin