+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;
+}
+
+long wxExecute(wxChar **argv,
+ bool sync,
+ wxProcess *process)
+{
+ wxCHECK_MSG( *argv, 0, wxT("can't exec empty command") );
+
+#if wxUSE_UNICODE
+ int mb_argc = 0;
+ char *mb_argv[WXEXECUTE_NARGS];
+
+ while (argv[mb_argc])
+ {
+ wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]);
+ mb_argv[mb_argc] = strdup(mb_arg);
+ mb_argc++;
+ }
+ mb_argv[mb_argc] = (char *) NULL;
+
+ // this macro will free memory we used above
+ #define ARGS_CLEANUP \
+ for ( mb_argc = 0; mb_argv[mb_argc]; mb_argc++ ) \
+ free(mb_argv[mb_argc])
+#else // ANSI
+ // no need for cleanup
+ #define ARGS_CLEANUP
+
+ wxChar **mb_argv = argv;
+#endif // Unicode/ANSI
+
+#if wxUSE_GUI