Core: LocalProcess now allows setting current directory for started process

git-svn-id: svn://ultimatepp.org/upp/trunk@12319 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-09-30 09:13:16 +00:00
parent a94c44df8d
commit f1cdb1625a
5 changed files with 40 additions and 30 deletions

View file

@ -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<wchar> 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<String> *arg, bool spliterr, const char *envptr)
bool LocalProcess::DoStart(const char *command, const Vector<String> *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<String> *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<String> *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;

View file

@ -58,14 +58,14 @@ private:
typedef LocalProcess CLASSNAME;
bool DoStart(const char *cmdline, const Vector<String> *arg, bool spliterr, const char *envptr = NULL);
bool DoStart(const char *cmdline, const Vector<String> *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<String>& arg, const char *envptr = NULL) { return DoStart(cmd, &arg, false, envptr); }
bool Start2(const char *cmd, const Vector<String>& arg, const char *envptr = NULL) { return DoStart(cmd, &arg, true, envptr); }
bool Start(const char *cmd, const Vector<String>& arg, const char *envptr = NULL, const char *cd = NULL) { return DoStart(cmd, &arg, false, envptr, cd); }
bool Start2(const char *cmd, const Vector<String>& 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; }

View file

@ -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();

View file

@ -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`<String`>`&`,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`<Upp`:`:String`>`&`,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`<String`>`&`,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`<Upp`:`:String`>`&`,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

View file

@ -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);
}