diff options
| author | Michael Albinus | 2017-08-21 17:30:33 +0200 |
|---|---|---|
| committer | Michael Albinus | 2017-08-21 17:30:33 +0200 |
| commit | 01844e40dc43baf1fdc088ef6400343e908ea449 (patch) | |
| tree | 65ffb9b54340522908591de90a01f402b6226b8d | |
| parent | 76fbe2f4541b11af8bcb0b5e57bb155b796b8d8e (diff) | |
| download | emacs-01844e40dc43baf1fdc088ef6400343e908ea449.tar.gz emacs-01844e40dc43baf1fdc088ef6400343e908ea449.zip | |
Implement `interrupt-process-functions'
* lisp/net/tramp.el (tramp-interrupt-process): Rename from
`tramp-advice-interrupt-process'. Adapt according to changed API.
(top): Add it to `interrupt-process-functions'.
* src/process.c (Finternal_default_interrupt_process): New defun.
(Finterrupt_process): Change implementation, based on
Vinterrupt_process_functions.
(Vinterrupt_process_functions): New defvar.
* test/lisp/net/tramp-tests.el (tramp-test40-unload): Do not
test removal of advice.
| -rw-r--r-- | lisp/net/tramp.el | 53 | ||||
| -rw-r--r-- | src/process.c | 33 | ||||
| -rw-r--r-- | test/lisp/net/tramp-tests.el | 5 |
3 files changed, 59 insertions, 32 deletions
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 3469d45ff2a..2aa9a6b9859 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -4381,33 +4381,36 @@ Only works for Bourne-like shells." | |||
| 4381 | ;;; Signal handling. This works for remote processes, which have set | 4381 | ;;; Signal handling. This works for remote processes, which have set |
| 4382 | ;;; the process property `remote-pid'. | 4382 | ;;; the process property `remote-pid'. |
| 4383 | 4383 | ||
| 4384 | (defun tramp-advice-interrupt-process (orig-fun &rest args) | 4384 | (defun tramp-interrupt-process (&optional process _current-group) |
| 4385 | "Interrupt remote process PROC." | 4385 | "Interrupt remote process PROC." |
| 4386 | (let* ((arg0 (car args)) | 4386 | ;; CURRENT-GROUP is not implemented yet. |
| 4387 | (proc (cond | 4387 | (let ((proc (cond |
| 4388 | ((processp arg0) arg0) | 4388 | ((processp process) process) |
| 4389 | ((bufferp arg0) (get-buffer-process arg0)) | 4389 | ((bufferp process) (get-buffer-process process)) |
| 4390 | ((stringp arg0) (or (get-process arg0) | 4390 | ((stringp process) (or (get-process process) |
| 4391 | (get-buffer-process arg0))) | 4391 | (get-buffer-process process))) |
| 4392 | ((null arg0) (get-buffer-process (current-buffer))) | 4392 | ((null process) (get-buffer-process (current-buffer))) |
| 4393 | (t arg0))) | 4393 | (t process))) |
| 4394 | pid) | 4394 | pid) |
| 4395 | ;; If it's a Tramp process, send the INT signal remotely. | 4395 | ;; If it's a Tramp process, send the INT signal remotely. |
| 4396 | (if (and (processp proc) | 4396 | (when (and (processp proc) |
| 4397 | (setq pid (process-get proc 'remote-pid))) | 4397 | (setq pid (process-get proc 'remote-pid))) |
| 4398 | (progn | 4398 | (tramp-message proc 5 "Interrupt process %s with pid %s" proc pid) |
| 4399 | (tramp-message proc 5 "%s %s" proc pid) | 4399 | ;; This is for tramp-sh.el. Other backends do not support this (yet). |
| 4400 | (tramp-send-command | 4400 | (tramp-compat-funcall |
| 4401 | (tramp-get-connection-property proc "vector" nil) | 4401 | 'tramp-send-command |
| 4402 | (format "kill -2 %d" pid))) | 4402 | (tramp-get-connection-property proc "vector" nil) |
| 4403 | ;; Otherwise, just run the original function. | 4403 | (format "kill -2 %d" pid)) |
| 4404 | (apply orig-fun args)))) | 4404 | ;; Report success. |
| 4405 | 4405 | proc))) | |
| 4406 | (advice-add 'interrupt-process :around 'tramp-advice-interrupt-process) | 4406 | |
| 4407 | (add-hook | 4407 | ;; `interrupt-process-functions' exists since Emacs 26.1. |
| 4408 | 'tramp-unload-hook | 4408 | (when (boundp 'interrupt-process-functions) |
| 4409 | (lambda () | 4409 | (add-hook 'interrupt-process-functions 'tramp-interrupt-process) |
| 4410 | (advice-remove 'interrupt-process 'tramp-advice-interrupt-process))) | 4410 | (add-hook |
| 4411 | 'tramp-unload-hook | ||
| 4412 | (lambda () | ||
| 4413 | (remove-hook 'interrupt-process-functions 'tramp-interrupt-process)))) | ||
| 4411 | 4414 | ||
| 4412 | ;;; Integration of eshell.el: | 4415 | ;;; Integration of eshell.el: |
| 4413 | 4416 | ||
diff --git a/src/process.c b/src/process.c index 19009515336..e7ee99ab3d9 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -6677,6 +6677,18 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 6677 | unblock_child_signal (&oldset); | 6677 | unblock_child_signal (&oldset); |
| 6678 | } | 6678 | } |
| 6679 | 6679 | ||
| 6680 | DEFUN ("internal-default-interrupt-process", | ||
| 6681 | Finternal_default_interrupt_process, | ||
| 6682 | Sinternal_default_interrupt_process, 0, 2, 0, | ||
| 6683 | doc: /* Default function to interrupt process PROCESS. | ||
| 6684 | It shall be the last element in list `interrupt-process-functions'. | ||
| 6685 | See function `interrupt-process' for more details on usage. */) | ||
| 6686 | (Lisp_Object process, Lisp_Object current_group) | ||
| 6687 | { | ||
| 6688 | process_send_signal (process, SIGINT, current_group, 0); | ||
| 6689 | return process; | ||
| 6690 | } | ||
| 6691 | |||
| 6680 | DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, | 6692 | DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, |
| 6681 | doc: /* Interrupt process PROCESS. | 6693 | doc: /* Interrupt process PROCESS. |
| 6682 | PROCESS may be a process, a buffer, or the name of a process or buffer. | 6694 | PROCESS may be a process, a buffer, or the name of a process or buffer. |
| @@ -6688,11 +6700,14 @@ If the process is a shell, this means interrupt current subjob | |||
| 6688 | rather than the shell. | 6700 | rather than the shell. |
| 6689 | 6701 | ||
| 6690 | If CURRENT-GROUP is `lambda', and if the shell owns the terminal, | 6702 | If CURRENT-GROUP is `lambda', and if the shell owns the terminal, |
| 6691 | don't send the signal. */) | 6703 | don't send the signal. |
| 6704 | |||
| 6705 | This function calls the functions of `interrupt-process-functions' in | ||
| 6706 | the order of the list, until one of them returns non-`nil'. */) | ||
| 6692 | (Lisp_Object process, Lisp_Object current_group) | 6707 | (Lisp_Object process, Lisp_Object current_group) |
| 6693 | { | 6708 | { |
| 6694 | process_send_signal (process, SIGINT, current_group, 0); | 6709 | return CALLN (Frun_hook_with_args_until_success, Qinterrupt_process_functions, |
| 6695 | return process; | 6710 | process, current_group); |
| 6696 | } | 6711 | } |
| 6697 | 6712 | ||
| 6698 | DEFUN ("kill-process", Fkill_process, Skill_process, 0, 2, 0, | 6713 | DEFUN ("kill-process", Fkill_process, Skill_process, 0, 2, 0, |
| @@ -8176,6 +8191,17 @@ non-nil value means that the delay is not reset on write. | |||
| 8176 | The variable takes effect when `start-process' is called. */); | 8191 | The variable takes effect when `start-process' is called. */); |
| 8177 | Vprocess_adaptive_read_buffering = Qt; | 8192 | Vprocess_adaptive_read_buffering = Qt; |
| 8178 | 8193 | ||
| 8194 | DEFVAR_LISP ("interrupt-process-functions", Vinterrupt_process_functions, | ||
| 8195 | doc: /* List of functions to be called for `interrupt-function'. | ||
| 8196 | The arguments of the functions are the same as for `interrupt-function'. | ||
| 8197 | These functions are called in the order of the list, until one of them | ||
| 8198 | returns non-`nil'. */); | ||
| 8199 | Vinterrupt_process_functions = list1 (Qinternal_default_interrupt_process); | ||
| 8200 | |||
| 8201 | DEFSYM (Qinternal_default_interrupt_process, | ||
| 8202 | "internal-default-interrupt-process"); | ||
| 8203 | DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions"); | ||
| 8204 | |||
| 8179 | defsubr (&Sprocessp); | 8205 | defsubr (&Sprocessp); |
| 8180 | defsubr (&Sget_process); | 8206 | defsubr (&Sget_process); |
| 8181 | defsubr (&Sdelete_process); | 8207 | defsubr (&Sdelete_process); |
| @@ -8218,6 +8244,7 @@ The variable takes effect when `start-process' is called. */); | |||
| 8218 | defsubr (&Saccept_process_output); | 8244 | defsubr (&Saccept_process_output); |
| 8219 | defsubr (&Sprocess_send_region); | 8245 | defsubr (&Sprocess_send_region); |
| 8220 | defsubr (&Sprocess_send_string); | 8246 | defsubr (&Sprocess_send_string); |
| 8247 | defsubr (&Sinternal_default_interrupt_process); | ||
| 8221 | defsubr (&Sinterrupt_process); | 8248 | defsubr (&Sinterrupt_process); |
| 8222 | defsubr (&Skill_process); | 8249 | defsubr (&Skill_process); |
| 8223 | defsubr (&Squit_process); | 8250 | defsubr (&Squit_process); |
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index dba553a2c5e..129bc1d65da 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el | |||
| @@ -4072,10 +4072,7 @@ Since it unloads Tramp, it shall be the last test to run." | |||
| 4072 | (not (string-match "unload-hook$" (symbol-name x))) | 4072 | (not (string-match "unload-hook$" (symbol-name x))) |
| 4073 | (consp (symbol-value x)) | 4073 | (consp (symbol-value x)) |
| 4074 | (ignore-errors (all-completions "tramp" (symbol-value x))) | 4074 | (ignore-errors (all-completions "tramp" (symbol-value x))) |
| 4075 | (ert-fail (format "Hook `%s' still contains Tramp function" x))))) | 4075 | (ert-fail (format "Hook `%s' still contains Tramp function" x))))))) |
| 4076 | ;; The advice on `interrupt-process' shall be removed. | ||
| 4077 | (should-not | ||
| 4078 | (advice-member-p 'tramp-advice-interrupt-process 'interrupt-process)))) | ||
| 4079 | 4076 | ||
| 4080 | ;; TODO: | 4077 | ;; TODO: |
| 4081 | 4078 | ||