Allow redirecting to a log file in --detach mode

This commit is contained in:
Kovid Goyal
2025-04-24 06:46:46 +05:30
parent 18d58587fb
commit 559e8449c5
4 changed files with 17 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from collections.abc import Callable
from contextlib import suppress
@@ -189,6 +190,10 @@ Detach from the controlling terminal, if any, running in an independent child pr
the parent process exits immediately.
--detached-log
Path to a log file to store STDOUT/STDERR when using :option:`--detach`
--debug-rendering
type=bool-set
For internal debugging use.
@@ -346,7 +351,7 @@ def main(sys_args: list[str]) -> None:
args, items = parse_panel_args(sys_args[1:])
if args.detach:
from kitty.utils import detach
detach()
detach(log_file=args.detached_log or os.devnull)
sys.argv = ['kitty']
if args.debug_rendering:
sys.argv.append('--debug-rendering')

View File

@@ -67,12 +67,13 @@ process_group_map(PyObject *self UNUSED, PyObject *args UNUSED) {
#endif
static PyObject*
redirect_std_streams(PyObject UNUSED *self, PyObject *args) {
char *devnull = NULL;
if (!PyArg_ParseTuple(args, "s", &devnull)) return NULL;
if (freopen(devnull, "r", stdin) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
if (freopen(devnull, "w", stdout) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
if (freopen(devnull, "w", stderr) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
redirect_std_streams(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
char *in = "", *out = "", *err = "";
static const char* kwlist[] = {"stdin", "stdout", "stderr", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|sss", (char**)kwlist, &in, &out, &err)) return NULL;
if (in[0] && freopen(in, "r", stdin) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
if (out[0] && freopen(out, "a", stdout) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
if (out[0] && freopen(err, "a", stderr) == NULL) return PyErr_SetFromErrno(PyExc_OSError);
Py_RETURN_NONE;
}
@@ -663,7 +664,7 @@ static PyMethodDef module_methods[] = {
{"char_props_for", py_char_props_for, METH_O, ""},
{"split_into_graphemes", (PyCFunction)split_into_graphemes, METH_O, ""},
{"thread_write", (PyCFunction)cm_thread_write, METH_VARARGS, ""},
{"redirect_std_streams", (PyCFunction)redirect_std_streams, METH_VARARGS, ""},
{"redirect_std_streams", (PyCFunction)(void (*) (void))(redirect_std_streams), METH_VARARGS | METH_KEYWORDS, NULL},
{"locale_is_valid", (PyCFunction)locale_is_valid, METH_VARARGS, ""},
{"shm_open", (PyCFunction)py_shm_open, METH_VARARGS, ""},
{"shm_unlink", (PyCFunction)py_shm_unlink, METH_VARARGS, ""},

View File

@@ -335,7 +335,7 @@ def log_error_string(s: str) -> None:
pass
def redirect_std_streams(devnull: str) -> None:
def redirect_std_streams(stdin: str = '', stdout: str = '', stderr: str = '') -> None:
pass

View File

@@ -257,7 +257,7 @@ def open_url(url: str, program: str | list[str] = 'default', cwd: str | None = N
return open_cmd(command_for_open(program), url, cwd=cwd, extra_env=extra_env)
def detach(fork: bool = True, setsid: bool = True, redirect: bool = True) -> None:
def detach(fork: bool = True, setsid: bool = True, redirect: bool = True, log_file: str = os.devnull) -> None:
if fork:
# Detach from the controlling process.
if os.fork() != 0:
@@ -266,7 +266,7 @@ def detach(fork: bool = True, setsid: bool = True, redirect: bool = True) -> Non
os.setsid()
if redirect:
from .fast_data_types import redirect_std_streams
redirect_std_streams(os.devnull)
redirect_std_streams(stdin=os.devnull, stdout=log_file, stderr=log_file)
def init_startup_notification_x11(window_handle: int, startup_id: str | None = None) -> Optional['StartupCtx']: