Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion electron/bridges/terminalBridge.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,45 @@ function getLocalShellArgs(shellPath) {
return [];
}

function isWslExecutable(shellPath) {
if (process.platform !== "win32" || typeof shellPath !== "string") return false;
return /(?:^|[\\/])wsl(?:\.exe)?$/i.test(shellPath.trim());
}

function getWslLaunchArgs(shellPath, shellArgs, hasExplicitCwd) {
const args = Array.isArray(shellArgs) ? [...shellArgs] : [];
// Without --cd, wsl.exe translates the parent Windows cwd. That can fail
// before the Linux shell starts (for example, when the Windows home is not
// mounted or accessible to the selected distro). Start at Linux $HOME unless
// the caller deliberately supplied a working directory or --cd option.
if (
!isWslExecutable(shellPath) ||
hasExplicitCwd ||
args.some((arg) => arg === "--cd" || arg.startsWith("--cd="))
) {
return args;
}

// The tokens following --exec/-e, or the first bare command, are passed to
// Linux verbatim. Account for WSL options with a separate value before
// locating that boundary, then insert --cd before it rather than accidentally
// passing --cd to the shell or command.
let commandIndex = -1;
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === "--exec" || arg === "-e" || !arg.startsWith("-")) {
Comment thread
binaricat marked this conversation as resolved.
Outdated
commandIndex = index;
break;
}
if (arg === "--distribution" || arg === "-d" || arg === "--user" || arg === "-u") {
index += 1;
}
}
const insertAt = commandIndex === -1 ? args.length : commandIndex;
args.splice(insertAt, 0, "--cd", "~");
return args;
}

const isUtf8Locale = (value) => typeof value === "string" && /utf-?8/i.test(value);

const isEmptyLocale = (value) => {
Expand Down Expand Up @@ -896,7 +935,12 @@ function startLocalSession(event, payload) {
}
}
const shell = normalizeExecutablePath(resolvedShell) || defaultShell;
const shellArgs = resolvedArgs ?? getLocalShellArgs(shell);
const requestedCwd = typeof payload?.cwd === "string" && payload.cwd.trim().length > 0;
const shellArgs = getWslLaunchArgs(
shell,
resolvedArgs ?? getLocalShellArgs(shell),
requestedCwd,
);
const shellKind = detectShellKind(shell);
const { buildTerminalProcessEnv } = require("./httpNetworkProxyBridge.cjs");
const env = applyLocaleDefaults({
Expand Down Expand Up @@ -2536,6 +2580,7 @@ module.exports = {
registerHandlers,
findExecutable,
getDefaultLocalShell,
getWslLaunchArgs,
startLocalSession,
startTelnetSession,
startMoshSession,
Expand Down
27 changes: 27 additions & 0 deletions electron/bridges/terminalBridge.outputFlood.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,33 @@ function loadBridgeWithFakes(spawns, sentries) {
}
}

test("WSL launch arguments use Linux home unless a working directory is explicit", () => {
const bridge = loadBridgeWithFakes([], []);
const platformDescriptor = Object.getOwnPropertyDescriptor(process, "platform");

try {
Object.defineProperty(process, "platform", { ...platformDescriptor, value: "win32" });
assert.deepEqual(
bridge.getWslLaunchArgs("C:\\Windows\\System32\\wsl.exe", ["-d", "Ubuntu"], false),
["-d", "Ubuntu", "--cd", "~"],
);
assert.deepEqual(
bridge.getWslLaunchArgs("C:\\Windows\\System32\\wsl.exe", ["-d", "Ubuntu"], true),
["-d", "Ubuntu"],
);
assert.deepEqual(
bridge.getWslLaunchArgs(
"C:\\Windows\\System32\\wsl.exe",
["-d", "Ubuntu", "--exec", "zsh", "-l"],
false,
),
["-d", "Ubuntu", "--cd", "~", "--exec", "zsh", "-l"],
);
} finally {
Object.defineProperty(process, "platform", platformDescriptor);
}
});

test("Windows local terminals enable the bundled ConPTY implementation required for clear", () => {
const spawns = [];
const sentries = [];
Expand Down
Loading