+// ----------------------------------------------------------------------------
+// wxStream classes to support IO redirection in wxExecute
+// ----------------------------------------------------------------------------
+
+class wxProcessFileInputStream : public wxInputStream
+{
+public:
+ wxProcessFileInputStream(int fd) { m_fd = fd; }
+ ~wxProcessFileInputStream() { close(m_fd); }
+
+ virtual bool Eof() const;
+
+protected:
+ size_t OnSysRead(void *buffer, size_t bufsize);
+
+protected:
+ int m_fd;
+};
+
+class wxProcessFileOutputStream : public wxOutputStream
+{
+public:
+ wxProcessFileOutputStream(int fd) { m_fd = fd; }
+ ~wxProcessFileOutputStream() { close(m_fd); }
+
+protected:
+ size_t OnSysWrite(const void *buffer, size_t bufsize);
+
+protected:
+ int m_fd;
+};
+
+bool wxProcessFileInputStream::Eof() const
+{
+ if ( m_lasterror == wxSTREAM_EOF )
+ return TRUE;
+
+ // check if there is any input available
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(m_fd, &readfds);
+ switch ( select(m_fd + 1, &readfds, NULL, NULL, &tv) )
+ {
+ case -1:
+ wxLogSysError(_("Impossible to get child process input"));
+ // fall through
+
+ case 0:
+ return TRUE;
+
+ default:
+ wxFAIL_MSG(_T("unexpected select() return value"));
+ // still fall through
+
+ case 1:
+ // input available: check if there is any
+ return wxInputStream::Eof();
+ }
+}
+
+size_t wxProcessFileInputStream::OnSysRead(void *buffer, size_t bufsize)
+{
+ int ret = read(m_fd, buffer, bufsize);
+ if ( ret == 0 )
+ {
+ m_lasterror = wxSTREAM_EOF;
+ }
+ else if ( ret == -1 )
+ {
+ m_lasterror = wxSTREAM_READ_ERROR;
+ ret = 0;
+ }
+ else
+ {
+ m_lasterror = wxSTREAM_NOERROR;
+ }
+
+ return ret;
+}
+
+size_t wxProcessFileOutputStream::OnSysWrite(const void *buffer, size_t bufsize)
+{
+ int ret = write(m_fd, buffer, bufsize);
+ if ( ret == -1 )
+ {
+ m_lasterror = wxSTREAM_WRITE_ERROR;
+ ret = 0;
+ }
+ else
+ {
+ m_lasterror = wxSTREAM_NOERROR;
+ }
+
+ return ret;
+}