Closed sfsam closed 1 year ago
Works for me with
kitty --config=NONE
and inside kitty run
kitty +runpy "import os; print(os.getlogin())"
I still get root
with kitty --config=NONE
and kitty +runpy "import os; print(os.getlogin())"
.
Both Terminal.app and Alacritty report the correct username.
Why might kitty report root, but the other terminal emulators report the username?
FWIW, I installed kitty with the command on https://sw.kovidgoyal.net/kitty/binary/
kitty isnt reporting anything. getlogin() does not interact with the controlling terminal in any way. IIRC it uses a bunch of heuristics like looking at the file owners of controlling tty devices, env vars, etc. Since apple is closed source no way to know exactly what getlogin() does.
From macos man 2 getlogin
:
The
getlogin()
routine returns the login name of the user associated with the current session, as previously set bysetlogin()
. The name is normally associated with a login shell at the time a session is created, and is inherited by all processes descended from the login shell. (This is true even if some of those processes assume another user ID, for example whensu(1)
is used.)
I think the setlogin
part is the key here. It's not that Kitty is doing something wrong, it's just that the other macos terminals are starting login shells. You can replicate the default Kitty behavior in iTerm, for example, by changing the "Command" setting from "Login Shell" to "Command", and passing "/bin/zsh". If you then run python3 -c 'import os; print(os.getlogin())'
or something else that calls the getlogin
routine, it'll report root
as well.
After some experiments (just switched to macos from Arch...) it seems like what happens is that the init process in macos (launchd
) is the parent of any program that you start as a logged in user. The launchd process itself has uid=0, or root. It doesn't appear to call setlogin
each time a program is started, but just setuid
(or something similar). I think that in Linux the parent process is usually a login shell or maybe calls setlogin
(haven't checked).
What iTerm, terminal.app, and others seem to be doing is to call login
when launching your shell. Here's the htop output in tree mode:
The top -zsh
process was started with the default iTerm setting ("Login Shell"), and the second one is using the custom "Command" set to "/bin/zsh".
I've browsed the issues in this repo and it seems like @kovidgoyal understands this much better than I ever will. Here's my attempts at fixing this issue by updating the shell
in my kitty config:
shell .
# Kitty spawns `-zsh`, getlogin returns `root`
shell /bin/zsh --login --interactive
# Kitty spawns -zsh --login --interactive, getlogin returns `root
shell /usr/bin/login -f andrelaszlo /bin/zsh
# Kitty spawns `login`, which spawns `-zsh`, getlogin returns `andrelaszlo`
The last one matches the behavior of other terminal apps on macos, both in terms of what they spawn and what getlogin
returns. The problem is that for some reason the TERMINFO
environment variable isn't set properly now, which of course causes problems. Another issue is that my username is hard coded in the config, maybe there's a workaround? iTerm has simple variable substitutions, like $$USERNAME$$
.
Maybe this is not the biggest issue, but I wanted to add the info I found in case it helps someone else. I haven't figured out how the TERMINFO environment variable (and the other Kitty env vars of course) is set, but if that worked I would have had an okay workaround at least! :)
Small update, this works perfectly:
shell /usr/bin/login -fpq andrelaszlo /bin/zsh
But the kitty variable substitution doesn't seem to work the way I expected it to:
shell /usr/bin/login -fpq ${USER} /bin/zsh
Gives ´login incorrect`. Tried finding a debug flag that would log what it's expanded to, but didn't find anything.
Instead, I tried this - to see if it expands the variable at all:
shell "/opt/homebrew/bin/bash" "-c" "echo user: ${USER}; sleep 10"
I tried various ways of quoting the shell /usr/bin/login -fpq ${USER} /bin/zsh
line, but always ended up with login incorrect
, despite ${USER}
expanding correctly to andrelaszlo
in the bash echo experiment.
This monstrosity does what I want, except it also starts a bash process of course 😆
shell "/opt/homebrew/bin/bash" "-c" "/usr/bin/login -fpq ${USER} /bin/zsh"
Next step would be to read the Kitty code to understand the variable expansion better, but it's getting late! 😴 Would be super interesting to know what's going on though.
kitty does start shells in login mode by default on macOS. You dont need to set shell at all, see line 277 onwards in child.py
kitty does start shells in login mode by default on macOS.
@kovidgoyal True! I should have written a better summary:
getlogin
on macos (at least my version, 13.5 "Ventura") since it returns root for processes even though they're running under a login shell with a different uid. This kind of contradicts the macos getlogin
man page:
The getlogin() routine returns the login name of the user associated with the current session, as previously set by setlogin(). The name is normally associated with a login shell at the time a session is created, and is inherited by all processes descended from the login shell
setlogin
is never called (and .profile
never loaded). I learned a little bit about this in this SO answer.login
(as in /usr/bin/login
), which will not only launch the shell in login mode automatically, but also call setlogin
- which makes the issue of getlogin
returning root
go away - (as well as login
, you need to pass the current username, so environment variable expansion for shell
config lines might be useful.I was confused about env var expansion yesterday, my bad! It seems like it's only working for include*
lines, and that the expansion I managed to get working was actually done by bash 🤦
On Sat, Sep 23, 2023 at 09:24:44AM -0700, André Laszlo wrote:
kitty does start shells in login mode by default on macOS.
@kovidgoyal True! I should have written a better summary:
- There seems to be a bug in
getlogin
on macos (at least my version, 13.5 "Ventura") since it returns root for processes even though they're running under a login shell with a different uid. This kind of contradicts the macosgetlogin
man page:The getlogin() routine returns the login name of the user associated with the current session, as previously set by setlogin(). The name is normally associated with a login shell at the time a session is created, and is inherited by all processes descended from the login shell
- Kitty starts login shells just fine, but apparently that's not enough. Macos doesn't seem to run the user session inside a login shell, so
setlogin
is never called (and.profile
never loaded). I learned a little bit about this in this SO answer.
No, starting a shell in login mode is enough to load ~/.bash_profile. See man bash or man zsh. As long as the shell is started in login mode it will read /etc/profile and ~/.profile and kitty does this.
- The way
lesserother terminals work on macos is that they start shells using thelogin
(as in/usr/bin/login
), which will not only launch the shell in login mode automatically, but also callsetlogin
- which makes the issue ofgetlogin
returningroot
go away - (as well assolvemask the issues other Kitty users might have had with profiles not being loaded etc).
The only issue here is getlogin(). Reading the macOS login manpage it messes with a bunch of env vars including TERM, so it seems to me the cure is worse than the disease. The way to do this would probably be to use the run-shell kitten. Something like
/usr/bin/login -fpl $USER kitten run-shell --shell=
- In order to launch a shell with
login
, you need to pass the current username, so environment variable expansion forshell
config lines might be useful.
I am OK with implementing env var expansion for this setting.
@kovidgoyal Amazing, thanks for taking the time!
I must be doing something obviously wrong, but I don't know what...
Describe the bug Calling the
getlogin()
system call from a simple C program returnsroot
when run in kitty. Running the same program in Terminal.app returns the correct username.To Reproduce Run the following program in kitty and Terminal.app and compare output. Both kitty and Terminal.app are launched the standard way by double-clicking the app icon in the
/Applications
folder.Screenshots kitty:
Terminal.app:
Environment details
Additional context
kitty --config NONE
reproduces the same output:root
instead of username.