]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/utilsunx.cpp
Add wxDataViewRendererBase::PrepareForItem() helper.
[wxWidgets.git] / src / unix / utilsunx.cpp
index d7036f000b5dcd08d0d94031cf7ee786bfb2dd25..fa2eb472873f9e724f9ec3e3eccc1461f1b08166 100644 (file)
@@ -255,7 +255,7 @@ int wxKill(long pid, wxSignal sig, wxKillError *rc, int flags)
 
             default:
                 // this goes against Unix98 docs so log it
-                wxLogDebug(_T("unexpected kill(2) return value %d"), err);
+                wxLogDebug(wxT("unexpected kill(2) return value %d"), err);
 
                 // something else...
                 *rc = wxKILL_ERROR;
@@ -274,11 +274,11 @@ bool wxShutdown(int flags)
     switch ( flags )
     {
         case wxSHUTDOWN_POWEROFF:
-            level = _T('0');
+            level = wxT('0');
             break;
 
         case wxSHUTDOWN_REBOOT:
-            level = _T('6');
+            level = wxT('6');
             break;
 
         case wxSHUTDOWN_LOGOFF:
@@ -286,7 +286,7 @@ bool wxShutdown(int flags)
             return false;
 
         default:
-            wxFAIL_MSG( _T("unknown wxShutdown() flag") );
+            wxFAIL_MSG( wxT("unknown wxShutdown() flag") );
             return false;
     }
 
@@ -326,7 +326,7 @@ bool wxPipeInputStream::CanRead() const
             return false;
 
         default:
-            wxFAIL_MSG(_T("unexpected select() return value"));
+            wxFAIL_MSG(wxT("unexpected select() return value"));
             // still fall through
 
         case 1:
@@ -349,12 +349,12 @@ static wxString wxMakeShellCommand(const wxString& command)
     if ( !command )
     {
         // just an interactive shell
-        cmd = _T("xterm");
+        cmd = wxT("xterm");
     }
     else
     {
         // execute command in a shell
-        cmd << _T("/bin/sh -c '") << command << _T('\'');
+        cmd << wxT("/bin/sh -c '") << command << wxT('\'');
     }
 
     return cmd;
@@ -367,7 +367,7 @@ bool wxShell(const wxString& command)
 
 bool wxShell(const wxString& command, wxArrayString& output)
 {
-    wxCHECK_MSG( !command.empty(), false, _T("can't exec shell non interactively") );
+    wxCHECK_MSG( !command.empty(), false, wxT("can't exec shell non interactively") );
 
     return wxExecute(wxMakeShellCommand(command), output);
 }
@@ -394,7 +394,7 @@ public:
     ArgsArray(wchar_t **wargv)
     {
         int argc = 0;
-        while ( *wargv++ )
+        while ( wargv[argc] )
             argc++;
 
         Init(argc);
@@ -429,7 +429,7 @@ private:
     int m_argc;
     char **m_argv;
 
-    DECLARE_NO_COPY_CLASS(ArgsArray)
+    wxDECLARE_NO_COPY_CLASS(ArgsArray);
 };
 
 } // anonymous namespace
@@ -442,27 +442,30 @@ private:
 bool wxMacLaunch(char **argv);
 #endif
 
-long wxExecute(const wxString& command, int flags, wxProcess *process)
+long wxExecute(const wxString& command, int flags, wxProcess *process,
+        const wxExecuteEnv *env)
 {
     ArgsArray argv(wxCmdLineParser::ConvertStringToArgs(command,
                                                         wxCMD_LINE_SPLIT_UNIX));
 
-    return wxExecute(argv, flags, process);
+    return wxExecute(argv, flags, process, env);
 }
 
 #if wxUSE_UNICODE
 
-long wxExecute(wchar_t **wargv, int flags, wxProcess *process)
+long wxExecute(wchar_t **wargv, int flags, wxProcess *process,
+        const wxExecuteEnv *env)
 {
     ArgsArray argv(wargv);
 
-    return wxExecute(argv, flags, process);
+    return wxExecute(argv, flags, process, env);
 }
 
 #endif // wxUSE_UNICODE
 
 // wxExecute: the real worker function
-long wxExecute(char **argv, int flags, wxProcess *process)
+long wxExecute(char **argv, int flags, wxProcess *process,
+        const wxExecuteEnv *env)
 {
     // for the sync execution, we return -1 to indicate failure, but for async
     // case we return 0 which is never a valid PID
@@ -480,7 +483,7 @@ long wxExecute(char **argv, int flags, wxProcess *process)
     // don't know what yet, so for now just warn the user (this is the least we
     // can do) about it
     wxASSERT_MSG( wxThread::IsMain(),
-                    _T("wxExecute() can be called only from the main thread") );
+                    wxT("wxExecute() can be called only from the main thread") );
 #endif // wxUSE_THREADS
 
 #if defined(__WXCOCOA__) || ( defined(__WXOSX_MAC__) && wxOSX_USE_COCOA_OR_CARBON )
@@ -577,6 +580,40 @@ long wxExecute(char **argv, int flags, wxProcess *process)
             pipeErr.Close();
         }
 
+        // Process additional options if we have any
+        if ( env )
+        {
+            // Change working directory if it is specified
+            if ( !env->cwd.empty() )
+                wxSetWorkingDirectory(env->cwd);
+
+            // Change environment if needed.
+            //
+            // NB: We can't use execve() currently because we allow using
+            //     non full paths to wxExecute(), i.e. we want to search for
+            //     the program in PATH. However it just might be simpler/better
+            //     to do the search manually and use execve() envp parameter to
+            //     set up the environment of the child process explicitly
+            //     instead of doing what we do below.
+            if ( !env->env.empty() )
+            {
+                wxEnvVariableHashMap oldenv;
+                wxGetEnvMap(&oldenv);
+
+                // Remove unwanted variables
+                wxEnvVariableHashMap::const_iterator it;
+                for ( it = oldenv.begin(); it != oldenv.end(); ++it )
+                {
+                    if ( env->env.find(it->first) == env->env.end() )
+                        wxUnsetEnv(it->first);
+                }
+
+                // And add the new ones (possibly replacing the old values)
+                for ( it = env->env.begin(); it != env->env.end(); ++it )
+                    wxSetEnv(it->first, it->second);
+            }
+        }
+
         execvp(*argv, argv);
 
         fprintf(stderr, "execvp(");
@@ -601,6 +638,8 @@ long wxExecute(char **argv, int flags, wxProcess *process)
     {
         // save it for WaitForChild() use
         execData.pid = pid;
+        if (execData.process)
+            execData.process->SetPid(pid);  // and also in the wxProcess
 
         // prepare for IO redirection
 
@@ -720,7 +759,7 @@ static wxString wxGetCommandOutput(const wxString &cmd)
     FILE *f = popen(cmd.ToAscii(), "r");
     if ( !f )
     {
-        wxLogSysError(_T("Executing \"%s\" failed"), cmd.c_str());
+        wxLogSysError(wxT("Executing \"%s\" failed"), cmd.c_str());
         return wxEmptyString;
     }
 
@@ -736,7 +775,7 @@ static wxString wxGetCommandOutput(const wxString &cmd)
 
     pclose(f);
 
-    if ( !s.empty() && s.Last() == _T('\n') )
+    if ( !s.empty() && s.Last() == wxT('\n') )
         s.RemoveLast();
 
     return s;
@@ -871,6 +910,25 @@ bool wxIsPlatform64Bit()
                 machine.Contains(wxT("alpha"));
 }
 
+#ifdef __LINUX__
+wxLinuxDistributionInfo wxGetLinuxDistributionInfo()
+{
+    const wxString id = wxGetCommandOutput(wxT("lsb_release --id"));
+    const wxString desc = wxGetCommandOutput(wxT("lsb_release --description"));
+    const wxString rel = wxGetCommandOutput(wxT("lsb_release --release"));
+    const wxString codename = wxGetCommandOutput(wxT("lsb_release --codename"));
+
+    wxLinuxDistributionInfo ret;
+
+    id.StartsWith("Distributor ID:\t", &ret.Id);
+    desc.StartsWith("Description:\t", &ret.Description);
+    rel.StartsWith("Release:\t", &ret.Release);
+    codename.StartsWith("Codename:\t", &ret.CodeName);
+
+    return ret;
+}
+#endif
+
 // these functions are in src/osx/utilsexc_base.cpp for wxMac
 #ifndef __WXMAC__
 
@@ -1074,7 +1132,7 @@ static bool wxDoSetEnv(const wxString& variable, const char *value)
 #elif defined(HAVE_PUTENV)
     wxString s = variable;
     if ( value )
-        s << _T('=') << value;
+        s << wxT('=') << value;
 
     // transform to ANSI
     const wxWX2MBbuf p = s.mb_str();
@@ -1157,7 +1215,7 @@ bool wxHandleFatalExceptions(bool doit)
         ok &= sigaction(SIGSEGV, &act, &s_handlerSEGV) == 0;
         if ( !ok )
         {
-            wxLogDebug(_T("Failed to install our signal handler."));
+            wxLogDebug(wxT("Failed to install our signal handler."));
         }
 
         s_savedHandlers = true;
@@ -1171,7 +1229,7 @@ bool wxHandleFatalExceptions(bool doit)
         ok &= sigaction(SIGSEGV, &s_handlerSEGV, NULL) == 0;
         if ( !ok )
         {
-            wxLogDebug(_T("Failed to uninstall our signal handler."));
+            wxLogDebug(wxT("Failed to uninstall our signal handler."));
         }
 
         s_savedHandlers = false;
@@ -1263,7 +1321,7 @@ public:
 protected:
     const int m_fd;
 
-    DECLARE_NO_COPY_CLASS(wxReadFDIOHandler)
+    wxDECLARE_NO_COPY_CLASS(wxReadFDIOHandler);
 };
 
 // class for monitoring our end of the process detection pipe, simply sets a
@@ -1284,7 +1342,7 @@ public:
 private:
     bool m_terminated;
 
-    DECLARE_NO_COPY_CLASS(wxEndHandler)
+    wxDECLARE_NO_COPY_CLASS(wxEndHandler);
 };
 
 #if HAS_PIPE_INPUT_STREAM
@@ -1313,7 +1371,7 @@ public:
 private:
     wxStreamTempInputBuffer * const m_buf;
 
-    DECLARE_NO_COPY_CLASS(wxRedirectedIOHandler)
+    wxDECLARE_NO_COPY_CLASS(wxRedirectedIOHandler);
 };
 
 #endif // HAS_PIPE_INPUT_STREAM
@@ -1352,15 +1410,21 @@ int DoWaitForChild(int pid, int flags = 0)
     {
         wxASSERT_MSG( rc == pid, "unexpected waitpid() return value" );
 
+        // notice that the caller expects the exit code to be signed, e.g. -1
+        // instead of 255 so don't assign WEXITSTATUS() to an int
+        signed char exitcode;
         if ( WIFEXITED(status) )
-            return WEXITSTATUS(status);
+            exitcode = WEXITSTATUS(status);
         else if ( WIFSIGNALED(status) )
-            return -WTERMSIG(status);
+            exitcode = -WTERMSIG(status);
         else
         {
             wxLogError("Child process (PID %d) exited for unknown reason, "
                        "status = %d", pid, status);
+            exitcode = -1;
         }
+
+        return exitcode;
     }
 
     return -1;
@@ -1391,7 +1455,7 @@ int wxAppTraits::WaitForChild(wxExecuteData& execData)
     }
     //else: synchronous execution case
 
-#if HAS_PIPE_INPUT_STREAM
+#if HAS_PIPE_INPUT_STREAM && wxUSE_SOCKETS
     wxProcess * const process = execData.process;
     if ( process && process->IsRedirected() )
     {