utilsunx.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,275 行 · 第 1/3 页
CPP
1,275 行
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
return true;
}
return false;
}
// this function is in mac/utils.cpp for wxMac
#ifndef __WXMAC__
wxString wxGetOsDescription()
{
FILE *f = popen("uname -s -r -m", "r");
if (f)
{
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 );
}
wxFAIL_MSG( _T("uname failed") );
return _T("");
}
#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) )
{
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(__FREEBSD__) -- might use sysctl() to find it out, probably
#endif
// can't find it out
return -1;
}
bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *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
wxLongLong blockSize = fs.f_frsize;
#else // HAVE_STATFS
wxLongLong blockSize = fs.f_bsize;
#endif // HAVE_STATVFS/HAVE_STATFS
if ( pTotal )
{
*pTotal = wxLongLong(fs.f_blocks) * blockSize;
}
if ( pFree )
{
*pFree = wxLongLong(fs.f_bavail) * blockSize;
}
return true;
#else // !HAVE_STATFS && !HAVE_STATVFS
return false;
#endif // HAVE_STATFS
}
// ----------------------------------------------------------------------------
// env vars
// ----------------------------------------------------------------------------
bool wxGetEnv(const wxString& var, wxString *value)
{
// wxGetenv is defined as getenv()
wxChar *p = wxGetenv(var);
if ( !p )
return false;
if ( value )
{
*value = p;
}
return true;
}
bool wxSetEnv(const wxString& variable, const wxChar *value)
{
#if defined(HAVE_SETENV)
return setenv(variable.mb_str(),
value ? (const char *)wxString(value).mb_str()
: NULL,
1 /* overwrite */) == 0;
#elif defined(HAVE_PUTENV)
wxString s = variable;
if ( value )
s << _T('=') << value;
// transform to ANSI
const wxWX2MBbuf p = s.mb_str();
// the string will be free()d by libc
char *buf = (char *)malloc(strlen(p) + 1);
strcpy(buf, p);
return putenv(buf) == 0;
#else // no way to set an env var
return false;
#endif
}
// ----------------------------------------------------------------------------
// signal handling
// ----------------------------------------------------------------------------
#if wxUSE_ON_FATAL_EXCEPTION
#include <signal.h>
extern "C" void wxFatalSignalHandler(wxTYPE_SA_HANDLER)
{
if ( wxTheApp )
{
// give the user a chance to do something special about this
wxTheApp->OnFatalException();
}
abort();
}
bool wxHandleFatalExceptions(bool doit)
{
// old sig handlers
static bool s_savedHandlers = false;
static struct sigaction s_handlerFPE,
s_handlerILL,
s_handlerBUS,
s_handlerSEGV;
bool ok = true;
if ( doit && !s_savedHandlers )
{
// install the signal handler
struct sigaction act;
// some systems extend it with non std fields, so zero everything
memset(&act, 0, sizeof(act));
act.sa_handler = wxFatalSignalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
ok &= sigaction(SIGFPE, &act, &s_handlerFPE) == 0;
ok &= sigaction(SIGILL, &act, &s_handlerILL) == 0;
ok &= sigaction(SIGBUS, &act, &s_handlerBUS) == 0;
ok &= sigaction(SIGSEGV, &act, &s_handlerSEGV) == 0;
if ( !ok )
{
wxLogDebug(_T("Failed to install our signal handler."));
}
s_savedHandlers = true;
}
else if ( s_savedHandlers )
{
// uninstall the signal handler
ok &= sigaction(SIGFPE, &s_handlerFPE, NULL) == 0;
ok &= sigaction(SIGILL, &s_handlerILL, NULL) == 0;
ok &= sigaction(SIGBUS, &s_handlerBUS, NULL) == 0;
ok &= sigaction(SIGSEGV, &s_handlerSEGV, NULL) == 0;
if ( !ok )
{
wxLogDebug(_T("Failed to uninstall our signal handler."));
}
s_savedHandlers = false;
}
//else: nothing to do
return ok;
}
#endif // wxUSE_ON_FATAL_EXCEPTION
// ----------------------------------------------------------------------------
// error and debug output routines (deprecated, use wxLog)
// ----------------------------------------------------------------------------
#if WXWIN_COMPATIBILITY_2_2
void wxDebugMsg( const char *format, ... )
{
va_list ap;
va_start( ap, format );
vfprintf( stderr, format, ap );
fflush( stderr );
va_end(ap);
}
void wxError( const wxString &msg, const wxString &title )
{
wxFprintf( stderr, _("Error ") );
if (!title.IsNull()) wxFprintf( stderr, wxT("%s "), WXSTRINGCAST(title) );
if (!msg.IsNull()) wxFprintf( stderr, wxT(": %s"), WXSTRINGCAST(msg) );
wxFprintf( stderr, wxT(".\n") );
}
void wxFatalError( const wxString &msg, const wxString &title )
{
wxFprintf( stderr, _("Error ") );
if (!title.IsNull()) wxFprintf( stderr, wxT("%s "), WXSTRINGCAST(title) );
if (!msg.IsNull()) wxFprintf( stderr, wxT(": %s"), WXSTRINGCAST(msg) );
wxFprintf( stderr, wxT(".\n") );
exit(3); // the same exit code as for abort()
}
#endif // WXWIN_COMPATIBILITY_2_2
#endif // wxUSE_BASE
#if wxUSE_GUI
// ----------------------------------------------------------------------------
// wxExecute support
// ----------------------------------------------------------------------------
// Darwin doesn't use the same process end detection mechanisms so we don't
// need wxExecute-related helpers for it
#if !(defined(__DARWIN__) && defined(__WXMAC__))
bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData)
{
return execData.pipeEndProcDetect.Create();
}
bool wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd)
{
return fd == (execData.pipeEndProcDetect)[wxPipe::Write];
}
void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData)
{
execData.pipeEndProcDetect.Detach(wxPipe::Write);
execData.pipeEndProcDetect.Close();
}
#else // !Darwin
bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData))
{
return true;
}
bool
wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData),
int WXUNUSED(fd))
{
return false;
}
void
wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData))
{
// nothing to do here, we don't use the pipe
}
#endif // !Darwin/Darwin
int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
{
wxEndProcessData *endProcData = new wxEndProcessData;
const int flags = execData.flags;
// wxAddProcessCallback is now (with DARWIN) allowed to call the
// callback function directly if the process terminates before
// the callback can be added to the run loop. Set up the endProcData.
if ( flags & wxEXEC_SYNC )
{
// we may have process for capturing the program output, but it's
// not used in wxEndProcessData in the case of sync execution
endProcData->process = NULL;
// sync execution: indicate it by negating the pid
endProcData->pid = -execData.pid;
}
else
{
// async execution, nothing special to do -- caller will be
// notified about the process termination if process != NULL, endProcData
// will be deleted in GTK_EndProcessDetector
endProcData->process = execData.process;
endProcData->pid = execData.pid;
}
#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
#else
endProcData->tag = wxAddProcessCallback
(
endProcData,
execData.pipeEndProcDetect.Detach(wxPipe::Read)
);
execData.pipeEndProcDetect.Close();
#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
if ( flags & wxEXEC_SYNC )
{
wxBusyCursor bc;
wxWindowDisabler *wd = flags & wxEXEC_NODISABLE ? NULL
: new wxWindowDisabler;
// endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
// process terminates
while ( endProcData->pid != 0 )
{
bool idle = true;
#if wxUSE_STREAMS
if ( execData.bufOut )
{
execData.bufOut->Update();
idle = false;
}
if ( execData.bufErr )
{
execData.bufErr->Update();
idle = false;
}
#endif // wxUSE_STREAMS
// don't consume 100% of the CPU while we're sitting in this
// loop
if ( idle )
wxMilliSleep(1);
// give GTK+ a chance to call GTK_EndProcessDetector here and
// also repaint the GUI
wxYield();
}
int exitcode = endProcData->exitcode;
delete wd;
delete endProcData;
return exitcode;
}
else // async execution
{
return execData.pid;
}
}
#endif // wxUSE_GUI
#if wxUSE_BASE
void wxHandleProcessTermination(wxEndProcessData *proc_data)
{
// notify user about termination if required
if ( proc_data->process )
{
proc_data->process->OnTerminate(proc_data->pid, proc_data->exitcode);
}
// clean up
if ( proc_data->pid > 0 )
{
delete proc_data;
}
else
{
// let wxExecute() know that the process has terminated
proc_data->pid = 0;
}
}
#endif // wxUSE_BASE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?