From a045f4f0e65be77f78d305e6304cc77a7fb4369d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 3 Nov 2016 18:04:39 +0530 Subject: [PATCH] Retrieve child exit status before shutting down --- kitty/main.py | 7 ++++--- kitty/utils.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/kitty/main.py b/kitty/main.py index cc54cd52a..77fe23e1f 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -13,7 +13,7 @@ from gettext import gettext as _ from .config import load_config from .constants import appname, str_version, config_dir from .boss import Boss -from .utils import fork_child, hangup +from .utils import fork_child, hangup, get_child_status from .shaders import GL_VERSION from .fast_data_types import glewInit, enable_automatic_opengl_error_checking import glfw @@ -56,7 +56,9 @@ def run_app(opts, args): glfw.glfwMakeContextCurrent(window) glewInit() glfw.glfwSwapInterval(1) + child = args.args or [pwd.getpwuid(os.geteuid()).pw_shell or '/bin/sh'] boss = Boss(window, window_width, window_height, opts, args) + fork_child(child, args.directory, opts) glfw.glfwSetFramebufferSizeCallback(window, boss.on_window_resize) boss.start() try: @@ -69,6 +71,7 @@ def run_app(opts, args): boss.close() boss.join() boss.destroy() + get_child_status() # Ensure child does not become zombie finally: glfw.glfwDestroyWindow(window) @@ -93,8 +96,6 @@ def main(): if not glfw.glfwInit(): raise SystemExit('GLFW initialization failed') try: - child = args.args or [pwd.getpwuid(os.geteuid()).pw_shell or '/bin/sh'] - fork_child(child, args.directory, opts) if args.profile: tf = tempfile.NamedTemporaryFile(prefix='kitty-profiling-stats-') args.profile = tf.name diff --git a/kitty/utils.py b/kitty/utils.py index 4fa01ddff..e707d6d2b 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -84,10 +84,21 @@ def hangup(): if hasattr(fork_child, 'pid'): pid = fork_child.pid del fork_child.pid - pgrp = os.getpgid(pid) + try: + pgrp = os.getpgid(pid) + except ProcessLookupError: + return os.killpg(pgrp, signal.SIGHUP) os.close(create_pty()[0]) + +def get_child_status(): + if hasattr(fork_child, 'pid'): + try: + return os.waitid(os.P_PID, fork_child.pid, os.WEXITED | os.WNOHANG) + except ChildProcessError: + del fork_child.pid + base_size = sys.getsizeof('')