potentially reduce more copies in win32 process code

master
Daniel Kolesa 2017-05-13 19:52:19 +02:00
parent 45c8450209
commit 07ea93ba68
1 changed files with 19 additions and 12 deletions

View File

@ -140,7 +140,7 @@ struct pipe {
* makes this kind of easy, but it's still a lot of code I'd rather * makes this kind of easy, but it's still a lot of code I'd rather
* not write... oh well * not write... oh well
*/ */
static std::wstring resolve_file(wchar_t const *cmd) { static std::unique_ptr<wchar_t[]> resolve_file(std::unique_ptr<wchar_t[]> cmd) {
/* a reused buffer, TODO: allow longer paths */ /* a reused buffer, TODO: allow longer paths */
wchar_t buf[1024]; wchar_t buf[1024];
@ -149,7 +149,14 @@ static std::wstring resolve_file(wchar_t const *cmd) {
return (fs::is_regular_file(st) || fs::is_symlink(st)); return (fs::is_regular_file(st) || fs::is_symlink(st));
}; };
fs::path p{cmd}; auto get_unique = [](fs::path const &p) {
auto const &s = p.native();
std::unique_ptr<wchar_t[]> ret{new wchar_t[s.size() + 1]};
std::wstring::traits_type::copy(ret.get(), s.data(), s.size() + 1);
return ret;
};
fs::path p{cmd.get()};
/* deal with some easy cases */ /* deal with some easy cases */
if ((p.filename() != p) || (p == L".") || (p == L"..")) { if ((p.filename() != p) || (p == L".") || (p == L"..")) {
return cmd; return cmd;
@ -163,28 +170,28 @@ static std::wstring resolve_file(wchar_t const *cmd) {
fs::path rp{buf}; fs::path rp{buf};
rp.replace_filename(p); rp.replace_filename(p);
if (is_maybe_exec(rp)) { if (is_maybe_exec(rp)) {
return rp.native(); return get_unique(rp);
} }
} }
/* the current directory */ /* the current directory */
{ {
auto rp = fs::path{L"."} / p; auto rp = fs::path{L"."} / p;
if (is_maybe_exec(rp)) { if (is_maybe_exec(rp)) {
return rp.native(); return get_unique(rp);
} }
} }
/* the system directory */ /* the system directory */
if (GetSystemDirectoryW(buf, sizeof(buf))) { if (GetSystemDirectoryW(buf, sizeof(buf))) {
auto rp = fs::path{buf} / p; auto rp = fs::path{buf} / p;
if (is_maybe_exec(rp)) { if (is_maybe_exec(rp)) {
return rp.native(); return get_unique(rp);
} }
} }
/* the windows directory */ /* the windows directory */
if (GetWindowsDirectoryW(buf, sizeof(buf))) { if (GetWindowsDirectoryW(buf, sizeof(buf))) {
auto rp = fs::path{buf} / p; auto rp = fs::path{buf} / p;
if (is_maybe_exec(rp)) { if (is_maybe_exec(rp)) {
return rp.native(); return get_unique(rp);
} }
} }
/* the PATH envvar */ /* the PATH envvar */
@ -222,7 +229,7 @@ static std::wstring resolve_file(wchar_t const *cmd) {
envp = sp + 1; envp = sp + 1;
} }
if (is_maybe_exec(rp)) { if (is_maybe_exec(rp)) {
return rp.native(); return get_unique(rp);
} }
} }
} }
@ -240,7 +247,7 @@ static std::wstring resolve_file(wchar_t const *cmd) {
*/ */
static std::unique_ptr<wchar_t[]> concat_args( static std::unique_ptr<wchar_t[]> concat_args(
string_range cmd, bool (*func)(string_range &, void *), void *datap, string_range cmd, bool (*func)(string_range &, void *), void *datap,
std::wstring &cmdpath std::unique_ptr<wchar_t[]> &cmdpath
) { ) {
std::string ret; std::string ret;
@ -266,9 +273,9 @@ static std::unique_ptr<wchar_t[]> concat_args(
} }
wcmd.get()[req] = '\0'; wcmd.get()[req] = '\0';
if (!use_path) { if (!use_path) {
cmdpath = wcmd.get(); cmdpath = std::move(wcmd);
} else { } else {
cmdpath = resolve_file(wcmd.get()); cmdpath = resolve_file(std::move(wcmd));
} }
} }
@ -416,7 +423,7 @@ OSTD_EXPORT void subprocess::open_impl(
} }
si.dwFlags |= STARTF_USESTDHANDLES; si.dwFlags |= STARTF_USESTDHANDLES;
std::wstring cmdpath; std::unique_ptr<wchar_t[]> cmdpath;
auto cmdline = concat_args(cmd, func, datap, cmdpath); auto cmdline = concat_args(cmd, func, datap, cmdpath);
std::wstring envstr; std::wstring envstr;
@ -462,7 +469,7 @@ OSTD_EXPORT void subprocess::open_impl(
* actually start when job assignment ends up failing... * actually start when job assignment ends up failing...
*/ */
auto success = CreateProcessW( auto success = CreateProcessW(
cmdpath.data(), cmdpath.get(),
cmdline.get(), cmdline.get(),
nullptr, /* process security attributes */ nullptr, /* process security attributes */
nullptr, /* primary thread security attributes */ nullptr, /* primary thread security attributes */