unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Michael Albinus <michael.albinus@gmx.de>
Cc: 60722@debbugs.gnu.org
Subject: bug#60722: 30.0.50; [PATCH] Using Tramp to sudo in Eshell doesn't change prompt sigil
Date: Sat, 14 Jan 2023 14:10:27 -0800	[thread overview]
Message-ID: <f388bbc3-f01f-d667-6260-1820f6bb4881@gmail.com> (raw)
In-Reply-To: <0ecbefc7-ea79-d172-5e84-58368870b818@gmail.com>

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

On 1/14/2023 1:59 PM, Jim Porter wrote:
> Finally, I added documentation to the manuals. I didn't add any Tramp 
> regression tests though, since I wasn't sure of the right way to test this.

Oops. I missed an "@end defun" in the manual. Fixed.

[-- Attachment #2: 0001-Add-user-uid-for-file-to-get-the-effective-UID-for-r.patch --]
[-- Type: text/plain, Size: 15100 bytes --]

From d66131038f3a013e87fd3079fe62082ece6d91a2 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Tue, 10 Jan 2023 15:35:18 -0800
Subject: [PATCH] Add 'user-uid-for-file' to get the effective UID for remote
 files

In particular, this lets Eshell show a "#" root prompt sigil when the
user has sudo'ed via "cd /sudo::" (bug#60722).

* lisp/simple.el (user-uid-for-file): New function.

* lisp/net/tramp.el (tramp-file-name-for-operation): Add
'user-uid-for-file'.
(tramp-handle-user-uid-for-file): New function.

* lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
* lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
* lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
* lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
* lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
* lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
* lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
Add 'user-uid-for-file'.

* lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
Add comment about 'user-uid-for-file'.

* lisp/eshell/em-prompt.el (eshell-prompt-function): Use
'user-uid-for-file'.

* lisp/eshell/esh-var.el (eshell-variable-aliases-list): Add '$UID'.

* test/lisp/eshell/esh-var-tests.el (esh-var-test/uid-var): New test.

* doc/lispref/os.texi (User Identification): Document
'user-uid-for-file'.

* doc/lispref/files.texi (Magic File Names): Mention
'user-uid-for-file'.

* doc/misc/eshell.texi (Variables): Document '$UID'.  Add a missing
index entry for '$INSIDE_EMACS'.

* etc/NEWS: Announce 'user-uid-for-file'.
---
 doc/lispref/files.texi            |  2 ++
 doc/lispref/os.texi               | 10 ++++++++++
 doc/misc/eshell.texi              |  8 ++++++++
 etc/NEWS                          |  5 +++++
 lisp/eshell/em-prompt.el          |  2 +-
 lisp/eshell/esh-var.el            |  1 +
 lisp/net/tramp-adb.el             |  1 +
 lisp/net/tramp-archive.el         |  5 +++++
 lisp/net/tramp-crypt.el           |  1 +
 lisp/net/tramp-gvfs.el            |  1 +
 lisp/net/tramp-rclone.el          |  1 +
 lisp/net/tramp-sh.el              |  1 +
 lisp/net/tramp-smb.el             |  1 +
 lisp/net/tramp-sshfs.el           |  1 +
 lisp/net/tramp-sudoedit.el        |  1 +
 lisp/net/tramp.el                 | 10 ++++++++++
 lisp/simple.el                    | 10 ++++++++++
 test/lisp/eshell/esh-var-tests.el |  4 ++++
 18 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 5cc4c1e7ddf..7201bcc9c2c 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -3412,6 +3412,7 @@ Magic File Names
 @code{temporary-file-directory},
 @code{unhandled-file-name-directory},
 @code{unlock-file},
+@code{user-uid-for-file},
 @code{vc-registered},
 @code{verify-visited-file-modtime},@*
 @code{write-region}.
@@ -3473,6 +3474,7 @@ Magic File Names
 @code{temporary-file-directory},
 @code{unhandled-file-name-directory},
 @code{unlock-file},
+@code{user-uid-for-file},
 @code{vc-regis@discretionary{}{}{}tered},
 @code{verify-visited-file-modtime},
 @code{write-region}.
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 3be7036f637..9e76fbd2fbb 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1277,6 +1277,16 @@ User Identification
 This function returns the effective @acronym{UID} of the user.
 @end defun
 
+@defun user-uid-for-file filename
+This function returns the effective @acronym{UID} of the user
+associated with the file named @var{filename}.  If @var{filename} is
+local, this is equivalent to @code{user-uid}, but for remote files
+(@pxref{Remote Files, , , emacs, The GNU Emacs Manual}), it will
+return the @acronym{UID} for the user associated with that remote
+connection; if the remote connection has no associated user, it will
+instead return -1.
+@end defun
+
 @cindex GID
 @defun group-gid
 This function returns the effective @acronym{GID} of the Emacs process.
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index fc7d52eb711..c40ff58f42c 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -983,6 +983,13 @@ Variables
 the value will automatically update to reflect the search path on that
 host.
 
+@vindex $UID
+@item $UID
+This returns the effective @acronym{UID} for the current user.  This
+variable is connection-aware, so when the current directory is remote,
+its value will be @acronym{UID} for the user associated with that
+remote connection.
+
 @vindex $_
 @item $_
 This refers to the last argument of the last command.  With a
@@ -1014,6 +1021,7 @@ Variables
 copied to the environment, so external commands invoked from
 Eshell can consult them to do the right thing.
 
+@vindex $INSIDE_EMACS
 @item $INSIDE_EMACS
 This variable indicates to external commands that they are being
 invoked from within Emacs so they can adjust their behavior if
diff --git a/etc/NEWS b/etc/NEWS
index 068f7a27db8..8a190600d44 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -235,6 +235,11 @@ compared reliably at all.
 This warning can be suppressed using 'with-suppressed-warnings' with
 the warning name 'suspicious'.
 
++++
+** New function 'user-uid-for-file'.
+This function is like 'user-uid', but is aware of file name handlers,
+so it will return the remote UID for remote files.
+
 \f
 * Changes in Emacs 30.1 on Non-Free Operating Systems
 
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index 52d46282c52..36b6c5e0a1b 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -52,7 +52,7 @@ eshell-prompt-load-hook
 (defcustom eshell-prompt-function
   (lambda ()
     (concat (abbreviate-file-name (eshell/pwd))
-            (if (= (user-uid) 0) " # " " $ ")))
+            (if (= (user-uid-for-file default-directory) 0) " # " " $ ")))
   "A function that returns the Eshell prompt string.
 Make sure to update `eshell-prompt-regexp' so that it will match your
 prompt."
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index 811bb9957cf..ac48fd01bec 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -162,6 +162,7 @@ eshell-variable-aliases-list
     ("COLUMNS" ,(lambda () (window-body-width nil 'remap)) t t)
     ("LINES" ,(lambda () (window-body-height nil 'remap)) t t)
     ("INSIDE_EMACS" eshell-inside-emacs t)
+    ("UID" ,(lambda () (user-uid-for-file default-directory)) nil t)
 
     ;; for esh-ext.el
     ("PATH" (,(lambda () (string-join (eshell-get-path t) (path-separator)))
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 493a9fb39a9..6a473d03e9f 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -188,6 +188,7 @@ tramp-adb-file-name-handler-alist
     (tramp-set-file-uid-gid . ignore)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-adb-handle-write-region))
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index a2add1ed73a..e1f7a060783 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -300,6 +300,7 @@ tramp-archive-file-name-handler-alist
     (tramp-set-file-uid-gid . ignore)
     (unhandled-file-name-directory . ignore)
     (unlock-file . ignore)
+    (user-uid-for-file . tramp-archive-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-archive-handle-not-implemented))
@@ -701,6 +702,10 @@ tramp-archive-handle-temporary-file-directory
     (let ((default-directory (file-name-directory archive)))
       (temporary-file-directory))))
 
+(defun tramp-archive-handle-user-uid-for-file (filename)
+  "Like `user-uid-for-file' for file archives."
+  (user-uid-for-file (tramp-archive-gvfs-file-name filename)))
+
 (defun tramp-archive-handle-not-implemented (operation &rest args)
   "Generic handler for operations not implemented for file archives."
   (let ((v (ignore-errors
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index 507fd432419..d2e4805a737 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -239,6 +239,7 @@ tramp-crypt-file-name-handler-alist
     (tramp-set-file-uid-gid . tramp-crypt-handle-set-file-uid-gid)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-crypt-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-handle-write-region))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index cca7a5fe247..66e5313e516 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -833,6 +833,7 @@ tramp-gvfs-file-name-handler-alist
     (tramp-set-file-uid-gid . tramp-gvfs-handle-set-file-uid-gid)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-handle-write-region))
diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el
index 4018fa3aa29..2d25668b3ac 100644
--- a/lisp/net/tramp-rclone.el
+++ b/lisp/net/tramp-rclone.el
@@ -153,6 +153,7 @@ tramp-rclone-file-name-handler-alist
     (tramp-set-file-uid-gid . ignore)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-handle-write-region))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 4647600071c..c812300babf 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1121,6 +1121,7 @@ tramp-sh-file-name-handler-alist
     (tramp-set-file-uid-gid . tramp-sh-handle-set-file-uid-gid)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . tramp-sh-handle-vc-registered)
     (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
     (write-region . tramp-sh-handle-write-region))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index d6f3cca9733..240a4523e36 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -304,6 +304,7 @@ tramp-smb-file-name-handler-alist
     (tramp-set-file-uid-gid . ignore)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-smb-handle-write-region))
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index 27b2854e451..b81e84a213d 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -159,6 +159,7 @@ tramp-sshfs-file-name-handler-alist
     (tramp-set-file-uid-gid . ignore)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-sshfs-handle-write-region))
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 2660dbb1fac..c115b17f98f 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -149,6 +149,7 @@ tramp-sudoedit-file-name-handler-alist
     (tramp-set-file-uid-gid . tramp-sudoedit-handle-set-file-uid-gid)
     (unhandled-file-name-directory . ignore)
     (unlock-file . tramp-handle-unlock-file)
+    (user-uid-for-file . tramp-handle-user-uid-for-file)
     (vc-registered . ignore)
     (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
     (write-region . tramp-handle-write-region))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index b8475b7cb48..5be0347ff25 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2589,6 +2589,8 @@ tramp-file-name-for-operation
 	      file-locked-p lock-file make-lock-file-name unlock-file
 	      ;; Emacs 29+ only.
 	      abbreviate-file-name
+	      ;; Emacs 30+ only.
+	      user-uid-for-file
 	      ;; Tramp internal magic file name function.
 	      tramp-set-file-uid-gid))
     (if (file-name-absolute-p (nth 0 args))
@@ -3710,6 +3712,14 @@ tramp-handle-abbreviate-file-name
 	 vec (concat "~" (substring filename (match-beginning 1))))
       (tramp-make-tramp-file-name (tramp-dissect-file-name filename)))))
 
+(defun tramp-handle-user-uid-for-file (filename)
+  "Like `user-uid' for Tramp files."
+  (or (tramp-get-remote-uid (tramp-dissect-file-name filename) 'integer)
+      ;; Some handlers for `tramp-get-remote-uid' return nil if they
+      ;; can't get the UID; always return -1 in this case for
+      ;; consistency.
+      -1))
+
 (defun tramp-handle-access-file (filename string)
   "Like `access-file' for Tramp files."
   (setq filename (file-truename filename))
diff --git a/lisp/simple.el b/lisp/simple.el
index bbcb32cb04f..adcbe835e5f 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4730,6 +4730,16 @@ shell-command--same-buffer-confirm
                      action))
       (user-error "Shell command in progress"))))
 
+(defun user-uid-for-file (filename)
+  "Return the effective uid for FILENAME.
+For local files, this is equivalent to `user-uid' (which see),
+but for remote files, this returns the effective uid for that
+remote connection; if the remote connection has no associated
+user, it will instead return -1."
+  (if-let ((handler (find-file-name-handler filename 'user-uid-for-file)))
+      (funcall handler 'user-uid-for-file filename)
+    (user-uid)))
+
 (defun max-mini-window-lines (&optional frame)
   "Compute maximum number of lines for echo area in FRAME.
 As defined by `max-mini-window-height'.  FRAME defaults to the
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index 3f602798dbe..0cc1b92266f 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -746,6 +746,10 @@ esh-var-test/path-var/preserve-across-hosts
       (format "cd %s" ert-remote-temporary-file-directory))
      (eshell-match-command-output "echo $PATH" (regexp-quote remote-path)))))
 
+(ert-deftest esh-var-test/uid-var ()
+  "Test that $UID is equivalent to (user-uid) for local directories."
+  (eshell-command-result-equal "echo $UID" (user-uid)))
+
 (ert-deftest esh-var-test/last-status-var-lisp-command ()
   "Test using the \"last exit status\" ($?) variable with a Lisp command"
   (with-temp-eshell
-- 
2.25.1


  reply	other threads:[~2023-01-14 22:10 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-10 23:50 bug#60722: 30.0.50; [PATCH] Using Tramp to sudo in Eshell doesn't change prompt sigil Jim Porter
2023-01-11  2:12 ` Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-01-11  9:35   ` Michael Albinus
2023-01-11  9:33 ` Michael Albinus
2023-01-11 13:59   ` Michael Albinus
2023-01-14 21:59     ` Jim Porter
2023-01-14 22:10       ` Jim Porter [this message]
2023-01-15  9:23         ` Michael Albinus
2023-01-16  5:38           ` Jim Porter
2023-01-16  9:09             ` Michael Albinus
2023-01-17  1:21               ` Jim Porter
2023-01-17  9:12                 ` Michael Albinus
2023-01-18  1:04                   ` Jim Porter
2023-01-17 15:03                 ` Michael Albinus

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=f388bbc3-f01f-d667-6260-1820f6bb4881@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=60722@debbugs.gnu.org \
    --cc=michael.albinus@gmx.de \
    /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).