bash: explicitly request a login shell

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/7253/head
Jon Parise 2025-05-02 07:42:51 -04:00
parent b6f338065e
commit 37974dba06
1 changed files with 47 additions and 17 deletions

View File

@ -239,7 +239,7 @@ fn setupBash(
resource_dir: []const u8,
env: *EnvMap,
) !?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();
// Iterator that yields each argument in the original command line.
@ -247,12 +247,17 @@ fn setupBash(
var iter = try command.argIterator(alloc);
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| {
try args.append(try alloc.dupeZ(u8, exe));
} else return null;
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
// to our shell integration script: --norc --noprofile
// 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);
try testing.expectEqual(2, command.?.direct.len);
try testing.expect(command.?.direct.len >= 2);
try testing.expectEqualStrings("bash", command.?.direct[0]);
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("1", env.get("GHOSTTY_BASH_INJECT").?);
}
@ -387,9 +395,12 @@ test "bash: inject flags" {
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("--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").?);
}
@ -400,9 +411,12 @@ test "bash: inject flags" {
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("--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").?);
}
}
@ -419,18 +433,24 @@ test "bash: rcfile" {
// bash --rcfile
{
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("--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").?);
}
// bash --init-file
{
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("--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").?);
}
}
@ -476,25 +496,35 @@ test "bash: additional arguments" {
// "-" argument separator
{
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("--posix", command.?.direct[1]);
try testing.expectEqualStrings("-", command.?.direct[2]);
try testing.expectEqualStrings("--arg", command.?.direct[3]);
try testing.expectEqualStrings("file1", command.?.direct[4]);
try testing.expectEqualStrings("file2", command.?.direct[5]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
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
{
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("--posix", command.?.direct[1]);
try testing.expectEqualStrings("--", command.?.direct[2]);
try testing.expectEqualStrings("--arg", command.?.direct[3]);
try testing.expectEqualStrings("file1", command.?.direct[4]);
try testing.expectEqualStrings("file2", command.?.direct[5]);
if (comptime builtin.target.os.tag.isDarwin()) {
try testing.expectEqualStrings("--login", command.?.direct[2]);
}
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]);
}
}