]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/utilsunx.cpp
Fixed wxMessageBox with only an OK button returning wxCANCEL under MSW.
[wxWidgets.git] / src / unix / utilsunx.cpp
index a96e20e6392b391d2199c3b555b0ba83104f215e..ec550fcf244c9a990bec2e530683fd7418e9533a 100644 (file)
@@ -598,12 +598,6 @@ long wxExecute(char **argv, int flags, wxProcess *process,
         }
 #endif // !__VMS
 
-        // reading side can be safely closed but we should keep the write one
-        // opened, it will be only closed when the process terminates resulting
-        // in a read notification to the parent
-        execData.pipeEndProcDetect.Detach(wxPipe::Write);
-        execData.pipeEndProcDetect.Close();
-
         // redirect stdin, stdout and stderr
         if ( pipeIn.IsOk() )
         {
@@ -619,6 +613,39 @@ long wxExecute(char **argv, int flags, wxProcess *process,
             pipeErr.Close();
         }
 
+        // Close all (presumably accidentally) inherited file descriptors to
+        // avoid descriptor leaks. This means that we don't allow inheriting
+        // them purposefully but this seems like a lesser evil in wx code.
+        // Ideally we'd provide some flag to indicate that none (or some?) of
+        // the descriptors do not need to be closed but for now this is better
+        // than never closing them at all as wx code never used FD_CLOEXEC.
+
+        // Note that while the reading side of the end process detection pipe
+        // can be safely closed, we should keep the write one opened, it will
+        // be only closed when the process terminates resulting in a read
+        // notification to the parent
+        const int fdEndProc = execData.pipeEndProcDetect.Detach(wxPipe::Write);
+        execData.pipeEndProcDetect.Close();
+
+        // TODO: Iterating up to FD_SETSIZE is both inefficient (because it may
+        //       be quite big) and incorrect (because in principle we could
+        //       have more opened descriptions than this number). Unfortunately
+        //       there is no good portable solution for closing all descriptors
+        //       above a certain threshold but non-portable solutions exist for
+        //       most platforms, see [http://stackoverflow.com/questions/899038/
+        //          getting-the-highest-allocated-file-descriptor]
+        for ( int fd = 0; fd < (int)FD_SETSIZE; ++fd )
+        {
+            if ( fd != STDIN_FILENO  &&
+                 fd != STDOUT_FILENO &&
+                 fd != STDERR_FILENO &&
+                 fd != fdEndProc )
+            {
+                close(fd);
+            }
+        }
+
+
         // Process additional options if we have any
         if ( env )
         {
@@ -701,7 +728,9 @@ long wxExecute(char **argv, int flags, wxProcess *process,
                 // it might not be the best idea.
                 wxLogSysError(_("Failed to set up non-blocking pipe, "
                                 "the program might hang."));
+#if wxUSE_LOG
                 wxLog::FlushActive();
+#endif
             }
 
             wxOutputStream *inStream =