emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/emacs-24 r107864: Fixes for pty handling in


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/emacs-24 r107864: Fixes for pty handling in gdb-mi.el and process.c.
Date: Fri, 20 Apr 2012 14:39:29 +0800
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 107864
committer: Chong Yidong <address@hidden>
branch nick: emacs-24
timestamp: Fri 2012-04-20 14:39:29 +0800
message:
  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.
modified:
  doc/lispref/ChangeLog
  doc/lispref/processes.texi
  lisp/ChangeLog
  lisp/progmodes/gdb-mi.el
  src/ChangeLog
  src/process.c
=== modified file 'doc/lispref/ChangeLog'
--- a/doc/lispref/ChangeLog     2012-04-20 01:37:14 +0000
+++ b/doc/lispref/ChangeLog     2012-04-20 06:39:29 +0000
@@ -1,3 +1,8 @@
+2012-04-20  Chong Yidong  <address@hidden>
+
+       * processes.texi (Asynchronous Processes): Mention nil argument to
+       start-process.
+
 2012-04-20  Glenn Morris  <address@hidden>
 
        * minibuf.texi (Basic Completion): No need to describe obarrays here.

=== modified file 'doc/lispref/processes.texi'
--- a/doc/lispref/processes.texi        2012-04-18 07:21:18 +0000
+++ b/doc/lispref/processes.texi        2012-04-20 06:39:29 +0000
@@ -559,8 +559,13 @@
 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
address@hidden 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

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-04-20 06:28:32 +0000
+++ b/lisp/ChangeLog    2012-04-20 06:39:29 +0000
@@ -1,3 +1,15 @@
+2012-04-20  Chong Yidong  <address@hidden>
+
+       * 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  <address@hidden>
 
        * window.el (window-min-size, window-sizable, window-min-delta)

=== modified file 'lisp/progmodes/gdb-mi.el'
--- a/lisp/progmodes/gdb-mi.el  2012-04-19 08:09:30 +0000
+++ b/lisp/progmodes/gdb-mi.el  2012-04-20 06:39:29 +0000
@@ -817,10 +817,7 @@
             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 @@
 
   (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 @@
     (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 @@
       (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 @@
     (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 @@
   (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 @@
 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

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-04-18 07:21:18 +0000
+++ b/src/ChangeLog     2012-04-20 06:39:29 +0000
@@ -1,3 +1,8 @@
+2012-04-20  Chong Yidong  <address@hidden>
+
+       * 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  <address@hidden>
 
        * process.c (Fset_process_inherit_coding_system_flag)

=== modified file 'src/process.c'
--- a/src/process.c     2012-04-18 07:21:18 +0000
+++ b/src/process.c     2012-04-20 06:39:29 +0000
@@ -4893,16 +4893,23 @@
                 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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]