From 68b861b188c585ab4c8484bacd18747a56a1c4d6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 24 Sep 2023 11:12:02 +0530 Subject: [PATCH] macOS: When running the default shell, run it via the login program so that calls to ``getlogin()`` work Fixes #6511 --- docs/changelog.rst | 2 ++ kitty/child.py | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 982ffcd0d..dc099d75b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -54,6 +54,8 @@ Detailed list of changes - Expand environment variables in the :opt:`shell` option (:iss:`6511`) +- macOS: When running the default shell, run it via the login program so that calls to ``getlogin()`` work (:iss:`6511`) + 0.30.0 [2023-09-18] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/child.py b/kitty/child.py index c52184f99..fcc0fe02a 100644 --- a/kitty/child.py +++ b/kitty/child.py @@ -214,6 +214,8 @@ class Child: self.cwd = os.path.abspath(cwd) self.stdin = stdin self.env = env or {} + self.is_default_shell = bool(self.argv and self.argv[0] == shell_path) + self.should_run_via_run_shell_kitten = is_macos and self.is_default_shell def final_env(self) -> Dict[str, str]: from kitty.options.utils import DELETE_ENV_VAR @@ -244,7 +246,7 @@ class Child: if opts.forward_stdio: env['KITTY_STDIO_FORWARDED'] = '3' self.unmodified_argv = list(self.argv) - if 'disabled' not in opts.shell_integration: + if not self.should_run_via_run_shell_kitten and 'disabled' not in opts.shell_integration: from .shell_integration import modify_shell_environ modify_shell_environ(opts, env, self.argv) env = {k: v for k, v in env.items() if v is not DELETE_ENV_VAR} @@ -271,10 +273,10 @@ class Child: os.set_inheritable(stdin_read_fd, True) else: stdin_read_fd = stdin_write_fd = -1 - env = tuple(f'{k}={v}' for k, v in self.final_env().items()) + final_env = self.final_env() + env = tuple(f'{k}={v}' for k, v in final_env.items()) argv = list(self.argv) - exe = argv[0] - if is_macos and exe == shell_path: + if self.should_run_via_run_shell_kitten: # bash will only source ~/.bash_profile if it detects it is a login # shell (see the invocation section of the bash man page), which it # does if argv[0] is prefixed by a hyphen see @@ -289,8 +291,19 @@ class Child: # https://github.com/kovidgoyal/kitty/issues/1870 # xterm, urxvt, konsole and gnome-terminal do not do it in my # testing. - argv[0] = (f'-{exe.split("/")[-1]}') - self.final_exe = which(exe) or exe + import shlex + ksi = ' '.join(opts.shell_integration) + if ksi == 'invalid': + ksi = 'enabled' + argv = [kitten_exe(), 'run-shell', '--shell', shlex.join(argv), '--shell-integration', ksi] + if is_macos: + # In addition for getlogin() to work we need to run the shell + # via the /usr/bin/login wrapper, sigh. + # https://github.com/kovidgoyal/kitty/issues/6511 + import pwd + user = pwd.getpwuid(os.geteuid()).pw_name + argv = ['/usr/bin/login', '-f', '-l', '-p', user] + argv + self.final_exe = which(argv[0]) or argv[0] self.final_argv0 = argv[0] pid = fast_data_types.spawn( self.final_exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd,