unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Michael Albinus <michael.albinus@gmx.de>
To: Roland Winkler <winkler@gnu.org>
Cc: Filipp Gunbin <fgunbin@fastmail.fm>, emacs-devel@gnu.org
Subject: Re: process-file instead of call-process in proced.el?
Date: Sun, 27 Mar 2022 16:08:15 +0200	[thread overview]
Message-ID: <87tubjfpyo.fsf@gmx.de> (raw)
In-Reply-To: <87bkxrhn1e.fsf@gmx.de> (Michael Albinus's message of "Sun, 27 Mar 2022 09:28:29 +0200")

[-- Attachment #1: Type: text/plain, Size: 927 bytes --]

Michael Albinus <michael.albinus@gmx.de> writes:

Hi,

> I see. So if we don't want to emulate list-system-processes on a remote
> host, we need another mean to determine, that a process is killed in a
> sudo environment.

I've prepared a first version of a patch (still missing documentation),
see appended. The changes are:

- `signal-process' is capable now to signal remote processes. This is
  triggered when either the PROCESS object has the property `remote-pid'
  (set by Tramp), or the PROCESS is just a number, and the additional
  optional parameter REMOTE is a remote file name.

- There is a new user option `proced-remote-directory', which defaults
  to "/sudo::". When `proced-send-signal' or `proced-renice' are invoked
  with a prefix arg ("C-u k" or "C-u r" in the *Proced* buffer), the
  respective signal is sent with the credentials as identified by this
  user option.

Comments?

Best regards, Michael.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 11026 bytes --]

diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 0192a63a10..ff42a22765 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -5957,6 +5957,43 @@ tramp-interrupt-process
  (lambda ()
    (remove-hook 'interrupt-process-functions #'tramp-interrupt-process)))

+(defun tramp-signal-process (process sigcode &optional remote)
+  "Send PROCESS the signal with code SIGCODE.
+PROCESS may also be a number specifying the process id of the
+process to signal; in this case, the process need not be a child of
+this Emacs.  Furthermore, if REMOTE is a remote file name, this
+number is interpreted as process id on the respective remote
+host, which will be the process to signal.
+SIGCODE may be an integer, or a symbol whose name is a signal name."
+  (let (pid vec)
+    (cond
+     ((processp process)
+      (setq pid (process-get process 'remote-pid)
+            vec (process-get process 'vector)))
+     ((numberp process)
+      (setq pid process
+            vec (and (stringp remote) (tramp-dissect-file-name remote))))
+     (t (signal 'wrong-type-argument (list #'processp process))))
+    (unless (or (numberp sigcode) (symbolp sigcode))
+      (signal 'wrong-type-argument (list #'numberp sigcode)))
+    ;; If it's a Tramp process, send SIGCODE remotely.
+    (when (and pid vec)
+      (tramp-message
+       vec 5 "Send signal %s to process %s with pid %s" sigcode process pid)
+      ;; This is for tramp-sh.el.  Other backends do not support this (yet).
+      (if (tramp-compat-funcall
+           'tramp-send-command-and-check
+           vec (format "\\kill -%s %d" sigcode pid))
+          0 -1))))
+
+;; `signal-process-functions' exists since Emacs 29.1.
+(when (boundp 'signal-process-functions)
+  (add-hook 'signal-process-functions #'tramp-signal-process)
+  (add-hook
+   'tramp-unload-hook
+   (lambda ()
+     (remove-hook 'signal-process-functions #'tramp-signal-process))))
+
 (defun tramp-get-remote-null-device (vec)
   "Return null device on the remote host identified by VEC.
 If VEC is `tramp-null-hop', return local null device."
diff --git a/lisp/proced.el b/lisp/proced.el
index c1d599afc4..7966ccfb08 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -29,10 +29,6 @@
 ;;
 ;; To do:
 ;; - Interactive temporary customizability of flags in `proced-grammar-alist'
-;; - Allow "sudo kill PID", "sudo renice PID"
-;;   `proced-send-signal' operates on multiple processes one by one.
-;;   With "sudo" we want to execute one "kill" or "renice" command
-;;   for all marked processes.  Is there a `sudo-call-process'?
 ;;
 ;; Thoughts and Ideas
 ;; - Currently, `process-attributes' returns the list of
@@ -61,6 +57,14 @@ proced-signal-function
 the external command (usually \"kill\")."
   :type '(choice (function :tag "function")
                  (string :tag "command")))
+(make-obsolete-variable 'proced-signal-function "no longer used." "29.1")
+
+(defcustom proced-remote-directory "/sudo::"
+  "Remote directory to be used when sending a signal.
+It must point to the local host, via a `sudo' or `doas' method,
+or alike.  See `proced-send-signal' and `proced-renice'."
+  :version "29.1"
+  :type '(string :tag "remote directory"))

 (defcustom proced-renice-command "renice"
   "Name of renice command."
@@ -626,6 +630,9 @@ proced-mode
 Type \\[proced] to start a Proced session.  In a Proced buffer
 type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands.
 Type \\[proced-send-signal] to send signals to marked processes.
+Type \\[proced-renice] to renice marked processes.
+With a prefix argument \\[universal-argument], sending signals to and renicing of processes
+will be performed with the credentials of `proced-remote-directory'.

 The initial content of a listing is defined by the variable `proced-filter'
 and the variable `proced-format'.
@@ -1766,7 +1773,10 @@ proced-send-signal
 For backward compatibility SIGNAL and PROCESS-ALIST may be nil.
 Then PROCESS-ALIST contains the marked processes or the process point is on
 and SIGNAL is queried interactively.  This noninteractive usage is still
-supported but discouraged.  It will be removed in a future version of Emacs."
+supported but discouraged.  It will be removed in a future version of Emacs.
+
+With a prefix argument \\[universal-argument], send the signal with the credentials of
+`proced-remote-directory'."
   (interactive
    (let* ((process-alist (proced-marked-processes))
           (pnum (if (= 1 (length process-alist))
@@ -1808,7 +1818,10 @@ proced-send-signal
                                         proced-signal-list
                                         nil nil nil nil "TERM"))))))

-  (let (failures)
+  (let ((default-directory
+         (if (and current-prefix-arg (stringp proced-remote-directory))
+             proced-remote-directory temporary-file-directory))
+        failures)
     ;; Why not always use `signal-process'?  See
     ;; https://lists.gnu.org/r/emacs-devel/2008-03/msg02955.html
     (if (functionp proced-signal-function)
@@ -1821,7 +1834,8 @@ proced-send-signal
           (dolist (process process-alist)
             (condition-case err
                 (unless (zerop (funcall
-                                proced-signal-function (car process) signal))
+                                proced-signal-function (car process) signal
+                                (file-remote-p default-directory)))
                   (proced-log "%s\n" (cdr process))
                   (push (cdr process) failures))
               (error ; catch errors from failed signals
@@ -1833,7 +1847,7 @@ proced-send-signal
         (dolist (process process-alist)
           (with-temp-buffer
             (condition-case nil
-                (unless (zerop (call-process
+                (unless (zerop (process-file
                                 proced-signal-function nil t nil
                                 signal (number-to-string (car process))))
                   (proced-log (current-buffer))
@@ -1862,7 +1876,10 @@ proced-renice
 Interactively, PROCESS-ALIST contains the marked processes.
 If no process is marked, it contains the process point is on,
 After renicing all processes in PROCESS-ALIST, this command runs
-the normal hook `proced-after-send-signal-hook'."
+the normal hook `proced-after-send-signal-hook'.
+
+With a prefix argument \\[universal-argument], apply renice with the credentials of
+`proced-remote-directory'."
   (interactive
    (let ((process-alist (proced-marked-processes)))
      (proced-with-processes-buffer process-alist
@@ -1871,11 +1888,14 @@ proced-renice
    proced-mode)
   (if (numberp priority)
       (setq priority (number-to-string priority)))
-  (let (failures)
+  (let ((default-directory
+         (if (and current-prefix-arg (stringp proced-remote-directory))
+             proced-remote-directory temporary-file-directory))
+        failures)
     (dolist (process process-alist)
       (with-temp-buffer
         (condition-case nil
-            (unless (zerop (call-process
+            (unless (zerop (process-file
                             proced-renice-command nil t nil
                             priority (number-to-string (car process))))
               (proced-log (current-buffer))
diff --git a/src/process.c b/src/process.c
index 993e1c5603..fcff9c71ac 100644
--- a/src/process.c
+++ b/src/process.c
@@ -7034,14 +7034,13 @@ abbr_to_signal (char const *name)
   return -1;
 }

-DEFUN ("signal-process", Fsignal_process, Ssignal_process,
-       2, 2, "sProcess (name or number): \nnSignal code: ",
-       doc: /* Send PROCESS the signal with code SIGCODE.
-PROCESS may also be a number specifying the process id of the
-process to signal; in this case, the process need not be a child of
-this Emacs.
-SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
-  (Lisp_Object process, Lisp_Object sigcode)
+DEFUN ("internal-default-signal-process",
+       Finternal_default_signal_process,
+       Sinternal_default_signal_process, 2, 3, 0,
+       doc: /* Default function to send PROCESS the signal with code SIGCODE.
+It shall be the last element in list `signal-process-functions'.
+See function `signal-process' for more details on usage.  */)
+  (Lisp_Object process, Lisp_Object sigcode, Lisp_Object remote)
 {
   pid_t pid;
   int signo;
@@ -7091,6 +7090,21 @@ DEFUN ("signal-process", Fsignal_process, Ssignal_process,
   return make_fixnum (kill (pid, signo));
 }

+DEFUN ("signal-process", Fsignal_process, Ssignal_process,
+       2, 3, "sProcess (name or number): \nnSignal code: ",
+       doc: /* Send PROCESS the signal with code SIGCODE.
+PROCESS may also be a number specifying the process id of the
+process to signal; in this case, the process need not be a child of
+this Emacs.  Furthermore, if REMOTE is a remote file name, this
+number is interpreted as process id on the respective remote
+host, which will be the process to signal.
+SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
+  (Lisp_Object process, Lisp_Object sigcode, Lisp_Object remote)
+{
+  return CALLN (Frun_hook_with_args_until_success, Qsignal_process_functions,
+		process, sigcode, remote);
+}
+
 DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
        doc: /* Make PROCESS see end-of-file in its input.
 EOF comes after any text already sent to it.
@@ -8580,6 +8594,13 @@ syms_of_process (void)
 returns non-nil.  */);
   Vinterrupt_process_functions = list1 (Qinternal_default_interrupt_process);

+  DEFVAR_LISP ("signal-process-functions", Vsignal_process_functions,
+	       doc: /* List of functions to be called for `signal-process'.
+The arguments of the functions are the same as for `signal-process'.
+These functions are called in the order of the list, until one of them
+returns non-nil.  */);
+  Vsignal_process_functions = list1 (Qinternal_default_signal_process);
+
   DEFVAR_LISP ("internal--daemon-sockname", Vinternal__daemon_sockname,
 	       doc: /* Name of external socket passed to Emacs, or nil if none.  */);
   Vinternal__daemon_sockname = Qnil;
@@ -8600,6 +8621,10 @@ syms_of_process (void)
 	  "internal-default-interrupt-process");
   DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions");

+  DEFSYM (Qinternal_default_signal_process,
+	  "internal-default-signal-process");
+  DEFSYM (Qsignal_process_functions, "signal-process-functions");
+
   DEFSYM (Qnull, "null");
   DEFSYM (Qpipe_process_p, "pipe-process-p");

@@ -8654,6 +8679,7 @@ syms_of_process (void)
   defsubr (&Scontinue_process);
   defsubr (&Sprocess_running_child_p);
   defsubr (&Sprocess_send_eof);
+  defsubr (&Sinternal_default_signal_process);
   defsubr (&Ssignal_process);
   defsubr (&Swaiting_for_user_input_p);
   defsubr (&Sprocess_type);

  reply	other threads:[~2022-03-27 14:08 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-25  0:09 process-file instead of call-process in proced.el? Filipp Gunbin
2022-03-25  6:54 ` Eli Zaretskii
2022-03-25 10:24   ` Filipp Gunbin
2022-03-25 10:31     ` Eli Zaretskii
2022-03-25 11:46       ` Michael Albinus
2022-03-25 12:12         ` Eli Zaretskii
2022-03-25 12:29           ` Filipp Gunbin
2022-03-25 13:34             ` Roland Winkler
2022-03-25 13:58             ` Michael Albinus
2022-03-25 14:26               ` Filipp Gunbin
2022-03-25 14:29                 ` Michael Albinus
2022-03-25 15:40                   ` Filipp Gunbin
2022-03-25 15:43                     ` Michael Albinus
2022-03-26 16:49 ` Michael Albinus
2022-03-26 17:37   ` Roland Winkler
2022-03-26 18:31     ` Michael Albinus
2022-03-26 18:49       ` Roland Winkler
2022-03-27  7:28         ` Michael Albinus
2022-03-27 14:08           ` Michael Albinus [this message]
2022-03-28  2:57             ` Roland Winkler
2022-03-28  7:41               ` Michael Albinus
2022-03-28 14:34                 ` Roland Winkler
2022-03-28 14:53             ` Filipp Gunbin
2022-03-28 15:40               ` Michael Albinus
2022-03-28 16:11                 ` Filipp Gunbin
2022-03-28 16:39                   ` Michael Albinus
2022-03-28 19:42                     ` Filipp Gunbin
2022-03-30 11:20                       ` Michael Albinus
2022-03-30 15:34                         ` Filipp Gunbin
2022-03-28 17:08             ` Jim Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tubjfpyo.fsf@gmx.de \
    --to=michael.albinus@gmx.de \
    --cc=emacs-devel@gnu.org \
    --cc=fgunbin@fastmail.fm \
    --cc=winkler@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).