summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorChong Yidong <cyd@gnu.org>2012-04-20 14:39:29 +0800
committerChong Yidong <cyd@gnu.org>2012-04-20 14:39:29 +0800
commitf30d612a7a628828baa7c333629a10295605291b (patch)
tree4ae2ece5cb60bd828d8e0b4657d2912f47a3639c /lisp
parentcd0f830c2127781a9f9f50ab4a0cb8cd05a66a1f (diff)
downloademacs-f30d612a7a628828baa7c333629a10295605291b.tar.gz
Fixes for pty handling in gdb-mi.el and process.c.
* lisp/progmodes/gdb-mi.el (gdb): Revert 2012-04-19 change. (gdb-inferior-io--init-proc): New function. (gdb-init-1): Use it. (gdb-inferior-io-sentinel): New sentinel for the gdb-inferior pty, responsible for allocating a new pty and hooking it to gdb when the old pty gets an EIO due to process exit. (gdb-delchar-or-quit): New command. Bind it in gdb-mi buffers. (gdb-tooltip-print): Don't use obsolete tooltip-use-echo-area. (gdb-inferior-io--maybe-delete-pty): Move into gdb-reset. * src/process.c (wait_reading_process_output): If EIO occurs on a pty, set the status to "failed" and ensure that sentinel is run. * doc/lispref/processes.texi (Asynchronous Processes): Mention nil argument to start-process.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/progmodes/gdb-mi.el69
2 files changed, 58 insertions, 23 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ec008022e0e..601e4f4f59f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,15 @@
+2012-04-20 Chong Yidong <cyd@gnu.org>
+
+ * progmodes/gdb-mi.el (gdb): Revert 2012-04-19 change.
+ (gdb-inferior-io--init-proc): New function.
+ (gdb-init-1): Use it.
+ (gdb-inferior-io-sentinel): New sentinel for the gdb-inferior pty,
+ responsible for allocating a new pty and hooking it to gdb when
+ the old pty gets an EIO due to process exit.
+ (gdb-delchar-or-quit): New command. Bind it in gdb-mi buffers.
+ (gdb-tooltip-print): Don't use obsolete tooltip-use-echo-area.
+ (gdb-inferior-io--maybe-delete-pty): Move into gdb-reset.
+
2012-04-20 Eli Zaretskii <eliz@gnu.org>
* window.el (window-min-size, window-sizable, window-min-delta)
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 450075fde42..455727f9e02 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -817,10 +817,7 @@ detailed description of this mode.
nil 'local)
(local-set-key "\C-i" 'completion-at-point)
- ;; FIXME: Under some circumstances, `gud-sentinel' apparently does
- ;; not get called when the gdb process is killed (Bug#11273).
- (add-hook 'post-command-hook 'gdb-inferior-io--maybe-delete-pty
- nil t)
+ (local-set-key [remap comint-delchar-or-maybe-eof] 'gdb-delchar-or-quit)
(setq gdb-first-prompt t)
(setq gud-running nil)
@@ -863,15 +860,8 @@ detailed description of this mode.
(gdb-get-buffer-create 'gdb-inferior-io)
(gdb-clear-inferior-io)
- (set-process-filter (get-process "gdb-inferior") 'gdb-inferior-filter)
- (gdb-input
- ;; Needs GDB 6.4 onwards
- (concat "-inferior-tty-set "
- (or
- ;; The process can run on a remote host.
- (process-get (get-process "gdb-inferior") 'remote-tty)
- (process-tty-name (get-process "gdb-inferior"))))
- 'ignore)
+ (gdb-inferior-io--init-proc (get-process "gdb-inferior"))
+
(if (eq window-system 'w32)
(gdb-input "-gdb-set new-console off" 'ignore))
(gdb-input "-gdb-set height 0" 'ignore)
@@ -909,6 +899,25 @@ detailed description of this mode.
(setq gdb-non-stop nil)
(gdb-input "-gdb-set non-stop 0" 'ignore)))
+(defun gdb-delchar-or-quit (arg)
+ "Delete ARG characters or send a quit command to GDB.
+Send a quit only if point is at the end of the buffer, there is
+no input, and GDB is waiting for input."
+ (interactive "p")
+ (unless (and (eq (current-buffer) gud-comint-buffer)
+ (eq gud-minor-mode 'gdbmi))
+ (error "Not in a GDB-MI buffer"))
+ (let ((proc (get-buffer-process gud-comint-buffer)))
+ (if (and (eobp) proc (process-live-p proc)
+ (not gud-running)
+ (= (point) (marker-position (process-mark proc))))
+ ;; Sending an EOF does not work with GDB-MI; submit an
+ ;; explicit quit command.
+ (progn
+ (insert "quit")
+ (comint-send-input t t))
+ (delete-char arg))))
+
(defvar gdb-define-alist nil "Alist of #define directives for GUD tooltips.")
(defun gdb-create-define-alist ()
@@ -933,7 +942,6 @@ detailed description of this mode.
(push (cons name define) gdb-define-alist))))
(declare-function tooltip-show "tooltip" (text &optional use-echo-area))
-(defvar tooltip-use-echo-area)
(defun gdb-tooltip-print (expr)
(with-current-buffer (gdb-get-buffer 'gdb-partial-output-buffer)
@@ -941,7 +949,7 @@ detailed description of this mode.
(if (re-search-forward ".*value=\\(\".*\"\\)" nil t)
(tooltip-show
(concat expr " = " (read (match-string 1)))
- (or gud-tooltip-echo-area tooltip-use-echo-area
+ (or gud-tooltip-echo-area
(not (display-graphic-p)))))))
;; If expr is a macro for a function don't print because of possible dangerous
@@ -1514,13 +1522,26 @@ DOC is an optional documentation string."
(gdb-display-buffer
(gdb-get-buffer-create 'gdb-inferior-io) t))
-(defun gdb-inferior-io--maybe-delete-pty ()
- (let ((proc (get-buffer-process gud-comint-buffer))
- (inf-pty (get-process "gdb-inferior")))
- (and (or (null proc)
- (memq (process-status proc) '(exit signal)))
- inf-pty
- (delete-process inf-pty))))
+(defun gdb-inferior-io--init-proc (proc)
+ ;; Set up inferior I/O. Needs GDB 6.4 onwards.
+ (set-process-filter proc 'gdb-inferior-filter)
+ (set-process-sentinel proc 'gdb-inferior-io-sentinel)
+ (gdb-input
+ (concat "-inferior-tty-set "
+ ;; The process can run on a remote host.
+ (or (process-get proc 'remote-tty)
+ (process-tty-name proc)))
+ 'ignore))
+
+(defun gdb-inferior-io-sentinel (proc str)
+ (when (eq (process-status proc) 'failed)
+ ;; When the debugged process exits, Emacs gets an EIO error on
+ ;; read from the pty, and stops listening to it. Remove the pty,
+ ;; make a new one, and pass it to gdb.
+ (let ((buffer (process-buffer proc)))
+ ;; `comint-exec' deletes the original process as a side effect.
+ (comint-exec buffer "gdb-inferior" nil nil nil)
+ (gdb-inferior-io--init-proc (get-buffer-process buffer)))))
(defconst gdb-frame-parameters
'((height . 14) (width . 80)
@@ -4131,7 +4152,9 @@ This arrangement depends on the value of `gdb-many-windows'."
Kills the gdb buffers, and resets variables and the source buffers."
;; The gdb-inferior buffer has a pty hooked up to the main gdb
;; process. This pty must be deleted explicitly.
- (gdb-inferior-io--maybe-delete-pty)
+ (let ((pty (get-process "gdb-inferior")))
+ (if pty (delete-process pty)))
+ ;; Find gdb-mi buffers and kill them.
(dolist (buffer (buffer-list))
(unless (eq buffer gud-comint-buffer)
(with-current-buffer buffer