#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
defined(__osf__) || defined(__EMX__))
extern "C"
{
- #ifdef __SUN__
+ #ifdef __EMX__
+ /* I copied this from the XFree86 diffs. AV. */
+ #define INCL_DOSPROCESS
+ #include <os2.h>
+ inline void usleep(unsigned long delay)
+ {
+ DosSleep(delay ? (delay/1000l) : 1l);
+ }
+ #else // Unix
int usleep(unsigned int usec);
- #else // !Sun
- #ifdef __EMX__
- /* I copied this from the XFree86 diffs. AV. */
- #define INCL_DOSPROCESS
- #include <os2.h>
- inline void usleep(unsigned long delay)
- {
- DosSleep(delay ? (delay/1000l) : 1l);
- }
- #else // !Sun && !EMX
- void usleep(unsigned long usec);
- #endif
- #endif // Sun/EMX/Something else
+ #endif // __EMX__/Unix
};
#define HAVE_USLEEP 1
long wxExecute( const wxString& command, int flags, wxProcess *process )
{
wxCHECK_MSG( !command.empty(), 0, wxT("can't exec empty command") );
- wxLogDebug(wxString(wxT("Launching: ")) + command);
+
+ wxLogTrace(wxT("exec"), wxT("Executing \"%s\""), command.c_str());
#if wxUSE_THREADS
// fork() doesn't mix well with POSIX threads: on many systems the program
// 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
while (argv[mb_argc])
{
- wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]);
+ wxWX2MBbuf mb_arg = wxSafeConvertWX2MB(argv[mb_argc]);
mb_argv[mb_argc] = strdup(mb_arg);
mb_argc++;
}
// 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() )
}
if ((ptr = wxGetenv(wxT("USER"))) != NULL || (ptr = wxGetenv(wxT("LOGNAME"))) != NULL)
{
- who = getpwnam(wxConvertWX2MB(ptr));
+ who = getpwnam(wxSafeConvertWX2MB(ptr));
}
// We now make sure the the user exists!
who = getpwnam (user.mb_str());
}
- return wxConvertMB2WX(who ? who->pw_dir : 0);
+ return wxSafeConvertMB2WX(who ? who->pw_dir : 0);
}
// ----------------------------------------------------------------------------
// 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)
bool ok = uname(&uts) != -1;
if ( ok )
{
- wxStrncpy(buf, wxConvertMB2WX(uts.nodename), sz - 1);
+ wxStrncpy(buf, wxSafeConvertMB2WX(uts.nodename), sz - 1);
buf[sz] = wxT('\0');
}
#elif defined(HAVE_GETHOSTNAME)
- bool ok = gethostname(buf, sz) != -1;
+ char cbuf[sz];
+ bool ok = gethostname(cbuf, sz) != -1;
+ if ( ok )
+ {
+ wxStrncpy(buf, wxSafeConvertMB2WX(cbuf), sz - 1);
+ buf[sz] = wxT('\0');
+ }
#else // no uname, no gethostname
wxFAIL_MSG(wxT("don't know host name for this machine"));
{
if ( !wxStrchr(buf, wxT('.')) )
{
- struct hostent *host = gethostbyname(wxConvertWX2MB(buf));
+ struct hostent *host = gethostbyname(wxSafeConvertWX2MB(buf));
if ( !host )
{
wxLogSysError(_("Cannot get the official hostname"));
else
{
// the canonical name
- wxStrncpy(buf, wxConvertMB2WX(host->h_name), sz);
+ wxStrncpy(buf, wxSafeConvertMB2WX(host->h_name), sz);
}
}
//else: it's already a FQDN (BSD behaves this way)
*buf = wxT('\0');
if ((who = getpwuid(getuid ())) != NULL)
{
- wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1);
+ wxStrncpy (buf, wxSafeConvertMB2WX(who->pw_name), sz - 1);
return true;
}
bool wxGetUserName(wxChar *buf, int sz)
{
+#ifdef HAVE_PW_GECOS
struct passwd *who;
*buf = wxT('\0');
if ((who = getpwuid (getuid ())) != NULL)
{
- // pw_gecos field in struct passwd is not standard
-#ifdef HAVE_PW_GECOS
char *comma = strchr(who->pw_gecos, ',');
if (comma)
*comma = '\0'; // cut off non-name comment fields
- wxStrncpy (buf, wxConvertMB2WX(who->pw_gecos), sz - 1);
-#else // !HAVE_PW_GECOS
- wxStrncpy (buf, wxConvertMB2WX(who->pw_name), sz - 1);
-#endif // HAVE_PW_GECOS/!HAVE_PW_GECOS
+ 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
}
-// 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 wxEmptyString;
+
+ 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);
return (wxMemorySize)memFree;
}
-#elif defined(__SUN__) && defined(_SC_AVPHYS_PAGES)
- return (wxMemorySize)(sysconf(_SC_AVPHYS_PAGES)*sysconf(_SC_PAGESIZE));
#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
{
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