From 4ae6c41e560df93e52229f872d4a6c1a0f073293 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 19 Jan 2015 15:45:17 +0000 Subject: [PATCH] Core: Fixed LocalProcess #958 git-svn-id: svn://ultimatepp.org/upp/trunk@8065 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Core.upp | 3 +- uppsrc/Core/LocalProcess.cpp | 92 ++++++++++++++++---------- uppsrc/Core/LocalProcess.h | 1 + uppsrc/CtrlCore/src.tpp/Ctrl$en-us.tpp | 2 +- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index e75717bba..b5c6633c4 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -32,8 +32,7 @@ link(SOLARIS) "-Wl,-R -Wl,/usr/local/lib"; link(GCC POSIX STACKTRACE) -rdynamic; file - Core.h - options() PCH, + Core.h options PCH, config.h, Defs.h, Cpu.cpp optimize_speed, diff --git a/uppsrc/Core/LocalProcess.cpp b/uppsrc/Core/LocalProcess.cpp index 83f2810bf..ccefb9fbb 100644 --- a/uppsrc/Core/LocalProcess.cpp +++ b/uppsrc/Core/LocalProcess.cpp @@ -13,7 +13,7 @@ NAMESPACE_UPP void LocalProcess::Init() { #ifdef PLATFORM_WIN32 - hProcess = hOutputRead = hInputWrite = NULL; + hProcess = hOutputRead = hErrorRead = hInputWrite = NULL; #endif #ifdef PLATFORM_POSIX pid = 0; @@ -33,6 +33,10 @@ void LocalProcess::Free() { CloseHandle(hOutputRead); hOutputRead = NULL; } + if(hErrorRead) { + CloseHandle(hErrorRead); + hErrorRead = NULL; + } if(hInputWrite) { CloseHandle(hInputWrite); hInputWrite = NULL; @@ -53,10 +57,12 @@ void LocalProcess::Free() { #endif } +#ifdef PLATFORM_POSIX static void sNoBlock(int fd) { fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); } +#endif bool LocalProcess::DoStart(const char *command, bool spliterr, const char *envptr) { @@ -68,9 +74,9 @@ bool LocalProcess::DoStart(const char *command, bool spliterr, const char *envpt command++; #ifdef PLATFORM_WIN32 - HANDLE hOutputReadTmp, hInputRead; - HANDLE hInputWriteTmp, hOutputWrite; - HANDLE hErrorWrite; + HANDLE hOutputReadTmp, hOutputWrite; + HANDLE hInputWriteTmp, hInputRead; + HANDLE hErrorReadTmp, hErrorWrite; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -79,15 +85,21 @@ bool LocalProcess::DoStart(const char *command, bool spliterr, const char *envpt HANDLE hp = GetCurrentProcess(); - ASSERT(!spliterr); //spliterr NOT IMPLEMENTED (yet) + CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0); + DuplicateHandle(hp, hInputWriteTmp, hp, &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS); + CloseHandle(hInputWriteTmp); CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0); - DuplicateHandle(hp, hOutputWrite, hp, &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS); - CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0); DuplicateHandle(hp, hOutputReadTmp, hp, &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS); - DuplicateHandle(hp, hInputWriteTmp, hp, &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hOutputReadTmp); - CloseHandle(hInputWriteTmp); + + if(spliterr) { + CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0); + DuplicateHandle(hp, hErrorReadTmp, hp, &hErrorRead, 0, FALSE, DUPLICATE_SAME_ACCESS); + CloseHandle(hErrorReadTmp); + } + else + DuplicateHandle(hp, hOutputWrite, hp, &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS); PROCESS_INFORMATION pi; STARTUPINFO si; @@ -364,35 +376,41 @@ String LocalProcess::GetExitMessage() { } bool LocalProcess::Read(String& res) { -#ifdef PLATFORM_POSIX - return Read2(res, res); -#endif -#ifdef PLATFORM_WIN32 - LLOG("LocalProcess::Read"); - res = wreso; - if(!hOutputRead) return false; - dword n; - if(!PeekNamedPipe(hOutputRead, NULL, 0, NULL, &n, NULL) || n == 0) - return IsRunning(); - char buffer[1024]; - if(!ReadFile(hOutputRead, buffer, sizeof(buffer), &n, NULL)) - return false; - res = String(buffer, n); - if(convertcharset) - res = FromOEMCharset(res); - return true; -#endif + String dummy; + return Read2(res, dummy); } bool LocalProcess::Read2(String& reso, String& rese) { LLOG("LocalProcess::Read2"); - String res[2] = {Null, Null}; + reso = wreso; + rese = wrese; + wreso.Clear(); + wrese.Clear(); + #ifdef PLATFORM_WIN32 - NEVER(); //Not implemented - return false; + LLOG("LocalProcess::Read"); + bool was_running = IsRunning(); + char buffer[1024]; + dword n; + if(hOutputRead && PeekNamedPipe(hOutputRead, NULL, 0, NULL, &n, NULL) && n) + while(ReadFile(hOutputRead, buffer, sizeof(buffer), &n, NULL) && n) + wreso.Cat(buffer, n); + + if(hErrorRead && PeekNamedPipe(hErrorRead, NULL, 0, NULL, &n, NULL) && n) + while(ReadFile(hErrorRead, buffer, sizeof(buffer), &n, NULL) && n) + wrese.Cat(buffer, n); + + if(convertcharset) { + reso = FromOEMCharset(reso); + rese = FromOEMCharset(rese); + } + + return reso.GetCount() || rese.GetCount() || was_running; + #endif #ifdef PLATFORM_POSIX + String res[2]; bool was_running = IsRunning() || wpipe[0] >= 0 || epipe[0] >= 0; for (int wp=0; wp<2;wp++) { int *pipe = wp ? epipe : wpipe; @@ -422,8 +440,6 @@ bool LocalProcess::Read2(String& reso, String& rese) LLOG("select -> " << sv); } } - reso = wreso; - rese = wrese; if(convertcharset) { reso << FromSystemCharset(res[0]); rese << FromSystemCharset(res[1]); @@ -440,11 +456,17 @@ void LocalProcess::Write(String s) if(convertcharset) s = ToSystemCharset(s); #ifdef PLATFORM_WIN32 - dword n; if (hInputWrite) { bool ret = true; - for(int wn = 0; (ret > 0 || errno == EINTR) && wn < s.GetLength(); wn += n) { - ret = WriteFile(hInputWrite, s, s.GetLength(), &n, NULL); + dword n; + for(int wn = 0; ret && wn < s.GetLength(); wn += n) { + ret = WriteFile(hInputWrite, ~s + wn, s.GetLength(), &n, NULL); + String ho = wreso; + String he = wrese; + wreso = wrese = Null; + Read2(wreso, wrese); + wreso = ho + wreso; + wrese = ho + wrese; } } #endif diff --git a/uppsrc/Core/LocalProcess.h b/uppsrc/Core/LocalProcess.h index b557557dc..0ee62130a 100644 --- a/uppsrc/Core/LocalProcess.h +++ b/uppsrc/Core/LocalProcess.h @@ -43,6 +43,7 @@ private: #ifdef PLATFORM_WIN32 HANDLE hProcess; HANDLE hOutputRead; + HANDLE hErrorRead; HANDLE hInputWrite; #endif #ifdef PLATFORM_POSIX diff --git a/uppsrc/CtrlCore/src.tpp/Ctrl$en-us.tpp b/uppsrc/CtrlCore/src.tpp/Ctrl$en-us.tpp index 59859b664..a5c2f48cd 100644 --- a/uppsrc/CtrlCore/src.tpp/Ctrl$en-us.tpp +++ b/uppsrc/CtrlCore/src.tpp/Ctrl$en-us.tpp @@ -584,7 +584,7 @@ occurs at the border area of view.&] [s5;:Ctrl`:`:GetDropData`(const String`&`)const:%- [@(0.0.255) virtual] [_^String^ String]_[* GetDropData]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 f mt])_[@(0.0.255) const]&] -[s2; This method is invoked to obtain drop data from Ctrl is such +[s2; This method is invoked to obtain drop data from Ctrl if such data was not supplied as ClipData in call to DoDragAndDrop. Default implementation calls GetSelectionData.&] [s3; &]