summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/terminal.cpp31
1 files changed, 21 insertions, 10 deletions
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 <string>
#include <cctype>
#include <linux/input.h>
+#include <sys/wait.h>
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