/////////////////////////////////////////////////////////////////////////////
-// Name: unix/utilsunx.cpp
+// Name: src/unix/utilsunx.cpp
// Purpose: generic Unix implementation of many wx functions
// Author: Vadim Zeitlin
// Id: $Id$
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
-#include "wx/defs.h"
-#include "wx/string.h"
+#include "wx/utils.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/app.h"
+#endif
-#include "wx/intl.h"
-#include "wx/log.h"
-#include "wx/app.h"
#include "wx/apptrait.h"
-#include "wx/utils.h"
#include "wx/process.h"
#include "wx/thread.h"
#include <pwd.h>
-#if wxUSE_STREAMS
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#define HAS_PIPE_INPUT_STREAM (wxUSE_STREAMS && wxUSE_FILE)
+
+#if HAS_PIPE_INPUT_STREAM
// define this to let wxexec.cpp know that we know what we're doing
#define _WX_USED_BY_WXEXECUTE_
#include "../common/execcmn.cpp"
-#endif // wxUSE_STREAMS
+#endif // HAS_PIPE_INPUT_STREAM
#if wxUSE_BASE
// split the command line in arguments
do
{
- argument=wxT("");
+ argument = wxEmptyString;
quotechar = wxT('\0');
// eat leading whitespace:
return system(wxString::Format(_T("init %c"), level).mb_str()) == 0;
}
-wxPowerType wxGetPowerType()
-{
- // TODO
- return wxPOWER_UNKNOWN;
-}
-
-wxBatteryState wxGetBatteryState()
-{
- // TODO
- return wxBATTERY_UNKNOWN_STATE;
-}
-
// ----------------------------------------------------------------------------
// wxStream classes to support IO redirection in wxExecute
// ----------------------------------------------------------------------------
-#if wxUSE_STREAMS
+#if HAS_PIPE_INPUT_STREAM
bool wxPipeInputStream::CanRead() const
{
}
}
-#endif // wxUSE_STREAMS
+#endif // HAS_PIPE_INPUT_STREAM
// ----------------------------------------------------------------------------
// wxExecute: the real worker function
// prepare for IO redirection
-#if wxUSE_STREAMS
+#if HAS_PIPE_INPUT_STREAM
// the input buffer bufOut is connected to stdout, this is why it is
// called bufOut and not bufIn
wxStreamTempInputBuffer bufOut,
bufErr;
-#endif // wxUSE_STREAMS
+#endif // HAS_PIPE_INPUT_STREAM
if ( process && process->IsRedirected() )
{
-#if wxUSE_STREAMS
+#if HAS_PIPE_INPUT_STREAM
wxOutputStream *inStream =
new wxFileOutputStream(pipeIn.Detach(wxPipe::Write));
execData.bufOut = &bufOut;
execData.bufErr = &bufErr;
-#endif // wxUSE_STREAMS
+#endif // HAS_PIPE_INPUT_STREAM
}
if ( pipeIn.IsOk() )
// network and user id routines
// ----------------------------------------------------------------------------
+// private utility function which returns output of the given command, removing
+// the trailing newline
+static wxString wxGetCommandOutput(const wxString &cmd)
+{
+ FILE *f = popen(cmd.ToAscii(), "r");
+ if ( !f )
+ {
+ wxLogSysError(_T("Executing \"%s\" failed"), cmd.c_str());
+ return wxEmptyString;
+ }
+
+ wxString s;
+ char buf[256];
+ while ( !feof(f) )
+ {
+ if ( !fgets(buf, sizeof(buf), f) )
+ break;
+
+ s += wxString::FromAscii(buf);
+ }
+
+ pclose(f);
+
+ if ( !s.empty() && s.Last() == _T('\n') )
+ s.RemoveLast();
+
+ return s;
+}
+
// retrieve either the hostname or FQDN depending on platform (caller must
// check whether it's one or the other, this is why this function is for
// private use only)
return false;
}
-// this function is in mac/utils.cpp for wxMac
+bool wxIsPlatform64Bit()
+{
+ wxString machine = wxGetCommandOutput(wxT("uname -m"));
+
+ // NOTE: these tests are not 100% reliable!
+ return machine.Contains(wxT("AMD64")) ||
+ machine.Contains(wxT("IA64")) ||
+ machine.Contains(wxT("x64")) ||
+ machine.Contains(wxT("X64")) ||
+ machine.Contains(wxT("alpha")) ||
+ machine.Contains(wxT("hppa64")) ||
+ machine.Contains(wxT("ppc64"));
+}
+
+// these functions are in mac/utils.cpp for wxMac
#ifndef __WXMAC__
-wxString wxGetOsDescription()
+wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
{
- FILE *f = popen("uname -s -r -m", "r");
- if (f)
+ // get OS version
+ int major, minor;
+ wxString release = wxGetCommandOutput(wxT("uname -r"));
+ if ( !release.empty() && wxSscanf(release, wxT("%d.%d"), &major, &minor) != 2 )
{
- char buf[256];
- size_t c = fread(buf, 1, sizeof(buf) - 1, f);
- pclose(f);
- // Trim newline from output.
- if (c && buf[c - 1] == '\n')
- --c;
- buf[c] = '\0';
- return wxString::FromAscii( buf );
+ // unrecognized uname string format
+ major =
+ minor = -1;
}
- wxFAIL_MSG( _T("uname failed") );
- return _T("");
+
+ 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__
char buf[1024];
if ( fgets(buf, WXSIZEOF(buf), fp) && fgets(buf, WXSIZEOF(buf), fp) )
{
- long memTotal, memUsed;
- sscanf(buf, "Mem: %ld %ld %ld", &memTotal, &memUsed, &memFree);
+ // /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);
{
bool idle = true;
-#if wxUSE_STREAMS
+#if HAS_PIPE_INPUT_STREAM
if ( execData.bufOut )
{
execData.bufOut->Update();
execData.bufErr->Update();
idle = false;
}
-#endif // wxUSE_STREAMS
+#endif // HAS_PIPE_INPUT_STREAM
// don't consume 100% of the CPU while we're sitting in this
// loop