Subject: bug#13290: 24.2.91; [PATCH] Comint can stall emacs with non-trivial input senders

From: Vitalie Spinu <[email-masked]>
Date: Thu, 27 Dec 2012 22:49:01 +0100

Hi, 

Comint can stall emacs while waiting for subproces output. I attach a
trivial patch.

Here is a short explanation. First comint calls comint-input-sender 

╭──────── #1842 ─ /home/vitoshka/TVC/emacs/lisp/comint.el ──
│         (let ((comint-input-sender-no-newline no-newline))
│           (funcall comint-input-sender proc input))
╰──────── #1843 ─

Then, if process echoes, comint first waits for process output:

╭──────── #1850 ─ /home/vitoshka/TVC/emacs/lisp/comint.el ──
│             (while (and (accept-process-output proc)
│                         (> (+ comint-last-input-end echo-len)
│                            (point-max))
╰──────── #1852 ─

The problem is that, occasionally, comint-input-sender might be a
non-trivial function and could take care of process output itself. Thus,
accept-process-output will wait for nonexistent output, and stall
emacs. The patch just reverts the order in the (and ...) above.

    Thanks, 
    Vitalie

>From d3c2753a571688370a4bc8fa2254679d9c23b74a Mon Sep 17 00:00:00 2001
From: Vitalie Spinu <[email-masked]>
Date: Thu, 27 Dec 2012 21:46:38 +0100
Subject: [PATCH] Avoid hanging emacs by complex comint input senders.

Revert the order of echo-len check and accept-process-output to avoid stalling
Emacs when there is no process output left.
---
 lisp/ChangeLog |    6 ++++++
 lisp/comint.el |    4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 5f4853d..cc94b0d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
+2012-12-27  Vitalie Spinu  <[email-masked]>
+
+	* comint.el (comint-send-input): revert the order of echo-len
+	check and accept-process-output to avoid hanging Emacs when there
+	is no process output left.
+
 2012-12-27  Michael Albinus  <[email-masked]>
 
 	* net/tramp.el (tramp-handle-file-accessible-directory-p): New defun.
diff --git a/lisp/comint.el b/lisp/comint.el
index f3450e3..6477f00 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -1847,9 +1847,9 @@ Similarly for Soar, Scheme, etc."
           (let ((echo-len (- comint-last-input-end
                              comint-last-input-start)))
             ;; Wait for all input to be echoed:
-            (while (and (accept-process-output proc)
-                        (> (+ comint-last-input-end echo-len)
+            (while (and (> (+ comint-last-input-end echo-len)
                            (point-max))
+                        (accept-process-output proc)
                         (zerop
                          (compare-buffer-substrings
                           nil comint-last-input-start
-- 
1.7.10.4

In GNU Emacs 24.2.91.1 (i686-pc-linux-gnu, GTK+ Version 2.24.13)
 of 2012-12-25 on vitoshka-home
Windowing system distributor `The X.Org Foundation', version 11.0.11300000
System Description:	Ubuntu 12.10

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t