bash: explicitly request a login shell (#7253)

Prior to #7044, on macOS, our shell integrated command line would be
executed under `exec -l`, which caused bash to be started as a login
shell. Now that we're using direct command execution, add `--login` to
our bash command's arguments on macOS to get that same behavior.
pull/7275/head
Mitchell Hashimoto 2025-05-06 07:16:09 -07:00 committed by GitHub
commit 7ce828253a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 47 additions and 17 deletions

View File

@ -239,7 +239,7 @@ fn setupBash(
resource_dir: []const u8, resource_dir: []const u8,
env: *EnvMap, env: *EnvMap,
) !?config.Command { ) !?config.Command {
var args = try std.ArrayList([:0]const u8).initCapacity(alloc, 2); var args = try std.ArrayList([:0]const u8).initCapacity(alloc, 3);
defer args.deinit(); defer args.deinit();
// Iterator that yields each argument in the original command line. // Iterator that yields each argument in the original command line.
@ -247,12 +247,17 @@ fn setupBash(
var iter = try command.argIterator(alloc); var iter = try command.argIterator(alloc);
defer iter.deinit(); defer iter.deinit();
// Start accumulating arguments with the executable and `--posix` mode flag. // Start accumulating arguments with the executable and initial flags.
if (iter.next()) |exe| { if (iter.next()) |exe| {
try args.append(try alloc.dupeZ(u8, exe)); try args.append(try alloc.dupeZ(u8, exe));
} else return null; } else return null;
try args.append("--posix"); try args.append("--posix");
// On macOS, we request a login shell to match that platform's norms.
if (comptime builtin.target.os.tag.isDarwin()) {
try args.append("--login");
}
// Stores the list of intercepted command line flags that will be passed // Stores the list of intercepted command line flags that will be passed
// to our shell integration script: --norc --noprofile // to our shell integration script: --norc --noprofile
// We always include at least "1" so the script can differentiate between // We always include at least "1" so the script can differentiate between
@ -342,9 +347,12 @@ test "bash" {
const command = try setupBash(alloc, .{ .shell = "bash" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
try testing.expectEqualStrings("./shell-integration/bash/ghostty.bash", env.get("ENV").?); try testing.expectEqualStrings("./shell-integration/bash/ghostty.bash", env.get("ENV").?);
try testing.expectEqualStrings("1", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1", env.get("GHOSTTY_BASH_INJECT").?);
} }
@ -387,9 +395,12 @@ test "bash: inject flags" {
const command = try setupBash(alloc, .{ .shell = "bash --norc" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --norc" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
try testing.expectEqualStrings("1 --norc", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1 --norc", env.get("GHOSTTY_BASH_INJECT").?);
} }
@ -400,9 +411,12 @@ test "bash: inject flags" {
const command = try setupBash(alloc, .{ .shell = "bash --noprofile" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --noprofile" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
try testing.expectEqualStrings("1 --noprofile", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1 --noprofile", env.get("GHOSTTY_BASH_INJECT").?);
} }
} }
@ -419,18 +433,24 @@ test "bash: rcfile" {
// bash --rcfile // bash --rcfile
{ {
const command = try setupBash(alloc, .{ .shell = "bash --rcfile profile.sh" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --rcfile profile.sh" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?); try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?);
} }
// bash --init-file // bash --init-file
{ {
const command = try setupBash(alloc, .{ .shell = "bash --init-file profile.sh" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --init-file profile.sh" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?); try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?);
} }
} }
@ -476,25 +496,35 @@ test "bash: additional arguments" {
// "-" argument separator // "-" argument separator
{ {
const command = try setupBash(alloc, .{ .shell = "bash - --arg file1 file2" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash - --arg file1 file2" }, ".", &env);
try testing.expectEqual(6, command.?.direct.len); try testing.expect(command.?.direct.len >= 6);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("-", command.?.direct[2]); if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--arg", command.?.direct[3]); try testing.expectEqualStrings("--login", command.?.direct[2]);
try testing.expectEqualStrings("file1", command.?.direct[4]); }
try testing.expectEqualStrings("file2", command.?.direct[5]);
const offset = if (comptime builtin.target.os.tag.isDarwin()) 3 else 2;
try testing.expectEqualStrings("-", command.?.direct[offset + 0]);
try testing.expectEqualStrings("--arg", command.?.direct[offset + 1]);
try testing.expectEqualStrings("file1", command.?.direct[offset + 2]);
try testing.expectEqualStrings("file2", command.?.direct[offset + 3]);
} }
// "--" argument separator // "--" argument separator
{ {
const command = try setupBash(alloc, .{ .shell = "bash -- --arg file1 file2" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash -- --arg file1 file2" }, ".", &env);
try testing.expectEqual(6, command.?.direct.len); try testing.expect(command.?.direct.len >= 6);
try testing.expectEqualStrings("bash", command.?.direct[0]); try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]); try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("--", command.?.direct[2]); if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--arg", command.?.direct[3]); try testing.expectEqualStrings("--login", command.?.direct[2]);
try testing.expectEqualStrings("file1", command.?.direct[4]); }
try testing.expectEqualStrings("file2", command.?.direct[5]);
const offset = if (comptime builtin.target.os.tag.isDarwin()) 3 else 2;
try testing.expectEqualStrings("--", command.?.direct[offset + 0]);
try testing.expectEqualStrings("--arg", command.?.direct[offset + 1]);
try testing.expectEqualStrings("file1", command.?.direct[offset + 2]);
try testing.expectEqualStrings("file2", command.?.direct[offset + 3]);
} }
} }