1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-03 08:30:09 +00:00

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.
This commit is contained in:
Chong Yidong 2012-04-20 14:39:29 +08:00
parent cd0f830c21
commit f30d612a7a
6 changed files with 91 additions and 34 deletions

View File

@ -1,3 +1,8 @@
2012-04-20 Chong Yidong <cyd@gnu.org>
* processes.texi (Asynchronous Processes): Mention nil argument to
start-process.
2012-04-20 Glenn Morris <rgm@gnu.org>
* minibuf.texi (Basic Completion): No need to describe obarrays here.

View File

@ -559,8 +559,13 @@ already exists, then @var{name} is modified (by appending @samp{<1>},
etc.) to be unique. The buffer @var{buffer-or-name} is the buffer to
associate with the process.
If @var{program} is @code{nil}, Emacs opens a new pseudoterminal (pty)
and associates its input and output with @var{buffer-or-name}, without
creating a subprocess. In that case, the remaining arguments
@var{args} are ignored.
The remaining arguments, @var{args}, are strings that specify command
line arguments for the program.
line arguments for the subprocess.
In the example below, the first process is started and runs (rather,
sleeps) for 100 seconds (the output buffer @samp{foo} is created

View File

@ -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)

View File

@ -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

View File

@ -1,3 +1,8 @@
2012-04-20 Chong Yidong <cyd@gnu.org>
* process.c (wait_reading_process_output): If EIO occurs on a pty,
set the status to "failed" and ensure that sentinel is run.
2012-04-18 Glenn Morris <rgm@gnu.org>
* process.c (Fset_process_inherit_coding_system_flag)

View File

@ -4893,16 +4893,23 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
It can't hurt. */
else if (nread == -1 && errno == EIO)
{
/* Don't do anything if only a pty, with no associated
process (bug#10933). */
if (XPROCESS (proc)->pid != -2) {
/* Clear the descriptor now, so we only raise the signal
once. */
FD_CLR (channel, &input_wait_mask);
FD_CLR (channel, &non_keyboard_wait_mask);
kill (getpid (), SIGCHLD);
}
struct Lisp_Process *p = XPROCESS (proc);
/* Clear the descriptor now, so we only raise the
signal once. */
FD_CLR (channel, &input_wait_mask);
FD_CLR (channel, &non_keyboard_wait_mask);
if (p->pid == -2)
{
/* If the EIO occurs on a pty, sigchld_handler's
wait3() will not find the process object to
delete. Do it here. */
p->tick = ++process_tick;
p->status = Qfailed;
}
else
kill (getpid (), SIGCHLD);
}
#endif /* HAVE_PTYS */
/* If we can detect process termination, don't consider the