From 2f1c8cf397be6c91fcd60234740d9727650c1a87 Mon Sep 17 00:00:00 2001 From: "Martin T. H. Sandsmark" Date: Sun, 10 Jul 2016 00:47:34 +0200 Subject: [PATCH] Send EOF when closing first, before SIGHUP According to the bash maintainer sending EOF is the appropriate way of telling e. g. bash to quit: http://permalink.gmane.org/gmane.comp.shells.bash.bugs/12602 I wasn't able to get KPtyProcess to send that in a nice way (calling setStandardInputFile(QProcess::nullDevice(), for example), so we fetch the EOF character manually with tcgetattr and send that. BUG: 185140 REVIEW: 128416 --- src/Pty.cpp | 16 ++++++++++++++++ src/Pty.h | 5 +++++ src/Session.cpp | 9 +++++++++ 3 files changed, 30 insertions(+) diff --git a/src/Pty.cpp b/src/Pty.cpp index eaeda07db..f76edfbc0 100644 --- a/src/Pty.cpp +++ b/src/Pty.cpp @@ -281,6 +281,22 @@ void Pty::closePty() pty()->close(); } +void Pty::sendEof() +{ + if (pty()->masterFd() < 0) { + qWarning() << "Unable to get eof char attribute, terminal not connected."; + return; + } + struct ::termios ttyAttributes; + pty()->tcGetAttr(&ttyAttributes); + char eofChar = ttyAttributes.c_cc[VEOF]; + if (!pty()->write(QByteArray(1, eofChar))) { + qWarning() << "Unable to send EOF"; + } + + pty()->waitForBytesWritten(); +} + int Pty::foregroundProcessGroup() const { int foregroundPid = tcgetpgrp(pty()->masterFd()); diff --git a/src/Pty.h b/src/Pty.h index 0e7c4786c..5996f95ca 100644 --- a/src/Pty.h +++ b/src/Pty.h @@ -141,6 +141,11 @@ public: */ void closePty(); + /** + * Sends EOF to the controlled process, this is the preferred method of telling e. g. bash to close + */ + void sendEof(); + public slots: /** * Put the pty into UTF-8 mode on systems which support it. diff --git a/src/Session.cpp b/src/Session.cpp index 768dc06ac..65bb220dc 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -822,6 +822,15 @@ bool Session::closeInNormalWay() return true; } + _shellProcess->sendEof(); + + if (_shellProcess->waitForFinished(1000)) { + return true; + } + + qWarning() << "shell did not close, sending SIGHUP"; + + // We tried asking nicely, ask a bit less nicely if (kill(SIGHUP)) { return true; } else {