X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/accb325754496ee949369884bd1bc2c1263c89ff..b09bda689c8525886d217a9b171b354391cd6d78:/src/unix/utilsunx.cpp diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index deeaa836ba..1f09b3d448 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -28,6 +28,10 @@ #include "wx/stream.h" +#ifdef HAVE_STATFS + #include +#endif // HAVE_STATFS + #if wxUSE_GUI #include "wx/unix/execute.h" #endif @@ -135,9 +139,39 @@ void wxUsleep(unsigned long milliseconds) // process management // ---------------------------------------------------------------------------- -int wxKill(long pid, wxSignal sig) +int wxKill(long pid, wxSignal sig, wxKillError *rc) { - return kill((pid_t)pid, (int)sig); + int err = kill((pid_t)pid, (int)sig); + if ( rc ) + { + switch ( err ) + { + case 0: + *rc = wxKILL_OK; + break; + + case EINVAL: + *rc = wxKILL_BAD_SIGNAL; + break; + + case EPERM: + *rc = wxKILL_ACCESS_DENIED; + break; + + case ESRCH: + *rc = wxKILL_NO_PROCESS; + break; + + default: + // this goes against Unix98 docs so log it + wxLogDebug(_T("unexpected kill(2) return value %d"), err); + + // something else... + *rc = wxKILL_ERROR; + } + } + + return err; } #define WXEXECUTE_NARGS 127 @@ -264,17 +298,33 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data) } while ( rc == -1 && errno == EINTR ); - - if( rc == -1 || ! (WIFEXITED(status) || WIFSIGNALED(status)) ) + if (rc == -1) + { + // JACS: this could happen if the process was terminated and waitpid called, + // so commenting out for now. + //wxLogSysError(_("Waiting for subprocess termination failed (return code = -1)")); + } + else if (! (WIFEXITED(status))) { - wxLogSysError(_("Waiting for subprocess termination failed")); + wxLogSysError(_("Waiting for subprocess termination failed (WIFEXITED returned zero)")); + /* AFAIK, this can only happen if something went wrong within wxGTK, i.e. due to a race condition or some serious bug. After having fixed the order of statements in GTK_EndProcessDetector(). (KB) */ } - else + else if (WIFSIGNALED(status)) + { + wxLogSysError(_("Waiting for subprocess termination failed (signal not caught)")); + + /* AFAIK, this can only happen if something went wrong within + wxGTK, i.e. due to a race condition or some serious bug. + After having fixed the order of statements in + GTK_EndProcessDetector(). (KB) + */ + } + // else { // notify user about termination if required if (proc_data->process) @@ -303,6 +353,8 @@ void wxHandleProcessTermination(wxEndProcessData *proc_data) // wxStream classes to support IO redirection in wxExecute // ---------------------------------------------------------------------------- +#if wxUSE_STREAMS + class wxProcessFileInputStream : public wxInputStream { public: @@ -399,6 +451,8 @@ size_t wxProcessFileOutputStream::OnSysWrite(const void *buffer, size_t bufsize) return ret; } +#endif // wxUSE_STREAMS + long wxExecute(wxChar **argv, bool sync, wxProcess *process) @@ -552,6 +606,13 @@ long wxExecute(wxChar **argv, // there is no return after successful exec() _exit(-1); + + // some compilers complain about missing return - of course, they + // should know that exit() doesn't return but what else can we do if + // they don't? +#if defined(__VMS) || defined(__INTEL_COMPILER) + return 0; +#endif } else // we're in parent { @@ -560,19 +621,21 @@ long wxExecute(wxChar **argv, // pipe initialization: construction of the wxStreams if ( process && process->IsRedirected() ) { +#if wxUSE_STREAMS // These two streams are relative to this process. wxOutputStream *outStream = new wxProcessFileOutputStream(pipeIn[1]); wxInputStream *inStream = new wxProcessFileInputStream(pipeOut[0]); wxInputStream *errStream = new wxProcessFileInputStream(pipeErr[0]); + process->SetPipeStreams(inStream, outStream, errStream); +#endif // wxUSE_STREAMS + close(pipeIn[0]); // close reading side close(pipeOut[1]); // close writing side close(pipeErr[1]); // close writing side - - process->SetPipeStreams(inStream, outStream, errStream); } -#if wxUSE_GUI +#if wxUSE_GUI && !defined(__WXMICROWIN__) wxEndProcessData *data = new wxEndProcessData; if ( sync ) @@ -625,13 +688,6 @@ long wxExecute(wxChar **argv, return exitcode; #endif // wxUSE_GUI } -#ifdef __VMS - // VMS does not recognise exit as a return and complains about - // a missing return - // I think VMS is wrong in this - // JJ - return 0; -#endif } #undef ERROR_RETURN_CODE @@ -873,6 +929,34 @@ long wxGetFreeMemory() return -1; } +bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) +{ +#ifdef HAVE_STATFS + + struct statfs fs; + if ( statfs(path, &fs) != 0 ) + { + wxLogSysError("Failed to get file system statistics"); + + return FALSE; + } + + if ( pTotal ) + { + *pTotal = wxLongLong(fs.f_blocks) * fs.f_bsize; + } + + if ( pFree ) + { + *pFree = wxLongLong(fs.f_bavail) * fs.f_bsize; + } + + return TRUE; +#endif // HAVE_STATFS + + return FALSE; +} + // ---------------------------------------------------------------------------- // env vars // ----------------------------------------------------------------------------