+// ----------------------------------------------------------------------------
+// wxStreamTempInputBuffer
+// ----------------------------------------------------------------------------
+
+/*
+ Extract of a mail to wx-users to give the context of the problem we are
+ trying to solve here:
+
+ MC> If I run the command:
+ MC> find . -name "*.h" -exec grep linux {} \;
+ MC> in the exec sample synchronously from the 'Capture command output'
+ MC> menu, wxExecute never returns. I have to xkill it. Has anyone
+ MC> else encountered this?
+
+ Yes, I can reproduce it too.
+
+ I even think I understand why it happens: before launching the external
+ command we set up a pipe with a valid file descriptor on the reading side
+ when the output is redirected. So the subprocess happily writes to it ...
+ until the pipe buffer (which is usually quite big on Unix, I think the
+ default is 4Kb) is full. Then the writing process stops and waits until we
+ read some data from the pipe to be able to continue writing to it but we
+ never do it because we wait until it terminates to start reading and so we
+ have a classical deadlock.
+
+ Here is the fix: we now read the output as soon as it appears into a temp
+ buffer (wxStreamTempInputBuffer object) and later just stuff it back into the
+ stream when the process terminates. See supporting code in wxExecute()
+ itself as well.
+
+ Note that this is horribly inefficient for large amounts of output (count
+ the number of times we copy the data around) and so a better API is badly
+ needed!
+*/
+
+class wxStreamTempInputBuffer
+{
+public:
+ wxStreamTempInputBuffer();
+
+ // call to associate a stream with this buffer, otherwise nothing happens
+ // at all
+ void Init(wxProcessFileInputStream *stream);
+
+ // check for input on our stream and cache it in our buffer if any
+ void Update();
+
+ ~wxStreamTempInputBuffer();
+
+private:
+ // the stream we're buffering, if NULL we don't do anything at all
+ wxProcessFileInputStream *m_stream;
+
+ // the buffer of size m_size (NULL if m_size == 0)
+ void *m_buffer;
+
+ // the size of the buffer
+ size_t m_size;
+};
+
+wxStreamTempInputBuffer::wxStreamTempInputBuffer()
+{
+ m_stream = NULL;
+ m_buffer = NULL;
+ m_size = 0;
+}
+
+void wxStreamTempInputBuffer::Init(wxProcessFileInputStream *stream)