Browse Source

KWSys 2012-10-16 (b7a97ac3)

Extract upstream KWSys using the following shell commands.

$ git archive --prefix=upstream-kwsys/ b7a97ac3 | tar x
$ git shortlog --no-merges --abbrev=8 --format='%h %s' bab53989..b7a97ac3
Brad King (3):
      f9db7eab SystemInformation: Fix helper definition order
      a1e83e42 SystemInformation: Expose helper functions only where needed
      b7a97ac3 SystemInformation: Drop unused LoadLines on OS X

Burlen Loring (1):
      6072e63b SystemInformation: support for resource limits

Sean McBride (2):
      a536d833 ProcessUNIX: Suppress warning about uninteresting return code
      00852081 SystemInformation: Fix sloppy use of sysctlbyname() API

Change-Id: Iae8af129a021435ef4e6daef255e312c99d7b773
KWSys Robot 13 years ago
parent
commit
7ae44db4b9
6 changed files with 657 additions and 133 deletions
  1. 61 4
      CMakeLists.txt
  2. 1 0
      ProcessUNIX.c
  3. 460 115
      SystemInformation.cxx
  4. 39 10
      SystemInformation.hxx.in
  5. 66 0
      kwsysPlatformTestsCXX.cxx
  6. 30 4
      testSystemInformation.cxx

+ 61 - 4
CMakeLists.txt

@@ -509,19 +509,28 @@ ENDIF(KWSYS_USE_FundamentalType)
 
 
 IF(KWSYS_USE_IOStream)
 IF(KWSYS_USE_IOStream)
   # Determine whether iostreams support long long.
   # Determine whether iostreams support long long.
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
+    -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
+    -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
   IF(KWSYS_CXX_HAS_LONG_LONG)
   IF(KWSYS_CXX_HAS_LONG_LONG)
-    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
-      -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
-      -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
       "Checking if istream supports long long" DIRECT)
       "Checking if istream supports long long" DIRECT)
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
       "Checking if ostream supports long long" DIRECT)
       "Checking if ostream supports long long" DIRECT)
-    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
   ELSE()
   ELSE()
     SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
     SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
     SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
     SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
   ENDIF()
   ENDIF()
+  IF(KWSYS_CXX_HAS___INT64)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
+      "Checking if istream supports __int64" DIRECT)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
+      "Checking if ostream supports __int64" DIRECT)
+  ELSE()
+    SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
+    SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
+  ENDIF()
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
 ENDIF(KWSYS_USE_IOStream)
 ENDIF(KWSYS_USE_IOStream)
 
 
 IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
 IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
@@ -588,6 +597,54 @@ IF(KWSYS_USE_SystemInformation)
       ENDIF()
       ENDIF()
     ENDIF()
     ENDIF()
   ENDIF()
   ENDIF()
+  IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
+    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
+    "Checking whether CXX compiler has rlimit64" DIRECT)
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+  IF(KWSYS_CXX_HAS_RLIMIT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
+    "Checking whether CXX compiler has atol" DIRECT)
+  IF(KWSYS_CXX_HAS_ATOL)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
+    "Checking whether CXX compiler has atoll" DIRECT)
+  IF(KWSYS_CXX_HAS_ATOLL)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
+    "Checking whether CXX compiler has _atoi64" DIRECT)
+  IF(KWSYS_CXX_HAS__ATOI64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
+  ENDIF()
+  IF(KWSYS_USE___INT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
+  ENDIF()
+  IF(KWSYS_USE_LONG_LONG)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
+  ENDIF()
+  IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
+  ENDIF()
+  IF(KWSYS_IOS_HAS_OSTREAM___INT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
+  ENDIF()
+  IF(KWSYS_BUILD_SHARED)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
+  ENDIF()
 ENDIF()
 ENDIF()
 
 
 #-----------------------------------------------------------------------------
 #-----------------------------------------------------------------------------

+ 1 - 0
ProcessUNIX.c

@@ -2732,6 +2732,7 @@ static void kwsysProcessesSignalHandler(int signum
     kwsysProcess* cp = kwsysProcesses.Processes[i];
     kwsysProcess* cp = kwsysProcesses.Processes[i];
     kwsysProcess_ssize_t status=
     kwsysProcess_ssize_t status=
       read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
       read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
+    (void)status;
     status=write(cp->SignalPipe, &buf, 1);
     status=write(cp->SignalPipe, &buf, 1);
     (void)status;
     (void)status;
     }
     }

+ 460 - 115
SystemInformation.cxx

@@ -9,7 +9,9 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
   See the License for more information.
 ============================================================================*/
 ============================================================================*/
-#ifdef _WIN32
+
+#if defined(_WIN32)
+# define NOMINMAX // use our min,max
 # if !defined(_WIN32_WINNT) && !(defined(_MSC_VER) && _MSC_VER < 1300)
 # if !defined(_WIN32_WINNT) && !(defined(_MSC_VER) && _MSC_VER < 1300)
 #  define _WIN32_WINNT 0x0501
 #  define _WIN32_WINNT 0x0501
 # endif
 # endif
@@ -54,6 +56,7 @@
 
 
 #if defined(_WIN32)
 #if defined(_WIN32)
 # include <windows.h>
 # include <windows.h>
+# include <errno.h>
 # if defined(KWSYS_SYS_HAS_PSAPI)
 # if defined(KWSYS_SYS_HAS_PSAPI)
 #  include <psapi.h>
 #  include <psapi.h>
 # endif
 # endif
@@ -64,6 +67,7 @@ typedef int siginfo_t;
 # include <sys/types.h>
 # include <sys/types.h>
 # include <sys/time.h>
 # include <sys/time.h>
 # include <sys/utsname.h> // int uname(struct utsname *buf);
 # include <sys/utsname.h> // int uname(struct utsname *buf);
+# include <sys/resource.h> // getrlimit
 # include <unistd.h>
 # include <unistd.h>
 # include <signal.h>
 # include <signal.h>
 # include <fcntl.h>
 # include <fcntl.h>
@@ -71,15 +75,15 @@ typedef int siginfo_t;
 #endif
 #endif
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
-#include <sys/sysctl.h>
-#include <mach/vm_statistics.h>
-#include <mach/host_info.h>
-#include <mach/mach.h>
-#include <mach/mach_types.h>
-#include <fenv.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
+# include <sys/sysctl.h>
+# include <mach/vm_statistics.h>
+# include <mach/host_info.h>
+# include <mach/mach.h>
+# include <mach/mach_types.h>
+# include <fenv.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
 # if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050
 # if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050
 #  include <execinfo.h>
 #  include <execinfo.h>
 #  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
 #  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
@@ -95,6 +99,13 @@ typedef int siginfo_t;
 #  include <execinfo.h>
 #  include <execinfo.h>
 #  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
 #  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
 # endif
 # endif
+# if defined(KWSYS_CXX_HAS_RLIMIT64)
+typedef struct rlimit64 ResourceLimitType;
+#  define GetResourceLimit getrlimit64
+# else
+typedef struct rlimit ResourceLimitType;
+#  define GetResourceLimit getrlimit
+# endif
 #elif defined( __hpux )
 #elif defined( __hpux )
 # include <sys/param.h>
 # include <sys/param.h>
 # include <sys/pstat.h>
 # include <sys/pstat.h>
@@ -105,7 +116,7 @@ typedef int siginfo_t;
 #endif
 #endif
 
 
 #ifdef __HAIKU__
 #ifdef __HAIKU__
-#include <OS.h>
+# include <OS.h>
 #endif
 #endif
 
 
 #include <memory.h>
 #include <memory.h>
@@ -114,8 +125,38 @@ typedef int siginfo_t;
 #include <string.h>
 #include <string.h>
 #include <ctype.h> // int isdigit(int c);
 #include <ctype.h> // int isdigit(int c);
 
 
+#if defined(KWSYS_USE_LONG_LONG)
+# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#elif defined(KWSYS_USE___INT64)
+# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#else
+# error "No Long Long"
+#endif
+
+#if defined(KWSYS_CXX_HAS_ATOLL)
+# define atoLongLong atoll
+#else
+# if defined(KWSYS_CXX_HAS__ATOI64)
+#  define atoLongLong _atoi64
+# elif defined(KWSYS_CXX_HAS_ATOL)
+#  define atoLongLong atol
+# else
+#  define atoLongLong atoi
+# endif
+#endif
+
 namespace KWSYS_NAMESPACE
 namespace KWSYS_NAMESPACE
 {
 {
+template<typename T>
+T min(T a, T b){ return a<b ? a : b; }
 
 
 extern "C" { typedef void (*SigAction)(int,siginfo_t*,void*); }
 extern "C" { typedef void (*SigAction)(int,siginfo_t*,void*); }
 
 
@@ -168,8 +209,14 @@ public:
   LongLong GetProcessId();
   LongLong GetProcessId();
 
 
   // Retrieve memory information in kib
   // Retrieve memory information in kib
-  LongLong GetMemoryTotal();
-  LongLong GetMemoryUsed();
+  LongLong GetHostMemoryTotal();
+  LongLong GetHostMemoryAvailable(const char *envVarName);
+  LongLong GetHostMemoryUsed();
+
+  LongLong GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName);
+  LongLong GetProcMemoryUsed();
 
 
   // enable/disable stack trace signal handler.
   // enable/disable stack trace signal handler.
   static
   static
@@ -448,11 +495,7 @@ const char * SystemInformation::GetHostname()
 kwsys_stl::string SystemInformation::GetFullyQualifiedDomainName()
 kwsys_stl::string SystemInformation::GetFullyQualifiedDomainName()
 {
 {
   kwsys_stl::string fqdn;
   kwsys_stl::string fqdn;
-  int ierr=this->Implementation->GetFullyQualifiedDomainName(fqdn);
-  if (ierr)
-    {
-    fqdn="localhost";
-    }
+  this->Implementation->GetFullyQualifiedDomainName(fqdn);
   return fqdn;
   return fqdn;
 }
 }
 
 
@@ -552,27 +595,54 @@ size_t SystemInformation::GetAvailablePhysicalMemory()
   return this->Implementation->GetAvailablePhysicalMemory();
   return this->Implementation->GetAvailablePhysicalMemory();
 }
 }
 
 
-kwsys_stl::string SystemInformation::GetMemoryDescription()
+kwsys_stl::string SystemInformation::GetMemoryDescription(
+      const char *hostLimitEnvVarName,
+      const char *procLimitEnvVarName)
 {
 {
   kwsys_stl::ostringstream oss;
   kwsys_stl::ostringstream oss;
   oss
   oss
-    << this->GetTotalPhysicalMemory()
-    << " MB physical "
-    << this->GetTotalVirtualMemory()
-    << " MB virtual";
-
+    << "Host Total: "
+    << iostreamLongLong(this->GetHostMemoryTotal())
+    << " KiB, Host Available: "
+    << iostreamLongLong(this->GetHostMemoryAvailable(hostLimitEnvVarName))
+    << " KiB, Process Available: "
+    << iostreamLongLong(
+         this->GetProcMemoryAvailable(hostLimitEnvVarName,procLimitEnvVarName))
+    << " KiB";
   return oss.str();
   return oss.str();
 }
 }
 
 
-// Get total system RAM in units of KiB.
-SystemInformation::LongLong SystemInformation::GetMemoryTotal()
+// host memory info in units of KiB.
+SystemInformation::LongLong SystemInformation::GetHostMemoryTotal()
 {
 {
-  return this->Implementation->GetMemoryTotal();
+  return this->Implementation->GetHostMemoryTotal();
 }
 }
 
 
-SystemInformation::LongLong SystemInformation::GetMemoryUsed()
+SystemInformation::LongLong
+SystemInformation::GetHostMemoryAvailable(const char *hostLimitEnvVarName)
+{
+  return this->Implementation->GetHostMemoryAvailable(hostLimitEnvVarName);
+}
+
+SystemInformation::LongLong SystemInformation::GetHostMemoryUsed()
 {
 {
-  return this->Implementation->GetMemoryUsed();
+  return this->Implementation->GetHostMemoryUsed();
+}
+
+// process memory info in units of KiB.
+SystemInformation::LongLong
+SystemInformation::GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName)
+{
+  return this->Implementation->GetProcMemoryAvailable(
+          hostLimitEnvVarName,
+          procLimitEnvVarName);
+}
+
+SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
+{
+  return this->Implementation->GetProcMemoryUsed();
 }
 }
 
 
 SystemInformation::LongLong SystemInformation::GetProcessId()
 SystemInformation::LongLong SystemInformation::GetProcessId()
@@ -671,33 +741,55 @@ void SystemInformation::RunMemoryCheck()
 // initial APIC ID for the processor this code is running on.
 // initial APIC ID for the processor this code is running on.
 // Default value = 0xff if HT is not supported
 // Default value = 0xff if HT is not supported
 
 
-
-//*****************************************************************************
+// Hide implementation details in an anonymous namespace.
+namespace {
+// *****************************************************************************
+#if defined(__linux) || defined(__APPLE__)
 int LoadLines(
 int LoadLines(
-      const char *fileName,
+      FILE *file,
       kwsys_stl::vector<kwsys_stl::string> &lines)
       kwsys_stl::vector<kwsys_stl::string> &lines)
 {
 {
   // Load each line in the given file into a the vector.
   // Load each line in the given file into a the vector.
   int nRead=0;
   int nRead=0;
   const int bufSize=1024;
   const int bufSize=1024;
   char buf[bufSize]={'\0'};
   char buf[bufSize]={'\0'};
-  kwsys_stl::ifstream file(fileName);
-  if (!file.is_open())
+  while (!feof(file) && !ferror(file))
+    {
+    errno=0;
+    if (fgets(buf,bufSize,file) == 0)
+      {
+      if (ferror(file) && (errno==EINTR))
+        {
+        clearerr(file);
+        }
+      continue;
+      }
+    lines.push_back(buf);
+    ++nRead;
+    }
+  if (ferror(file))
     {
     {
     return 0;
     return 0;
     }
     }
-  while(file.good())
+  return nRead;
+}
+
+# if defined(__linux)
+// *****************************************************************************
+int LoadLines(
+      const char *fileName,
+      kwsys_stl::vector<kwsys_stl::string> &lines)
+{
+  FILE *file=fopen(fileName,"r");
+  if (file==0)
     {
     {
-    file.getline(buf,bufSize);
-    if (file.gcount()>1)
-      {
-      lines.push_back(buf);
-      ++nRead;
-      }
+    return 0;
     }
     }
-  file.close();
+  int nRead=LoadLines(file,lines);
+  fclose(file);
   return nRead;
   return nRead;
 }
 }
+# endif
 
 
 // ****************************************************************************
 // ****************************************************************************
 template<typename T>
 template<typename T>
@@ -708,17 +800,44 @@ int NameValue(
   size_t nLines=lines.size();
   size_t nLines=lines.size();
   for (size_t i=0; i<nLines; ++i)
   for (size_t i=0; i<nLines; ++i)
     {
     {
-    kwsys_stl::string tok;
-    kwsys_stl::istringstream is(lines[i]);
-    is >> tok;
-    if (tok==name)
+    size_t at=lines[i].find(name);
+    if (at==kwsys_stl::string::npos)
       {
       {
-      is >> value;
-      return 0;
+      continue;
       }
       }
+    kwsys_stl::istringstream is(lines[i].substr(at+name.size()));
+    is >> value;
+    return 0;
     }
     }
   return -1;
   return -1;
 }
 }
+#endif
+
+#if defined(__linux)
+// ****************************************************************************
+template<typename T>
+int GetFieldsFromFile(
+      const char *fileName,
+      const char **fieldNames,
+      T *values)
+{
+  kwsys_stl::vector<kwsys_stl::string> fields;
+  if (!LoadLines(fileName,fields))
+    {
+    return -1;
+    }
+  int i=0;
+  while (fieldNames[i]!=NULL)
+    {
+    int ierr=NameValue(fields,fieldNames[i],values[i]);
+    if (ierr)
+      {
+      return -(i+2);
+      }
+    i+=1;
+    }
+  return 0;
+}
 
 
 // ****************************************************************************
 // ****************************************************************************
 template<typename T>
 template<typename T>
@@ -727,202 +846,244 @@ int GetFieldFromFile(
       const char *fieldName,
       const char *fieldName,
       T &value)
       T &value)
 {
 {
+  const char *fieldNames[2]={fieldName,NULL};
+  T values[1]={T(0)};
+  int ierr=GetFieldsFromFile(fileName,fieldNames,values);
+  if (ierr)
+    {
+    return ierr;
+    }
+  value=values[0];
+  return 0;
+}
+#endif
+
+// ****************************************************************************
+#if defined(__APPLE__)
+template<typename T>
+int GetFieldsFromCommand(
+      const char *command,
+      const char **fieldNames,
+      T *values)
+{
+  FILE *file=popen(command,"r");
+  if (file==0)
+    {
+    return -1;
+    }
   kwsys_stl::vector<kwsys_stl::string> fields;
   kwsys_stl::vector<kwsys_stl::string> fields;
-  if (!LoadLines(fileName,fields))
+  int nl=LoadLines(file,fields);
+  pclose(file);
+  if (nl==0)
     {
     {
     return -1;
     return -1;
     }
     }
-  int ierr=NameValue(fields,fieldName,value);
-  if (ierr)
+  int i=0;
+  while (fieldNames[i]!=NULL)
     {
     {
-    return -2;
+    int ierr=NameValue(fields,fieldNames[i],values[i]);
+    if (ierr)
+      {
+      return -(i+2);
+      }
+    i+=1;
     }
     }
   return 0;
   return 0;
 }
 }
+#endif
 
 
-//*****************************************************************************
+// ****************************************************************************
+#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
 void StacktraceSignalHandler(
 void StacktraceSignalHandler(
       int sigNo,
       int sigNo,
       siginfo_t *sigInfo,
       siginfo_t *sigInfo,
       void * /*sigContext*/)
       void * /*sigContext*/)
 {
 {
 #if defined(__linux) || defined(__APPLE__)
 #if defined(__linux) || defined(__APPLE__)
-  kwsys_ios::cerr << "[" << getpid() << "] ";
-
+  kwsys_ios::ostringstream oss;
+  oss
+     << "=========================================================" << kwsys_ios::endl
+     << "Process id " << getpid() << " ";
   switch (sigNo)
   switch (sigNo)
     {
     {
     case SIGFPE:
     case SIGFPE:
-      kwsys_ios::cerr << "Caught SIGFPE ";
+      oss << "Caught SIGFPE ";
       switch (sigInfo->si_code)
       switch (sigInfo->si_code)
         {
         {
 # if defined(FPE_INTDIV)
 # if defined(FPE_INTDIV)
         case FPE_INTDIV:
         case FPE_INTDIV:
-          kwsys_ios::cerr << "integer division by zero";
+          oss << "integer division by zero";
           break;
           break;
 # endif
 # endif
 
 
 # if defined(FPE_INTOVF)
 # if defined(FPE_INTOVF)
         case FPE_INTOVF:
         case FPE_INTOVF:
-          kwsys_ios::cerr << "integer overflow";
+          oss << "integer overflow";
           break;
           break;
 # endif
 # endif
 
 
         case FPE_FLTDIV:
         case FPE_FLTDIV:
-          kwsys_ios::cerr << "floating point divide by zero";
+          oss << "floating point divide by zero";
           break;
           break;
 
 
         case FPE_FLTOVF:
         case FPE_FLTOVF:
-          kwsys_ios::cerr << "floating point overflow";
+          oss << "floating point overflow";
           break;
           break;
 
 
         case FPE_FLTUND:
         case FPE_FLTUND:
-          kwsys_ios::cerr << "floating point underflow";
+          oss << "floating point underflow";
           break;
           break;
 
 
         case FPE_FLTRES:
         case FPE_FLTRES:
-          kwsys_ios::cerr << "floating point inexact result";
+          oss << "floating point inexact result";
           break;
           break;
 
 
         case FPE_FLTINV:
         case FPE_FLTINV:
-          kwsys_ios::cerr << "floating point invalid operation";
+          oss << "floating point invalid operation";
           break;
           break;
 
 
 #if defined(FPE_FLTSUB)
 #if defined(FPE_FLTSUB)
         case FPE_FLTSUB:
         case FPE_FLTSUB:
-          kwsys_ios::cerr << "floating point subscript out of range";
+          oss << "floating point subscript out of range";
           break;
           break;
 #endif
 #endif
 
 
         default:
         default:
-          kwsys_ios::cerr << "code " << sigInfo->si_code;
+          oss << "code " << sigInfo->si_code;
           break;
           break;
         }
         }
       break;
       break;
 
 
     case SIGSEGV:
     case SIGSEGV:
-      kwsys_ios::cerr << "Caught SIGSEGV ";
+      oss << "Caught SIGSEGV ";
       switch (sigInfo->si_code)
       switch (sigInfo->si_code)
         {
         {
         case SEGV_MAPERR:
         case SEGV_MAPERR:
-          kwsys_ios::cerr << "address not mapped to object";
+          oss << "address not mapped to object";
           break;
           break;
 
 
         case SEGV_ACCERR:
         case SEGV_ACCERR:
-          kwsys_ios::cerr << "invalid permission for mapped object";
+          oss << "invalid permission for mapped object";
           break;
           break;
 
 
         default:
         default:
-          kwsys_ios::cerr << "code " << sigInfo->si_code;
+          oss << "code " << sigInfo->si_code;
           break;
           break;
         }
         }
       break;
       break;
 
 
     case SIGINT:
     case SIGINT:
-      kwsys_ios::cerr << "Caught SIGTERM";
+      oss << "Caught SIGTERM";
       break;
       break;
 
 
     case SIGTERM:
     case SIGTERM:
-      kwsys_ios::cerr << "Caught SIGTERM";
+      oss << "Caught SIGTERM";
       break;
       break;
 
 
     case SIGBUS:
     case SIGBUS:
-      kwsys_ios::cerr << "Caught SIGBUS type ";
+      oss << "Caught SIGBUS type ";
       switch (sigInfo->si_code)
       switch (sigInfo->si_code)
         {
         {
         case BUS_ADRALN:
         case BUS_ADRALN:
-          kwsys_ios::cerr << "invalid address alignment";
+          oss << "invalid address alignment";
           break;
           break;
 
 
 # if defined(BUS_ADRERR)
 # if defined(BUS_ADRERR)
         case BUS_ADRERR:
         case BUS_ADRERR:
-          kwsys_ios::cerr << "non-exestent physical address";
+          oss << "non-exestent physical address";
           break;
           break;
 # endif
 # endif
 
 
 # if defined(BUS_OBJERR)
 # if defined(BUS_OBJERR)
         case BUS_OBJERR:
         case BUS_OBJERR:
-          kwsys_ios::cerr << "object specific hardware error";
+          oss << "object specific hardware error";
           break;
           break;
 # endif
 # endif
 
 
         default:
         default:
-          kwsys_ios::cerr << "code " << sigInfo->si_code;
+          oss << "code " << sigInfo->si_code;
           break;
           break;
         }
         }
       break;
       break;
 
 
     case SIGILL:
     case SIGILL:
-      kwsys_ios::cerr << "Caught SIGILL ";
+      oss << "Caught SIGILL ";
       switch (sigInfo->si_code)
       switch (sigInfo->si_code)
         {
         {
         case ILL_ILLOPC:
         case ILL_ILLOPC:
-          kwsys_ios::cerr << "illegal opcode";
+          oss << "illegal opcode";
           break;
           break;
 
 
 # if defined(ILL_ILLOPN)
 # if defined(ILL_ILLOPN)
         case ILL_ILLOPN:
         case ILL_ILLOPN:
-          kwsys_ios::cerr << "illegal operand";
+          oss << "illegal operand";
           break;
           break;
 # endif
 # endif
 
 
 # if defined(ILL_ILLADR)
 # if defined(ILL_ILLADR)
         case ILL_ILLADR:
         case ILL_ILLADR:
-          kwsys_ios::cerr << "illegal addressing mode.";
+          oss << "illegal addressing mode.";
           break;
           break;
 # endif
 # endif
 
 
         case ILL_ILLTRP:
         case ILL_ILLTRP:
-          kwsys_ios::cerr << "illegal trap";
+          oss << "illegal trap";
 
 
         case ILL_PRVOPC:
         case ILL_PRVOPC:
-          kwsys_ios::cerr << "privileged opcode";
+          oss << "privileged opcode";
           break;
           break;
 
 
 # if defined(ILL_PRVREG)
 # if defined(ILL_PRVREG)
         case ILL_PRVREG:
         case ILL_PRVREG:
-          kwsys_ios::cerr << "privileged register";
+          oss << "privileged register";
           break;
           break;
 # endif
 # endif
 
 
 # if defined(ILL_COPROC)
 # if defined(ILL_COPROC)
         case ILL_COPROC:
         case ILL_COPROC:
-          kwsys_ios::cerr << "co-processor error";
+          oss << "co-processor error";
           break;
           break;
 # endif
 # endif
 
 
 # if defined(ILL_BADSTK)
 # if defined(ILL_BADSTK)
         case ILL_BADSTK:
         case ILL_BADSTK:
-          kwsys_ios::cerr << "internal stack error";
+          oss << "internal stack error";
           break;
           break;
 # endif
 # endif
 
 
         default:
         default:
-          kwsys_ios::cerr << "code " << sigInfo->si_code;
+          oss << "code " << sigInfo->si_code;
           break;
           break;
         }
         }
       break;
       break;
 
 
     default:
     default:
-      kwsys_ios::cerr << "Caught " << sigNo << " code " << sigInfo->si_code;
+      oss << "Caught " << sigNo << " code " << sigInfo->si_code;
       break;
       break;
     }
     }
-  kwsys_ios::cerr << kwsys_ios::endl;
-
+  oss << kwsys_ios::endl;
 #if defined(KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE)
 #if defined(KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE)
-  kwsys_ios::cerr << "Stack:" << kwsys_ios::endl;
-  void *stack[128];
-  int n=backtrace(stack,128);
-  backtrace_symbols_fd(stack,n,2);
+  oss << "Program Stack:" << kwsys_ios::endl;
+  void *stackSymbols[128];
+  int n=backtrace(stackSymbols,128);
+  char **stackText=backtrace_symbols(stackSymbols,n);
+  for (int i=0; i<n; ++i)
+    {
+    oss << "  " << stackText[i] << kwsys_ios::endl;
+    }
 #endif
 #endif
-
+  oss
+     << "=========================================================" << kwsys_ios::endl;
+  kwsys_ios::cerr << oss.str() << kwsys_ios::endl;
   abort();
   abort();
-
 #else
 #else
   // avoid warning C4100
   // avoid warning C4100
   (void)sigNo;
   (void)sigNo;
   (void)sigInfo;
   (void)sigInfo;
 #endif
 #endif
 }
 }
+#endif
+} // anonymous namespace
 
 
 SystemInformationImplementation::SystemInformationImplementation()
 SystemInformationImplementation::SystemInformationImplementation()
 {
 {
@@ -1047,6 +1208,29 @@ const char * SystemInformationImplementation::GetOSName()
 /** Get the hostname */
 /** Get the hostname */
 const char* SystemInformationImplementation::GetHostname()
 const char* SystemInformationImplementation::GetHostname()
 {
 {
+  if (this->Hostname.empty())
+    {
+    this->Hostname="localhost";
+#if defined(_WIN32)
+    WORD wVersionRequested;
+    WSADATA wsaData;
+    char name[255];
+    wVersionRequested = MAKEWORD(2,0);
+    if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
+      {
+      gethostname(name,sizeof(name));
+      WSACleanup( );
+      }
+    this->Hostname = name;
+#else
+    struct utsname unameInfo;
+    int errorFlag = uname(&unameInfo);
+    if(errorFlag == 0)
+      {
+      this->Hostname = unameInfo.nodename;
+      }
+#endif
+    }
   return this->Hostname.c_str();
   return this->Hostname.c_str();
 }
 }
 
 
@@ -1092,7 +1276,12 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
   // we want the fully qualified domain name. Because there are
   // we want the fully qualified domain name. Because there are
   // any number of interfaces on this system we look for the
   // any number of interfaces on this system we look for the
   // first of these that contains the name returned by gethostname
   // first of these that contains the name returned by gethostname
-  // and is longer. failing that we return gethostname.
+  // and is longer. failing that we return gethostname and indicate
+  // with a failure code. Return of a failure code is not necessarilly
+  // an indication of an error. for instance gethostname may return
+  // the fully qualified domain name, or there may not be one if the
+  // system lives on a private network such as in the case of a cluster
+  // node.
 
 
   int ierr=0;
   int ierr=0;
   char base[NI_MAXHOST];
   char base[NI_MAXHOST];
@@ -1132,8 +1321,8 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
             NI_NAMEREQD);
             NI_NAMEREQD);
       if (ierr)
       if (ierr)
         {
         {
-        // don't report the error now since we may succeed on another
-        // interface. If all attempts fail then retrun an error code.
+        // don't report the failure now since we may succeed on another
+        // interface. If all attempts fail then return the failure code.
         ierr=-3;
         ierr=-3;
         continue;
         continue;
         }
         }
@@ -1153,6 +1342,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
   return ierr;
   return ierr;
 #else
 #else
   /* TODO: Implement on more platforms.  */
   /* TODO: Implement on more platforms.  */
+  fqdn=this->GetHostname();
   return -1;
   return -1;
 #endif
 #endif
 }
 }
@@ -2905,7 +3095,7 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 Get total system RAM in units of KiB.
 Get total system RAM in units of KiB.
 */
 */
 SystemInformation::LongLong
 SystemInformation::LongLong
-SystemInformationImplementation::GetMemoryTotal()
+SystemInformationImplementation::GetHostMemoryTotal()
 {
 {
 #if defined(_WIN32)
 #if defined(_WIN32)
 # if defined(_MSC_VER) && _MSC_VER < 1300
 # if defined(_MSC_VER) && _MSC_VER < 1300
@@ -2920,7 +3110,7 @@ SystemInformationImplementation::GetMemoryTotal()
   return statex.ullTotalPhys/1024;
   return statex.ullTotalPhys/1024;
 # endif
 # endif
 #elif defined(__linux)
 #elif defined(__linux)
-  LongLong memTotal=0;
+  SystemInformation::LongLong memTotal=0;
   int ierr=GetFieldFromFile("/proc/meminfo","MemTotal:",memTotal);
   int ierr=GetFieldFromFile("/proc/meminfo","MemTotal:",memTotal);
   if (ierr)
   if (ierr)
     {
     {
@@ -2941,16 +3131,157 @@ SystemInformationImplementation::GetMemoryTotal()
 #endif
 #endif
 }
 }
 
 
+/**
+Get total system RAM in units of KiB. This may differ from the
+host total if a host-wide resource limit is applied.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetHostMemoryAvailable(const char *hostLimitEnvVarName)
+{
+  SystemInformation::LongLong memTotal=this->GetHostMemoryTotal();
+
+  // the following mechanism is provided for systems that
+  // apply resource limits across groups of processes.
+  // this is of use on certain SMP systems (eg. SGI UV)
+  // where the host has a large amount of ram but a given user's
+  // access to it is severly restricted. The system will
+  // apply a limit across a set of processes. Units are in KiB.
+  if (hostLimitEnvVarName)
+    {
+    const char *hostLimitEnvVarValue=getenv(hostLimitEnvVarName);
+    if (hostLimitEnvVarValue)
+      {
+      SystemInformation::LongLong hostLimit=atoLongLong(hostLimitEnvVarValue);
+      if (hostLimit>0)
+        {
+        memTotal=min(hostLimit,memTotal);
+        }
+      }
+    }
+
+  return memTotal;
+}
+
+/**
+Get total system RAM in units of KiB. This may differ from the
+host total if a per-process resource limit is applied.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName)
+{
+  SystemInformation::LongLong memAvail
+    = this->GetHostMemoryAvailable(hostLimitEnvVarName);
+
+  // the following mechanism is provide for systems where rlimits
+  // are not employed. Units are in KiB.
+  if (procLimitEnvVarName)
+    {
+    const char *procLimitEnvVarValue=getenv(procLimitEnvVarName);
+    if (procLimitEnvVarValue)
+      {
+      SystemInformation::LongLong procLimit=atoLongLong(procLimitEnvVarValue);
+      if (procLimit>0)
+        {
+        memAvail=min(procLimit,memAvail);
+        }
+      }
+    }
+
+#if defined(__linux)
+  int ierr;
+  ResourceLimitType rlim;
+  ierr=GetResourceLimit(RLIMIT_DATA,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+
+  ierr=GetResourceLimit(RLIMIT_AS,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+#elif defined(__APPLE__)
+  struct rlimit rlim;
+  int ierr;
+  ierr=getrlimit(RLIMIT_DATA,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+
+  ierr=getrlimit(RLIMIT_RSS,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+#endif
+
+  return memAvail;
+}
+
+/**
+Get RAM used by all processes in the host, in units of KiB.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetHostMemoryUsed()
+{
+#if defined(_WIN32)
+# if defined(_MSC_VER) && _MSC_VER < 1300
+  MEMORYSTATUS stat;
+  stat.dwLength = sizeof(stat);
+  GlobalMemoryStatus(&stat);
+  return (stat.dwTotalPhys - stat.dwAvailPhys)/1024;
+# else
+  MEMORYSTATUSEX statex;
+  statex.dwLength=sizeof(statex);
+  GlobalMemoryStatusEx(&statex);
+  return (statex.ullTotalPhys - statex.ullAvailPhys)/1024;
+# endif
+#elif defined(__linux)
+  const char *names[3]={"MemTotal:","MemFree:",NULL};
+  SystemInformation::LongLong values[2]={SystemInformation::LongLong(0)};
+  int ierr=GetFieldsFromFile("/proc/meminfo",names,values);
+  if (ierr)
+    {
+    return ierr;
+    }
+  SystemInformation::LongLong &memTotal=values[0];
+  SystemInformation::LongLong &memFree=values[1];
+  return memTotal - memFree;
+#elif defined(__APPLE__)
+  SystemInformation::LongLong psz=getpagesize();
+  if (psz<1)
+    {
+    return -1;
+    }
+  const char *names[4]={"Pages active:","Pages inactive:","Pages wired down:",NULL};
+  SystemInformation::LongLong values[3]={SystemInformation::LongLong(0)};
+  int ierr=GetFieldsFromCommand("vm_stat", names, values);
+  if (ierr)
+    {
+    return -1;
+    }
+  SystemInformation::LongLong &vmActive=values[0];
+  SystemInformation::LongLong &vmInactive=values[1];
+  SystemInformation::LongLong &vmWired=values[2];
+  return ((vmActive+vmInactive+vmWired)*psz)/1024;
+#else
+  return 0;
+#endif
+}
+
 /**
 /**
 Get system RAM used by the process associated with the given
 Get system RAM used by the process associated with the given
 process id in units of KiB.
 process id in units of KiB.
 */
 */
 SystemInformation::LongLong
 SystemInformation::LongLong
-SystemInformationImplementation::GetMemoryUsed()
+SystemInformationImplementation::GetProcMemoryUsed()
 {
 {
 #if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI)
 #if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI)
   long pid=GetCurrentProcessId();
   long pid=GetCurrentProcessId();
-
   HANDLE hProc;
   HANDLE hProc;
   hProc=OpenProcess(
   hProc=OpenProcess(
       PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
       PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
@@ -2960,7 +3291,6 @@ SystemInformationImplementation::GetMemoryUsed()
     {
     {
     return -1;
     return -1;
     }
     }
-
   PROCESS_MEMORY_COUNTERS pmc;
   PROCESS_MEMORY_COUNTERS pmc;
   int ok=GetProcessMemoryInfo(hProc,&pmc,sizeof(pmc));
   int ok=GetProcessMemoryInfo(hProc,&pmc,sizeof(pmc));
   CloseHandle(hProc);
   CloseHandle(hProc);
@@ -2970,7 +3300,7 @@ SystemInformationImplementation::GetMemoryUsed()
     }
     }
   return pmc.WorkingSetSize/1024;
   return pmc.WorkingSetSize/1024;
 #elif defined(__linux)
 #elif defined(__linux)
-  LongLong memUsed=0;
+  SystemInformation::LongLong memUsed=0;
   int ierr=GetFieldFromFile("/proc/self/status","VmRSS:",memUsed);
   int ierr=GetFieldFromFile("/proc/self/status","VmRSS:",memUsed);
   if (ierr)
   if (ierr)
     {
     {
@@ -2978,23 +3308,34 @@ SystemInformationImplementation::GetMemoryUsed()
     }
     }
   return memUsed;
   return memUsed;
 #elif defined(__APPLE__)
 #elif defined(__APPLE__)
+  SystemInformation::LongLong memUsed=0;
   pid_t pid=getpid();
   pid_t pid=getpid();
   kwsys_stl::ostringstream oss;
   kwsys_stl::ostringstream oss;
   oss << "ps -o rss= -p " << pid;
   oss << "ps -o rss= -p " << pid;
-  FILE *f=popen(oss.str().c_str(),"r");
-  if (f==0)
+  FILE *file=popen(oss.str().c_str(),"r");
+  if (file==0)
     {
     {
     return -1;
     return -1;
     }
     }
   oss.str("");
   oss.str("");
-  char buf[256]={'\0'};
-  while (fgets(buf, 256, f) != 0)
+  while (!feof(file) && !ferror(file))
     {
     {
-    oss << buf;
+    char buf[256]={'\0'};
+    errno=0;
+    size_t nRead=fread(buf,1,256,file);
+    if (ferror(file) && (errno==EINTR))
+      {
+      clearerr(file);
+      }
+    if (nRead) oss << buf;
+    }
+  int ierr=ferror(file);
+  pclose(file);
+  if (ierr)
+    {
+    return -2;
     }
     }
-  pclose(f);
   kwsys_stl::istringstream iss(oss.str());
   kwsys_stl::istringstream iss(oss.str());
-  LongLong memUsed=0;
   iss >> memUsed;
   iss >> memUsed;
   return memUsed;
   return memUsed;
 #else
 #else
@@ -3603,6 +3944,7 @@ bool SystemInformationImplementation::ParseSysCtl()
   if ( host_statistics(mach_host_self(), HOST_VM_INFO,
   if ( host_statistics(mach_host_self(), HOST_VM_INFO,
                        (host_info_t) &vmstat, &count) == KERN_SUCCESS )
                        (host_info_t) &vmstat, &count) == KERN_SUCCESS )
     {
     {
+    len = sizeof(value);
     err = sysctlbyname("hw.pagesize", &value, &len, NULL, 0);
     err = sysctlbyname("hw.pagesize", &value, &len, NULL, 0);
     int64_t available_memory = vmstat.free_count * value;
     int64_t available_memory = vmstat.free_count * value;
     this->AvailablePhysicalMemory = static_cast< size_t >( available_memory / 1048576 );
     this->AvailablePhysicalMemory = static_cast< size_t >( available_memory / 1048576 );
@@ -3613,7 +3955,7 @@ bool SystemInformationImplementation::ParseSysCtl()
   int mib[2] = { CTL_VM, VM_SWAPUSAGE };
   int mib[2] = { CTL_VM, VM_SWAPUSAGE };
   size_t miblen = sizeof(mib) / sizeof(mib[0]);
   size_t miblen = sizeof(mib) / sizeof(mib[0]);
   struct xsw_usage swap;
   struct xsw_usage swap;
-  len = sizeof(struct xsw_usage);
+  len = sizeof(swap);
   err = sysctl(mib, miblen, &swap, &len, NULL, 0);
   err = sysctl(mib, miblen, &swap, &len, NULL, 0);
   if (err == 0)
   if (err == 0)
     {
     {
@@ -3628,6 +3970,7 @@ bool SystemInformationImplementation::ParseSysCtl()
 // CPU Info
 // CPU Info
   len = sizeof(this->NumberOfPhysicalCPU);
   len = sizeof(this->NumberOfPhysicalCPU);
   sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, NULL, 0);
   sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, NULL, 0);
+  len = sizeof(this->NumberOfLogicalCPU);
   sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, NULL, 0);
   sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, NULL, 0);
   this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
   this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
     this->LogicalCPUPerPhysicalCPU();
     this->LogicalCPUPerPhysicalCPU();
@@ -3653,8 +3996,9 @@ bool SystemInformationImplementation::ParseSysCtl()
     if (machineBuf.find_first_of("Power") != kwsys_stl::string::npos)
     if (machineBuf.find_first_of("Power") != kwsys_stl::string::npos)
       {
       {
       this->ChipID.Vendor = "IBM";
       this->ChipID.Vendor = "IBM";
-      len = 4;
+      len = sizeof(this->ChipID.Family);
       err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, NULL, 0);
       err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, NULL, 0);
+      len = sizeof(this->ChipID.Model);
       err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, NULL, 0);
       err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, NULL, 0);
       this->FindManufacturer();
       this->FindManufacturer();
       }
       }
@@ -3679,8 +4023,8 @@ bool SystemInformationImplementation::ParseSysCtl()
     }
     }
 
 
   // brand string
   // brand string
-  ::memset(retBuf, 0, 128);
-  len = 128;
+  ::memset(retBuf, 0, sizeof(retBuf));
+  len = sizeof(retBuf);
   err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, NULL, 0);
   err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, NULL, 0);
   if (!err)
   if (!err)
     {
     {
@@ -3692,6 +4036,7 @@ bool SystemInformationImplementation::ParseSysCtl()
   len = sizeof(value);
   len = sizeof(value);
   err = sysctlbyname("hw.l1icachesize", &value, &len, NULL, 0);
   err = sysctlbyname("hw.l1icachesize", &value, &len, NULL, 0);
   this->Features.L1CacheSize = static_cast< int >( value );
   this->Features.L1CacheSize = static_cast< int >( value );
+  len = sizeof(value);
   err = sysctlbyname("hw.l2cachesize", &value, &len, NULL, 0);
   err = sysctlbyname("hw.l2cachesize", &value, &len, NULL, 0);
   this->Features.L2CacheSize = static_cast< int >( value );
   this->Features.L2CacheSize = static_cast< int >( value );
 
 

+ 39 - 10
SystemInformation.hxx.in

@@ -24,7 +24,6 @@
 namespace @KWSYS_NAMESPACE@
 namespace @KWSYS_NAMESPACE@
 {
 {
 
 
-
 // forward declare the implementation class
 // forward declare the implementation class
 class SystemInformationImplementation;
 class SystemInformationImplementation;
 
 
@@ -96,15 +95,44 @@ public:
   size_t GetTotalPhysicalMemory();
   size_t GetTotalPhysicalMemory();
   size_t GetAvailablePhysicalMemory();
   size_t GetAvailablePhysicalMemory();
 
 
-  // returns an informative general description if the ram
-  // on this system
-  kwsys_stl::string GetMemoryDescription();
-
-  // Retrieve physical memory information in kib
-  LongLong GetMemoryTotal();
-  LongLong GetMemoryUsed();
-
-  // enable/disable stack trace signal handler.
+  // returns an informative general description if the installed and
+  // available ram on this system. See the  GetHostMmeoryTotal, and
+  // Get{Host,Proc}MemoryAvailable methods for more information.
+  kwsys_stl::string GetMemoryDescription(
+        const char *hostLimitEnvVarName=NULL,
+        const char *procLimitEnvVarName=NULL);
+
+  // Retrieve amount of physical memory installed on the system in KiB
+  // units.
+  LongLong GetHostMemoryTotal();
+
+  // Get total system RAM in units of KiB available colectivley to all
+  // processes in a process group. An example of a process group
+  // are the processes comprising an mpi program which is running in
+  // parallel. The amount of memory reported may differ from the host
+  // total if a host wide resource limit is applied. Such reource limits
+  // are reported to us via an applicaiton specified environment variable.
+  LongLong GetHostMemoryAvailable(const char *hostLimitEnvVarName=NULL);
+
+  // Get total system RAM in units of KiB available to this process.
+  // This may differ from the host available if a per-process resource
+  // limit is applied. per-process memory limits are applied on unix
+  // system via rlimit api. Resource limits that are not imposed via
+  // rlimit api may be reported to us via an application specified
+  // environment variable.
+  LongLong GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName=NULL,
+        const char *procLimitEnvVarName=NULL);
+
+  // Get the system RAM used by all processes on the host, in units of KiB.
+  LongLong GetHostMemoryUsed();
+
+  // Get system RAM used by this process id in units of KiB.
+  LongLong GetProcMemoryUsed();
+
+  // enable/disable stack trace signal handler. In order to
+  // produce an informative stack trace the application should
+  // be dynamically linked and compiled with debug symbols.
   static
   static
   void SetStackTraceOnError(int enable);
   void SetStackTraceOnError(int enable);
 
 
@@ -113,6 +141,7 @@ public:
   void RunOSCheck();
   void RunOSCheck();
   void RunMemoryCheck();
   void RunMemoryCheck();
 };
 };
+
 } // namespace @KWSYS_NAMESPACE@
 } // namespace @KWSYS_NAMESPACE@
 
 
 /* Undefine temporary macros.  */
 /* Undefine temporary macros.  */

+ 66 - 0
kwsysPlatformTestsCXX.cxx

@@ -358,6 +358,30 @@ int main()
 }
 }
 #endif
 #endif
 
 
+#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
+int test_istream(kwsys_ios::istream& is, __int64& x)
+{
+  return (is >> x)? 1:0;
+}
+int main()
+{
+  __int64 x = 0;
+  return test_istream(kwsys_ios::cin, x);
+}
+#endif
+
+#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
+int test_ostream(kwsys_ios::ostream& os, __int64 x)
+{
+  return (os << x)? 1:0;
+}
+int main()
+{
+  __int64 x = 0;
+  return test_ostream(kwsys_ios::cout, x);
+}
+#endif
+
 #ifdef TEST_KWSYS_CHAR_IS_SIGNED
 #ifdef TEST_KWSYS_CHAR_IS_SIGNED
 /* Return 0 for char signed and 1 for char unsigned.  */
 /* Return 0 for char signed and 1 for char unsigned.  */
 int main()
 int main()
@@ -428,6 +452,48 @@ int main()
 }
 }
 #endif
 #endif
 
 
+#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
+# if defined(KWSYS_HAS_LFS)
+#  define _LARGEFILE_SOURCE
+#  define _LARGEFILE64_SOURCE
+#  define _LARGE_FILES
+#  define _FILE_OFFSET_BITS 64
+# endif
+# include <sys/resource.h>
+int main()
+{
+  struct rlimit64 rlim;
+  return getrlimit64(0,&rlim);
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_ATOLL
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(atoll(str));
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_ATOL
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(atol(str));
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS__ATOI64
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(_atoi64(str));
+}
+#endif
+
 #ifdef TEST_KWSYS_CXX_TYPE_INFO
 #ifdef TEST_KWSYS_CXX_TYPE_INFO
 /* Collect fundamental type information and save it to a CMake script.  */
 /* Collect fundamental type information and save it to a CMake script.  */
 
 

+ 30 - 4
testSystemInformation.cxx

@@ -13,8 +13,6 @@
 #include KWSYS_HEADER(SystemInformation.hxx)
 #include KWSYS_HEADER(SystemInformation.hxx)
 #include KWSYS_HEADER(ios/iostream)
 #include KWSYS_HEADER(ios/iostream)
 
 
-
-
 // Work-around CMake dependency scanning limitation.  This must
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 // duplicate the above list of headers.
 #if 0
 #if 0
@@ -22,12 +20,31 @@
 # include "kwsys_ios_iostream.h.in"
 # include "kwsys_ios_iostream.h.in"
 #endif
 #endif
 
 
-#define printMethod(inof, m) kwsys_ios::cout << #m << ": " \
+#if defined(KWSYS_USE_LONG_LONG)
+# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#elif defined(KWSYS_USE___INT64)
+# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#else
+# error "No Long Long"
+#endif
+
+#define printMethod(info, m) kwsys_ios::cout << #m << ": " \
 << info.m() << "\n"
 << info.m() << "\n"
 
 
-#define printMethod2(inof, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod2(info, m, unit) kwsys_ios::cout << #m << ": " \
 << info.m() << " " << unit << "\n"
 << info.m() << " " << unit << "\n"
 
 
+#define printMethod3(info, m, unit) kwsys_ios::cout << #m << ": " \
+<< iostreamLongLong(info.m) << " " << unit << "\n"
+
 int testSystemInformation(int, char*[])
 int testSystemInformation(int, char*[])
 {
 {
   kwsys::SystemInformation info;
   kwsys::SystemInformation info;
@@ -35,7 +52,11 @@ int testSystemInformation(int, char*[])
   info.RunOSCheck();
   info.RunOSCheck();
   info.RunMemoryCheck();
   info.RunMemoryCheck();
   printMethod(info, GetOSName);
   printMethod(info, GetOSName);
+  printMethod(info, GetOSIsLinux);
+  printMethod(info, GetOSIsApple);
+  printMethod(info, GetOSIsWindows);
   printMethod(info, GetHostname);
   printMethod(info, GetHostname);
+  printMethod(info, GetFullyQualifiedDomainName);
   printMethod(info, GetOSRelease);
   printMethod(info, GetOSRelease);
   printMethod(info, GetOSVersion);
   printMethod(info, GetOSVersion);
   printMethod(info, GetOSPlatform);
   printMethod(info, GetOSPlatform);
@@ -58,6 +79,11 @@ int testSystemInformation(int, char*[])
   printMethod2(info, GetAvailableVirtualMemory, "MB");
   printMethod2(info, GetAvailableVirtualMemory, "MB");
   printMethod2(info, GetTotalPhysicalMemory, "MB");
   printMethod2(info, GetTotalPhysicalMemory, "MB");
   printMethod2(info, GetAvailablePhysicalMemory, "MB");
   printMethod2(info, GetAvailablePhysicalMemory, "MB");
+  printMethod3(info, GetHostMemoryTotal(), "KiB");
+  printMethod3(info, GetHostMemoryAvailable("KWSHL"), "KiB");
+  printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
+  printMethod3(info, GetHostMemoryUsed(), "KiB");
+  printMethod3(info, GetProcMemoryUsed(), "KiB");
 
 
   //int GetProcessorCacheXSize(long int);
   //int GetProcessorCacheXSize(long int);
 //  bool DoesCPUSupportFeature(long int);
 //  bool DoesCPUSupportFeature(long int);