From f1cdb1625a54780a644ab68e79dd3dab50cfa6b4 Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 30 Sep 2018 09:13:16 +0000 Subject: [PATCH] Core: LocalProcess now allows setting current directory for started process git-svn-id: svn://ultimatepp.org/upp/trunk@12319 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/LocalProcess.cpp | 12 ++++--- uppsrc/Core/LocalProcess.h | 10 +++--- uppsrc/Core/Win32Util.h | 2 +- uppsrc/Core/src.tpp/AProcess_en-us.tpp | 44 +++++++++++++++----------- uppsrc/ide/Core/Host.cpp | 2 +- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/uppsrc/Core/LocalProcess.cpp b/uppsrc/Core/LocalProcess.cpp index 646ba7c42..c55c3c800 100644 --- a/uppsrc/Core/LocalProcess.cpp +++ b/uppsrc/Core/LocalProcess.cpp @@ -66,10 +66,11 @@ static void sNoBlock(int fd) #endif #ifdef PLATFORM_WIN32 -bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi) +bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi, const char *cd) { // provides conversion of charset for cmdline and envptr WString wcmd(command); int n = wcmd.GetCount() + 1; + WString wcd(cd); Buffer cmd(n); memcpy(cmd, wcmd, n * sizeof(wchar)); #if 0 // unicode environment not necessary for now @@ -84,11 +85,11 @@ bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& s memcpy(env, wenv, (len + 2) * sizeof(wchar)); } #endif - return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr, NULL, &si, &pi); + return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr, wcd, &si, &pi); } #endif -bool LocalProcess::DoStart(const char *command, const Vector *arg, bool spliterr, const char *envptr) +bool LocalProcess::DoStart(const char *command, const Vector *arg, bool spliterr, const char *envptr, const char *cd) { LLOG("LocalProcess::Start(\"" << command << "\")"); @@ -173,7 +174,7 @@ bool LocalProcess::DoStart(const char *command, const Vector *arg, bool } command = cmdh; } - bool h = Win32CreateProcess(command, envptr, si, pi); + bool h = Win32CreateProcess(command, envptr, si, pi, cd); LLOG("CreateProcess " << (h ? "succeeded" : "failed")); CloseHandle(hErrorWrite); CloseHandle(hInputRead); @@ -338,6 +339,9 @@ bool LocalProcess::DoStart(const char *command, const Vector *arg, bool LLOG("[" << a << "]: <" << (args[a] ? args[a] : "NULL") << ">"); #endif//DO_LLOG + if(cd) + chdir(cd); + LLOG("running execve, app = " << app << ", #args = " << args.GetCount()); if(envptr) { const char *from = envptr; diff --git a/uppsrc/Core/LocalProcess.h b/uppsrc/Core/LocalProcess.h index 2e6299ff0..b000da837 100644 --- a/uppsrc/Core/LocalProcess.h +++ b/uppsrc/Core/LocalProcess.h @@ -58,14 +58,14 @@ private: typedef LocalProcess CLASSNAME; - bool DoStart(const char *cmdline, const Vector *arg, bool spliterr, const char *envptr = NULL); + bool DoStart(const char *cmdline, const Vector *arg, bool spliterr, const char *envptr, const char *cd); public: - bool Start(const char *cmdline, const char *envptr = NULL) { return DoStart(cmdline, NULL, false, envptr); } - bool Start2(const char *cmdline, const char *envptr = NULL) { return DoStart(cmdline, NULL, true, envptr); } + bool Start(const char *cmdline, const char *envptr = NULL, const char *cd = NULL) { return DoStart(cmdline, NULL, false, envptr, cd); } + bool Start2(const char *cmdline, const char *envptr = NULL, const char *cd = NULL) { return DoStart(cmdline, NULL, true, envptr, cd); } - bool Start(const char *cmd, const Vector& arg, const char *envptr = NULL) { return DoStart(cmd, &arg, false, envptr); } - bool Start2(const char *cmd, const Vector& arg, const char *envptr = NULL) { return DoStart(cmd, &arg, true, envptr); } + bool Start(const char *cmd, const Vector& arg, const char *envptr = NULL, const char *cd = NULL) { return DoStart(cmd, &arg, false, envptr, cd); } + bool Start2(const char *cmd, const Vector& arg, const char *envptr = NULL, const char *cd = NULL) { return DoStart(cmd, &arg, true, envptr, cd); } #ifdef PLATFORM_POSIX LocalProcess& DoubleFork(bool b = true) { doublefork = b; return *this; } diff --git a/uppsrc/Core/Win32Util.h b/uppsrc/Core/Win32Util.h index 964e52708..26a6b52b4 100644 --- a/uppsrc/Core/Win32Util.h +++ b/uppsrc/Core/Win32Util.h @@ -38,7 +38,7 @@ void DllFn(T& x, const char *dll, const char *fn) x = (T)GetDllFn(dll, fn); } -bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi); +bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi, const char *cd); #ifndef PLATFORM_WINCE String GetSystemDirectory(); diff --git a/uppsrc/Core/src.tpp/AProcess_en-us.tpp b/uppsrc/Core/src.tpp/AProcess_en-us.tpp index 7a2f77f6f..10b6401d0 100644 --- a/uppsrc/Core/src.tpp/AProcess_en-us.tpp +++ b/uppsrc/Core/src.tpp/AProcess_en-us.tpp @@ -1,5 +1,4 @@ topic "AProcess and LocalProcess"; -[2 $$0,0#00000000000000000000000000000000:Default] [i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] [l288;2 $$2,0#27521748481378242620020725143825:desc] [0 $$3,0#96390100711032703541132217272105:end] @@ -9,6 +8,7 @@ topic "AProcess and LocalProcess"; [l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] [i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] [b42;2 $$9,9#13035079074754324216151401829390:normal] +[2 $$0,0#00000000000000000000000000000000:Default] [{_} [ {{10000@(113.42.0) [s0;%% [*@7;4 AProcess]]}}&] [s3; &] @@ -100,40 +100,45 @@ output of process. If anything went wrong, returns String`::GetVoid().&] [s0; &] [ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&] [s3;%% &] -[s5;:LocalProcess`:`:Start`(const char`*`,const char`*`): [@(0.0.255) bool]_[* Start]([@(0.0.255) c -onst]_[@(0.0.255) char]_`*[*@3 cmdline], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr -]_`=_NULL)&] +[s5;:Upp`:`:LocalProcess`:`:Start`(const char`*`,const char`*`,const char`*`): [@(0.0.255) b +ool]_[* Start]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmdline], +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr]_`=_NULL, [@(0.0.255) const]_[@(0.0.255) c +har]_`*[*@3 cd]_`=_NULL)&] [s2;%% Starts a new process defined by [%-*@3 cmdline], [%-*@3 envptr ]can provide a new environment for the process, if NULL, then -the new process inherits caller`'s environment.&] +the new process inherits caller`'s environment. [%-*@3 cd] can +be used to specify the new current directory for the process.&] [s3;%% &] [s4; &] -[s5;:LocalProcess`:`:Start2`(const char`*`,const char`*`): [@(0.0.255) bool]_[* Start2]([@(0.0.255) c -onst]_[@(0.0.255) char]_`*[*@3 cmdline], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr -]_`=_NULL)&] +[s5;:Upp`:`:LocalProcess`:`:Start2`(const char`*`,const char`*`,const char`*`): [@(0.0.255) b +ool]_[* Start2]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmdline], +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr]_`=_NULL, [@(0.0.255) const]_[@(0.0.255) c +har]_`*[*@3 cd]_`=_NULL)&] [s2;%% Starts a new process defined by [%-*@3 cmdline], [%-*@3 envptr ]can provide a new environment for the process, if NULL, then the new process inherits caller`'s environment. This variant activates mode when standard output and standard error output -are read separately using Read2 method.&] +are read separately using Read2 method. [%-*@3 cd] can be used +to specify the new current directory for the process.&] [s3;%% &] [s4; &] -[s5;:LocalProcess`:`:Start`(const char`*`,const Vector``&`,const char`*`): [@(0.0.255) b -ool]_[* Start]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmd], [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/Vector`$en`-us`#Vector`:`:class^ V -ector]<[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ String]>`&_[*@3 arg], - [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr]_`=_NULL)&] +[s5;:Upp`:`:LocalProcess`:`:Start`(const char`*`,const Upp`:`:Vector``&`,const char`*`,const char`*`): [@(0.0.255) b +ool]_[* Start]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmd], [@(0.0.255) const]_[_^Upp`:`:Vector^ V +ector]<[_^Upp`:`:String^ String]>`&_[*@3 arg], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 e +nvptr]_`=_NULL, [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cd]_`=_NULL)&] [s2;%% Starts a new process defined by [%-*@3 cmd], [%-*@3 arg].[%-*@3 envptr ]can provide a new environment for the process, if NULL, then the new process inherits caller`'s environment. This variant passes individual arguments instead of whole commandline, this has advantage that arguments are in POSIX passed directly to -execv, without parsing the commandline.&] +execv, without parsing the commandline. [%-*@3 cd] can be used +to specify the new current directory for the process.&] [s3;%% &] [s4; &] -[s5;:LocalProcess`:`:Start2`(const char`*`,const Vector``&`,const char`*`): [@(0.0.255) b -ool]_[* Start2]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmd], [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/Vector`$en`-us`#Vector`:`:class^ V -ector]<[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ String]>`&_[*@3 arg], - [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 envptr]_`=_NULL)&] +[s5;:Upp`:`:LocalProcess`:`:Start2`(const char`*`,const Upp`:`:Vector``&`,const char`*`,const char`*`): [@(0.0.255) b +ool]_[* Start2]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cmd], [@(0.0.255) const]_[_^Upp`:`:Vector^ V +ector]<[_^Upp`:`:String^ String]>`&_[*@3 arg], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 e +nvptr]_`=_NULL, [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 cd]_`=_NULL)&] [s2;%% Starts a new process defined by [%-*@3 cmd], [%-*@3 arg].[%-*@3 envptr ]can provide a new environment for the process, if NULL, then the new process inherits caller`'s environment. This variant @@ -141,7 +146,8 @@ activates mode when standard output and standard error output are read separately using Read2 method. This variant passes individual arguments instead of whole commandline, this has advantage that arguments are in POSIX passed directly to execv, without parsing -the commandline.&] +the commandline. [%-*@3 cd] can be used to specify the new current +directory for the process.&] [s3; &] [s4; &] [s5;:Upp`:`:LocalProcess`:`:Finish`(Upp`:`:String`&`): [@(0.0.255) int]_[* Finish]([_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S diff --git a/uppsrc/ide/Core/Host.cpp b/uppsrc/ide/Core/Host.cpp index ab3dcd819..1e2bdced1 100644 --- a/uppsrc/ide/Core/Host.cpp +++ b/uppsrc/ide/Core/Host.cpp @@ -208,7 +208,7 @@ void LocalHost::Launch(const char *_cmdline, bool console) STARTUPINFOW si; ZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); - if(Win32CreateProcess(cmdline, ~environment, si, pi)) { + if(Win32CreateProcess(cmdline, ~environment, si, pi, NULL)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }