-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When launching wsl, promote the starting directory to --cd #9223
Changes from all commits
b3bbacf
7bb34c3
ad7b736
5c53dca
4c82087
13a16f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,72 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation | |
return S_OK; | ||
} | ||
|
||
// Function Description: | ||
// - Promotes a starting directory provided to a WSL invocation to a commandline argument. | ||
// This is necessary because WSL has some modicum of support for linux-side directories (!) which | ||
// CreateProcess never will. | ||
static std::tuple<std::wstring, std::wstring> _tryMangleStartingDirectoryForWSL(std::wstring_view commandLine, std::wstring_view startingDirectory) | ||
{ | ||
do | ||
{ | ||
if (startingDirectory.size() > 0 && commandLine.size() >= 3) | ||
{ // "wsl" is three characters; this is a safe bet. no point in doing it if there's no starting directory though! | ||
// Find the first space, quote or the end of the string -- we'll look for wsl before that. | ||
const auto terminator{ commandLine.find_first_of(LR"(" )", 1) }; // look past the first character in case it starts with " | ||
const auto start{ til::at(commandLine, 0) == L'"' ? 1 : 0 }; | ||
const std::filesystem::path executablePath{ commandLine.substr(start, terminator - start) }; | ||
const auto executableFilename{ executablePath.filename().wstring() }; | ||
if (executableFilename == L"wsl" || executableFilename == L"wsl.exe") | ||
{ | ||
// We've got a WSL -- let's just make sure it's the right one. | ||
if (executablePath.has_parent_path()) | ||
{ | ||
std::wstring systemDirectory{}; | ||
if (FAILED(wil::GetSystemDirectoryW(systemDirectory))) | ||
{ | ||
break; // just bail out. | ||
} | ||
if (executablePath.parent_path().wstring() != systemDirectory) | ||
{ | ||
break; // it wasn't in system32! | ||
} | ||
} | ||
else | ||
{ | ||
// assume that unqualified WSL is the one in system32 (minor danger) | ||
} | ||
|
||
const auto arguments{ terminator == std::wstring_view::npos ? std::wstring_view{} : commandLine.substr(terminator + 1) }; | ||
if (arguments.find(L"--cd") != std::wstring_view::npos) | ||
{ | ||
break; // they've already got a --cd! | ||
} | ||
|
||
const auto tilde{ arguments.find_first_of(L'~') }; | ||
if (tilde != std::wstring_view::npos) | ||
{ | ||
if (tilde + 1 == arguments.size() || til::at(arguments, tilde + 1) == L' ') | ||
{ | ||
// We want to suppress --cd if they have added a bare ~ to their commandline (they conflict). | ||
break; | ||
} | ||
// Tilde followed by non-space should be okay (like, wsl -d Debian ~/blah.sh) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mildly worried this will bite us slightly but it's still worth trying as it SEEMS ok. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea I'm mildly worried about someone doing some silly thing like (that's made up but you get the point) |
||
} | ||
|
||
return { | ||
fmt::format(LR"("{}" --cd "{}" {})", executablePath.wstring(), startingDirectory, arguments), | ||
std::wstring{} | ||
}; | ||
} | ||
} | ||
} while (false); | ||
|
||
return { | ||
std::wstring{ commandLine }, | ||
std::wstring{ startingDirectory } | ||
}; | ||
} | ||
|
||
// Function Description: | ||
// - launches the client application attached to the new pseudoconsole | ||
HRESULT ConptyConnection::_LaunchAttachedClient() noexcept | ||
|
@@ -163,11 +229,12 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation | |
siEx.StartupInfo.lpTitle = mutableTitle.data(); | ||
} | ||
|
||
const wchar_t* const startingDirectory = _startingDirectory.size() > 0 ? _startingDirectory.c_str() : nullptr; | ||
auto [newCommandLine, newStartingDirectory] = _tryMangleStartingDirectoryForWSL(cmdline, _startingDirectory); | ||
const wchar_t* const startingDirectory = newStartingDirectory.size() > 0 ? newStartingDirectory.c_str() : nullptr; | ||
|
||
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW( | ||
nullptr, | ||
cmdline.data(), | ||
newCommandLine.data(), | ||
nullptr, // lpProcessAttributes | ||
nullptr, // lpThreadAttributes | ||
false, // bInheritHandles | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.