]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/utilsunx.cpp
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / unix / utilsunx.cpp
index 784cf1031f42856bfe3c49b7e61bd7b582cb2e8c..7f275de250f23a9426564c9262d4723475fd1f64 100644 (file)
@@ -695,7 +695,7 @@ long wxExecute(wxChar **argv, int flags, wxProcess *process)
 
 const wxChar* wxGetHomeDir( wxString *home  )
 {
 
 const wxChar* wxGetHomeDir( wxString *home  )
 {
-    *home = wxGetUserHome( wxEmptyString );
+    *home = wxGetUserHome();
     wxString tmp;
     if ( home->empty() )
         *home = wxT("/");
     wxString tmp;
     if ( home->empty() )
         *home = wxT("/");
@@ -707,11 +707,7 @@ const wxChar* wxGetHomeDir( wxString *home  )
     return home->c_str();
 }
 
     return home->c_str();
 }
 
-#if wxUSE_UNICODE
-const wxMB2WXbuf wxGetUserHome( const wxString &user )
-#else // just for binary compatibility -- there is no 'const' here
-char *wxGetUserHome( const wxString &user )
-#endif
+wxString wxGetUserHome( const wxString &user )
 {
     struct passwd *who = (struct passwd *) NULL;
 
 {
     struct passwd *who = (struct passwd *) NULL;
 
@@ -721,20 +717,17 @@ char *wxGetUserHome( const wxString &user )
 
         if ((ptr = wxGetenv(wxT("HOME"))) != NULL)
         {
 
         if ((ptr = wxGetenv(wxT("HOME"))) != NULL)
         {
-#if wxUSE_UNICODE
-            wxWCharBuffer buffer( ptr );
-            return buffer;
-#else
             return ptr;
             return ptr;
-#endif
         }
         }
-        if ((ptr = wxGetenv(wxT("USER"))) != NULL || (ptr = wxGetenv(wxT("LOGNAME"))) != NULL)
+
+        if ((ptr = wxGetenv(wxT("USER"))) != NULL ||
+             (ptr = wxGetenv(wxT("LOGNAME"))) != NULL)
         {
             who = getpwnam(wxSafeConvertWX2MB(ptr));
         }
 
         {
             who = getpwnam(wxSafeConvertWX2MB(ptr));
         }
 
-        // We now make sure the the user exists!
-        if (who == NULL)
+        // make sure the user exists!
+        if ( !who )
         {
             who = getpwuid(getuid());
         }
         {
             who = getpwuid(getuid());
         }
@@ -1098,6 +1091,18 @@ bool wxGetEnv(const wxString& var, wxString *value)
 static bool wxDoSetEnv(const wxString& variable, const char *value)
 {
 #if defined(HAVE_SETENV)
 static bool wxDoSetEnv(const wxString& variable, const char *value)
 {
 #if defined(HAVE_SETENV)
+    if ( !value )
+    {
+#ifdef HAVE_UNSETENV
+        // don't test unsetenv() return value: it's void on some systems (at
+        // least Darwin)
+        unsetenv(variable.mb_str());
+        return true;
+#else
+        value = ""; // we can't pass NULL to setenv()
+#endif
+    }
+
     return setenv(variable.mb_str(), value, 1 /* overwrite */) == 0;
 #elif defined(HAVE_PUTENV)
     wxString s = variable;
     return setenv(variable.mb_str(), value, 1 /* overwrite */) == 0;
 #elif defined(HAVE_PUTENV)
     wxString s = variable;
@@ -1215,13 +1220,27 @@ bool wxHandleFatalExceptions(bool doit)
 
 #if wxUSE_GUI
 
 
 #if wxUSE_GUI
 
+#ifdef __DARWIN__
+    #include <sys/errno.h>
+#endif
 // ----------------------------------------------------------------------------
 // wxExecute support
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 // 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__))
+/*
+    NOTE: If this proves not to work well for wxMac then move back to the old
+    behavior.  If, however, it proves to work just fine, nuke all of the code
+    for the old behavior.  I strongly suggest backporting this to 2.8 as well.
+    However, beware that while you can nuke the old code here, you cannot
+    nuke the wxAddProcessCallbackForPid from the 2.8 branch (found in
+    utilsexc_cf since it's an exported symbol).
+ */
+// #define USE_OLD_DARWIN_END_PROCESS_DETECT (defined(__DARWIN__) && defined(__WXMAC__))
+#define USE_OLD_DARWIN_END_PROCESS_DETECT 0
+
+// wxMac/wxCocoa don't use the same process end detection mechanisms so we don't
+// need wxExecute-related helpers for them
+#if !USE_OLD_DARWIN_END_PROCESS_DETECT
 
 bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData)
 {
 
 bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData)
 {
@@ -1291,7 +1310,7 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
 
     if ( !(flags & wxEXEC_NOEVENTS) )
     {
 
     if ( !(flags & wxEXEC_NOEVENTS) )
     {
-#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
+#if USE_OLD_DARWIN_END_PROCESS_DETECT
         endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
 #else
         endProcData->tag = wxAddProcessCallback
         endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
 #else
         endProcData->tag = wxAddProcessCallback
@@ -1301,7 +1320,7 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
                            );
 
         execData.pipeEndProcDetect.Close();
                            );
 
         execData.pipeEndProcDetect.Close();
-#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
+#endif // USE_OLD_DARWIN_END_PROCESS_DETECT
     }
 
     if ( flags & wxEXEC_SYNC )
     }
 
     if ( flags & wxEXEC_SYNC )
@@ -1319,6 +1338,35 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
             int status = 0;
 
             int result = waitpid(execData.pid, &status, 0);
             int status = 0;
 
             int result = waitpid(execData.pid, &status, 0);
+#ifdef __DARWIN__
+            /*  DE: waitpid manpage states that waitpid can fail with EINTR
+                if the call is interrupted by a caught signal.  I suppose
+                that means that this ought to be a while loop.
+
+                The odd thing is that it seems to fail EVERY time.  It fails
+                with a quickly exiting process (e.g. echo), and fails with a
+                slowly exiting process (e.g. sleep 2) but clearly after
+                having waited for the child to exit. Maybe it's a bug in
+                my particular version.
+
+                It works, however, from the CFSocket callback without this
+                trick but in that case it's used only after CFSocket calls
+                the callback and with the WNOHANG flag which would seem to
+                preclude it from being interrupted or at least make it much
+                less likely since it would not then be waiting.
+
+                If Darwin's man page is to be believed then this is definitely
+                necessary.  It's just weird that I've never seen it before
+                and apparently no one else has either or you'd think they'd
+                have reported it by now.  Perhaps blocking the GUI while
+                waiting for a child process to exit is simply not that common.
+             */
+            if(result == -1 && errno == EINTR)
+            {
+                result = waitpid(execData.pid, &status, 0);
+            }
+
+#endif
 
             if ( result == -1 )
             {
 
             if ( result == -1 )
             {