]> git.eshelyaron.com Git - emacs.git/commitdiff
Fixes for pty handling in gdb-mi.el and process.c.
authorChong Yidong <cyd@gnu.org>
Fri, 20 Apr 2012 06:39:29 +0000 (14:39 +0800)
committerChong Yidong <cyd@gnu.org>
Fri, 20 Apr 2012 06:39:29 +0000 (14:39 +0800)
* 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.

doc/lispref/ChangeLog
doc/lispref/processes.texi
lisp/ChangeLog
lisp/progmodes/gdb-mi.el
src/ChangeLog
src/process.c

index 167539aa450981bd1fcf2834983fbe8023a1cd9b..fe555c0458ccd0c8fd1983dcb1c612044d1ec6e5 100644 (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.
index cd5647f18436de1bd57b02d8dbdfaba59d998a59..6275ce0b1b78036368e232588513eac7006d82e0 100644 (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
index ec008022e0e71306316ec4b604ed5a7cc95ad63d..601e4f4f59fa6685a210f8baddeffe8a2349049a 100644 (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)
index 450075fde42d58c09f98ffc3a04025091c9b02b6..455727f9e02167831fb049d0969fa65a504bbe70 100644 (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
index 00d257e69843c9d58a081d9e54bf9ea8545306ee..18b6ce1ad64865a2e5fceb866fd704b54840b6e1 100644 (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)
index 3ee22d270e973cd75bc93263ac9810a0fe1809f9..f6f1ad0a6fb8a060b2c6481cef7f9fb6c25ee6ce 100644 (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