Remote control: Allow using a random TCP socket as the remote control socket and also allow using TCP sockets in kitty.conf

This commit is contained in:
Kovid Goyal
2023-08-04 11:12:31 +05:30
parent 395e47cc9e
commit bde4a41ed4
5 changed files with 24 additions and 16 deletions

View File

@@ -47,6 +47,8 @@ Detailed list of changes
- kitten @ ls: Allow limiting output to matched windows/tabs (:iss:`6520`) - kitten @ ls: Allow limiting output to matched windows/tabs (:iss:`6520`)
- Remote control: Allow using a random TCP socket as the remote control socket and also allow using TCP sockets in :opt:`listen_on`
- X11: Print an error to :file:`STDERR` instead of refusing to start when the user sets a custom window icon larger than 128x128 (:iss:`6507`) - X11: Print an error to :file:`STDERR` instead of refusing to start when the user sets a custom window icon larger than 128x128 (:iss:`6507`)
0.29.2 [2023-07-27] 0.29.2 [2023-07-27]

View File

@@ -169,14 +169,18 @@ class OSWindowDict(TypedDict):
wm_name: str wm_name: str
def listen_on(spec: str) -> int: def listen_on(spec: str) -> Tuple[int, str]:
import socket import socket
family, address, socket_path = parse_address_spec(spec) family, address, socket_path = parse_address_spec(spec)
s = socket.socket(family) s = socket.socket(family)
atexit.register(remove_socket_file, s, socket_path) atexit.register(remove_socket_file, s, socket_path)
s.bind(address) s.bind(address)
s.listen() s.listen()
return s.fileno() if isinstance(address, tuple):
h, resolved_port = s.getsockname()
sfamily, host, port = spec.split(':', 2)
spec = f'{sfamily}:{host}:{resolved_port}'
return s.fileno(), spec
def data_for_at(w: Optional[Window], arg: str, add_wrap_markers: bool = False) -> Optional[str]: def data_for_at(w: Optional[Window], arg: str, add_wrap_markers: bool = False) -> Optional[str]:
@@ -357,8 +361,7 @@ class Boss:
self.allow_remote_control = 'n' self.allow_remote_control = 'n'
self.listening_on = '' self.listening_on = ''
if args.listen_on and self.allow_remote_control in ('y', 'socket', 'socket-only', 'password'): if args.listen_on and self.allow_remote_control in ('y', 'socket', 'socket-only', 'password'):
listen_fd = listen_on(args.listen_on) listen_fd, self.listening_on = listen_on(args.listen_on)
self.listening_on = args.listen_on
self.child_monitor = ChildMonitor( self.child_monitor = ChildMonitor(
self.on_child_death, self.on_child_death,
DumpCommands(args) if args.dump_commands or args.dump_bytes else None, DumpCommands(args) if args.dump_commands or args.dump_bytes else None,

View File

@@ -948,8 +948,8 @@ you can send commands to it with :italic:`{appname} @` using the
:italic:`{appname} @` within a kitty window, there is no need to specify the :italic:`{appname} @` within a kitty window, there is no need to specify the
:option:`{appname} @ --to` option as it will automatically read from the :option:`{appname} @ --to` option as it will automatically read from the
environment. Note that this will be ignored unless :opt:`allow_remote_control` environment. Note that this will be ignored unless :opt:`allow_remote_control`
is set to either: :code:`yes`, :code:`socket` or :code:`socket-only`. For UNIX is set to either: :code:`yes`, :code:`socket` or :code:`socket-only`. This can
sockets, this can also be specified in :file:`{conf_name}.conf`. also be specified in :file:`kitty.conf`.
--start-as --start-as

View File

@@ -359,7 +359,7 @@ def macos_cmdline(argv_args: List[str]) -> List[str]:
def expand_listen_on(listen_on: str, from_config_file: bool) -> str: def expand_listen_on(listen_on: str, from_config_file: bool) -> str:
listen_on = expandvars(listen_on) listen_on = expandvars(listen_on)
if '{kitty_pid}' not in listen_on and from_config_file: if '{kitty_pid}' not in listen_on and from_config_file and listen_on.startswith('unix:'):
listen_on += '-{kitty_pid}' listen_on += '-{kitty_pid}'
listen_on = listen_on.replace('{kitty_pid}', str(os.getpid())) listen_on = listen_on.replace('{kitty_pid}', str(os.getpid()))
if listen_on.startswith('unix:'): if listen_on.startswith('unix:'):
@@ -370,6 +370,9 @@ def expand_listen_on(listen_on: str, from_config_file: bool) -> str:
elif not os.path.isabs(path): elif not os.path.isabs(path):
import tempfile import tempfile
listen_on = f'unix:{os.path.join(tempfile.gettempdir(), path)}' listen_on = f'unix:{os.path.join(tempfile.gettempdir(), path)}'
elif listen_on.startswith('tcp:') or listen_on.startswith('tcp6:'):
if from_config_file: # use a random port
listen_on = ':'.join(listen_on.split(':', 2)[:2]) + ':0'
return listen_on return listen_on
@@ -432,7 +435,7 @@ def setup_manpath(env: Dict[str, str]) -> None:
def setup_environment(opts: Options, cli_opts: CLIOptions) -> None: def setup_environment(opts: Options, cli_opts: CLIOptions) -> None:
from_config_file = False from_config_file = False
if not cli_opts.listen_on and opts.listen_on.startswith('unix:'): if not cli_opts.listen_on:
cli_opts.listen_on = opts.listen_on cli_opts.listen_on = opts.listen_on
from_config_file = True from_config_file = True
if cli_opts.listen_on: if cli_opts.listen_on:

View File

@@ -2882,18 +2882,18 @@ prevents any form of remote control. The meaning of the various values are:
opt('listen_on', 'none', opt('listen_on', 'none',
long_text=''' long_text='''
Listen to the specified UNIX socket for remote control connections. Note that Listen to the specified socket for remote control connections. Note that this
this will apply to all kitty instances. It can be overridden by the will apply to all kitty instances. It can be overridden by the :option:`kitty
:option:`kitty --listen-on` command line option, which also supports listening --listen-on` command line option. For UNIX sockets, such as
on a TCP socket. This option accepts only UNIX sockets, such as
:code:`unix:${TEMP}/mykitty` or :code:`unix:@mykitty` (on Linux). Environment :code:`unix:${TEMP}/mykitty` or :code:`unix:@mykitty` (on Linux). Environment
variables are expanded and relative paths are resolved with respect to the variables are expanded and relative paths are resolved with respect to the
temporary directory. If :code:`{kitty_pid}` is present, then it is replaced by temporary directory. If :code:`{kitty_pid}` is present, then it is replaced by
the PID of the kitty process, otherwise the PID of the kitty process is the PID of the kitty process, otherwise the PID of the kitty process is
appended to the value, with a hyphen. See the help for :option:`kitty appended to the value, with a hyphen. For TCP sockets such as
--listen-on` for more details. Note that this will be ignored unless :code:`tcp:localhost:0` a random port is always used even if a non-zero port
:opt:`allow_remote_control` is set to either: :code:`yes`, :code:`socket` or number is specified. See the help for :option:`kitty --listen-on` for more
:code:`socket-only`. details. Note that this will be ignored unless :opt:`allow_remote_control` is
set to either: :code:`yes`, :code:`socket` or :code:`socket-only`.
Changing this option by reloading the config is not supported. Changing this option by reloading the config is not supported.
''' '''
) )