From a17f175bd3adb514b0e9e37d836642dbf0225024 Mon Sep 17 00:00:00 2001 From: that Date: Mon, 11 Jan 2016 01:07:28 +0100 Subject: gui: reap terminal child process to avoid zombies Change-Id: Ia46d8acb8b13075a2519df1deb91dd30a5969a48 --- gui/terminal.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'gui/terminal.cpp') diff --git a/gui/terminal.cpp b/gui/terminal.cpp index 00424eb90..00b7820a5 100644 --- a/gui/terminal.cpp +++ b/gui/terminal.cpp @@ -28,6 +28,7 @@ #include #include #include +#include extern "C" { #include "../twcommon.h" @@ -124,11 +125,10 @@ public: int rc = ::read(fdMaster, buffer, size); debug_printf("pty read: %d bytes\n", rc); if (rc < 0) { - LOGINFO("pty read failed: %d\n", errno); - // assume child has died - close(fdMaster); - g_pty_fd = fdMaster = -1; - pid = 0; + // assume child has died (usual errno when shell exits seems to be EIO == 5) + if (errno != EIO) + LOGERR("pty read failed: %d\n", errno); + stop(); } return rc; } @@ -142,11 +142,9 @@ public: int rc = ::write(fdMaster, buffer, size); debug_printf("pty write: %d bytes -> %d\n", size, rc); if (rc < 0) { - LOGINFO("pty write failed: %d\n", errno); + LOGERR("pty write failed: %d\n", errno); // assume child has died - close(fdMaster); - g_pty_fd = fdMaster = -1; - pid = 0; + stop(); } return rc; } @@ -168,9 +166,22 @@ public: LOGERR("failed to set window size, error %d\n", errno); } + void stop() + { + if (!started()) { + LOGERR("someone tried to stop pty, but it was not started\n"); + return; + } + close(fdMaster); + g_pty_fd = fdMaster = -1; + int status; + waitpid(pid, &status, WNOHANG); // avoid zombies but don't hang if the child is still alive and we got here due to some error + pid = 0; + } + private: int fdMaster; - int pid; + pid_t pid; }; // UTF-8 decoder -- cgit v1.2.3