+ wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_gecos), sz - 1);
+ return true;
+ }
+
+ return false;
+#else // !HAVE_PW_GECOS
+ return wxGetUserId(buf, sz);
+#endif // HAVE_PW_GECOS/!HAVE_PW_GECOS
+}
+
+bool wxIsPlatform64Bit()
+{
+ const wxString machine = wxGetCommandOutput(wxT("uname -m"));
+
+ // the test for "64" is obviously not 100% reliable but seems to work fine
+ // in practice
+ return machine.Contains(wxT("64")) ||
+ machine.Contains(wxT("alpha"));
+}
+
+// these functions are in mac/utils.cpp for wxMac
+#ifndef __WXMAC__
+
+wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
+{
+ // get OS version
+ int major, minor;
+ wxString release = wxGetCommandOutput(wxT("uname -r"));
+ if ( release.empty() ||
+ wxSscanf(release.c_str(), wxT("%d.%d"), &major, &minor) != 2 )
+ {
+ // failed to get version string or unrecognized format
+ major =
+ minor = -1;
+ }
+
+ if ( verMaj )
+ *verMaj = major;
+ if ( verMin )
+ *verMin = minor;
+
+ // try to understand which OS are we running
+ wxString kernel = wxGetCommandOutput(wxT("uname -s"));
+ if ( kernel.empty() )
+ kernel = wxGetCommandOutput(wxT("uname -o"));
+
+ if ( kernel.empty() )
+ return wxOS_UNKNOWN;
+
+ return wxPlatformInfo::GetOperatingSystemId(kernel);
+}
+
+wxString wxGetOsDescription()
+{
+ return wxGetCommandOutput(wxT("uname -s -r -m"));
+}
+
+#endif // !__WXMAC__
+
+unsigned long wxGetProcessId()
+{
+ return (unsigned long)getpid();
+}
+
+wxMemorySize wxGetFreeMemory()
+{
+#if defined(__LINUX__)
+ // get it from /proc/meminfo
+ FILE *fp = fopen("/proc/meminfo", "r");
+ if ( fp )
+ {
+ long memFree = -1;
+
+ char buf[1024];
+ if ( fgets(buf, WXSIZEOF(buf), fp) && fgets(buf, WXSIZEOF(buf), fp) )
+ {
+ // /proc/meminfo changed its format in kernel 2.6
+ if ( wxPlatformInfo().CheckOSVersion(2, 6) )
+ {
+ unsigned long cached, buffers;
+ sscanf(buf, "MemFree: %ld", &memFree);
+
+ fgets(buf, WXSIZEOF(buf), fp);
+ sscanf(buf, "Buffers: %lu", &buffers);
+
+ fgets(buf, WXSIZEOF(buf), fp);
+ sscanf(buf, "Cached: %lu", &cached);
+
+ // add to "MemFree" also the "Buffers" and "Cached" values as
+ // free(1) does as otherwise the value never makes sense: for
+ // kernel 2.6 it's always almost 0
+ memFree += buffers + cached;
+
+ // values here are always expressed in kB and we want bytes
+ memFree *= 1024;
+ }
+ else // Linux 2.4 (or < 2.6, anyhow)
+ {
+ long memTotal, memUsed;
+ sscanf(buf, "Mem: %ld %ld %ld", &memTotal, &memUsed, &memFree);
+ }
+ }
+
+ fclose(fp);
+
+ return (wxMemorySize)memFree;
+ }
+#elif defined(__SGI__)
+ struct rminfo realmem;
+ if ( sysmp(MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0 )
+ return ((wxMemorySize)realmem.physmem * sysconf(_SC_PAGESIZE));
+#elif defined(_SC_AVPHYS_PAGES)
+ return ((wxMemorySize)sysconf(_SC_AVPHYS_PAGES))*sysconf(_SC_PAGESIZE);
+//#elif defined(__FREEBSD__) -- might use sysctl() to find it out, probably
+#endif
+
+ // can't find it out
+ return -1;
+}
+
+bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
+{
+#if defined(HAVE_STATFS) || defined(HAVE_STATVFS)
+ // the case to "char *" is needed for AIX 4.3
+ wxStatfs_t fs;
+ if ( wxStatfs((char *)(const char*)path.fn_str(), &fs) != 0 )
+ {
+ wxLogSysError( wxT("Failed to get file system statistics") );
+
+ return false;
+ }
+
+ // under Solaris we also have to use f_frsize field instead of f_bsize
+ // which is in general a multiple of f_frsize
+#ifdef HAVE_STATVFS
+ wxDiskspaceSize_t blockSize = fs.f_frsize;
+#else // HAVE_STATFS
+ wxDiskspaceSize_t blockSize = fs.f_bsize;
+#endif // HAVE_STATVFS/HAVE_STATFS
+
+ if ( pTotal )
+ {
+ *pTotal = wxDiskspaceSize_t(fs.f_blocks) * blockSize;
+ }
+
+ if ( pFree )
+ {
+ *pFree = wxDiskspaceSize_t(fs.f_bavail) * blockSize;
+ }
+
+ return true;
+#else // !HAVE_STATFS && !HAVE_STATVFS
+ return false;
+#endif // HAVE_STATFS
+}
+
+// ----------------------------------------------------------------------------
+// env vars
+// ----------------------------------------------------------------------------
+
+#if USE_PUTENV
+
+WX_DECLARE_STRING_HASH_MAP(char *, wxEnvVars);
+
+static wxEnvVars gs_envVars;
+
+class wxSetEnvModule : public wxModule
+{
+public:
+ virtual bool OnInit() { return true; }
+ virtual void OnExit()
+ {
+ for ( wxEnvVars::const_iterator i = gs_envVars.begin();
+ i != gs_envVars.end();
+ ++i )
+ {
+ free(i->second);
+ }
+
+ gs_envVars.clear();
+ }
+
+ DECLARE_DYNAMIC_CLASS(wxSetEnvModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxSetEnvModule, wxModule)
+
+#endif // USE_PUTENV
+
+bool wxGetEnv(const wxString& var, wxString *value)
+{
+ // wxGetenv is defined as getenv()
+ char *p = wxGetenv(var);
+ if ( !p )
+ return false;
+
+ if ( value )
+ {
+ *value = p;
+ }
+
+ return true;
+}
+
+static bool wxDoSetEnv(const wxString& variable, const char *value)
+{
+#if defined(HAVE_SETENV)
+ if ( !value )
+ {
+#ifdef HAVE_UNSETENV
+ // don't test unsetenv() return value: it's void on some systems (at
+ // least Darwin)
+ unsetenv(variable.mb_str());
+ return true;