emacs-diffs
[Top][All Lists]
Advanced

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

master 0bb8a011d5: Add 'file-user-uid' to get the connection-local effec


From: Jim Porter
Subject: master 0bb8a011d5: Add 'file-user-uid' to get the connection-local effective UID
Date: Mon, 16 Jan 2023 20:19:19 -0500 (EST)

branch: master
commit 0bb8a011d57cb55c16ff502125b60e8e3bb3d5aa
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Jim Porter <jporterbugs@gmail.com>

    Add 'file-user-uid' to get the connection-local effective UID
    
    In particular, this lets Eshell show a "#" root prompt sigil when the
    user has sudo'ed via "cd /sudo::" (bug#60722).
    
    * lisp/simple.el (file-user-uid): New function.
    
    * lisp/net/tramp.el (tramp-file-name-for-operation): Add
    'file-user-uid'.
    (tramp-handle-file-user-uid): 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 'file-user-uid'.
    
    * lisp/net/tramp-archive.el (tramp-archive-handle-file-user-uid): New
    function...
    (tramp-archive-file-name-handler-alist): ... use it.
    
    * lisp/eshell/em-prompt.el (eshell-prompt-function): Use
    'file-user-uid'.
    
    * 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 'file-user-uid'.
    
    * doc/lispref/files.texi (Magic File Names): Mention 'file-user-uid'.
    
    * doc/misc/eshell.texi (Variables): Document '$UID'.  Add a missing
    index entry for '$INSIDE_EMACS'.
    
    * etc/NEWS: Announce 'file-user-uid'.
---
 doc/lispref/files.texi            |  6 ++++--
 doc/lispref/os.texi               | 10 ++++++++++
 doc/misc/eshell.texi              |  8 ++++++++
 etc/NEWS                          |  6 ++++++
 lisp/eshell/em-prompt.el          |  2 +-
 lisp/eshell/esh-var.el            |  1 +
 lisp/net/tramp-adb.el             |  1 +
 lisp/net/tramp-archive.el         |  7 +++++++
 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                 | 13 ++++++++++++-
 lisp/simple.el                    | 12 ++++++++++++
 test/lisp/eshell/esh-var-tests.el |  4 ++++
 18 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 5cc4c1e7dd..ad01e0f288 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -3390,7 +3390,8 @@ first, before handlers for jobs such as remote file 
access.
 @code{file-readable-p}, @code{file-regular-p},
 @code{file-remote-p}, @code{file-selinux-context},
 @code{file-symlink-p}, @code{file-system-info},
-@code{file-truename}, @code{file-writable-p},
+@code{file-truename}, @code{file-user-uid},
+@code{file-writable-p},
 @code{find-backup-file-name},@*
 @code{get-file-buffer},
 @code{insert-directory},
@@ -3451,7 +3452,8 @@ first, before handlers for jobs such as remote file 
access.
 @code{file-readable-p}, @code{file-regular-p},
 @code{file-remote-p}, @code{file-selinux-context},
 @code{file-symlink-p}, @code{file-system-info},
-@code{file-truename}, @code{file-writable-p},
+@code{file-truename}, @code{file-user-uid},
+@code{file-writable-p},
 @code{find-backup-file-name},
 @code{get-file-buffer},
 @code{insert-directory},
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 3be7036f63..bca62a7a8d 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1277,6 +1277,16 @@ This function returns the real @acronym{UID} of the user.
 This function returns the effective @acronym{UID} of the user.
 @end defun
 
+@defun file-user-uid
+This function returns the connection-local value for the user's
+effective @acronym{UID}.  If @code{default-directory} 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 fc7d52eb71..c40ff58f42 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -983,6 +983,13 @@ whenever you change the current directory to a different 
host
 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 @@ that are currently visible in the Eshell window.  They 
are both
 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 068f7a27db..cde6783349 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -235,6 +235,12 @@ compared reliably at all.
 This warning can be suppressed using 'with-suppressed-warnings' with
 the warning name 'suspicious'.
 
++++
+** New function 'file-user-uid'.
+This function is like 'user-uid', but is aware of file name handlers,
+so it will return the remote UID for remote files (or -1 if the
+connection has no associated user).
+
 
 * 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 52d46282c5..b3a0fadf61 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -52,7 +52,7 @@ as is common with most shells."
 (defcustom eshell-prompt-function
   (lambda ()
     (concat (abbreviate-file-name (eshell/pwd))
-            (if (= (user-uid) 0) " # " " $ ")))
+            (if (= (file-user-uid) 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 811bb9957c..fd76a2c6f0 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -162,6 +162,7 @@ if they are quoted with a backslash."
     ("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 () (file-user-uid)) 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 29b9f894ec..10f33e5f92 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -153,6 +153,7 @@ It is used for TCP/IP devices."
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-adb-handle-file-system-info)
     (file-truename . tramp-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-adb-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 3b1d568c12..b9cf85bd84 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -265,6 +265,7 @@ It must be supported by libarchive(3).")
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-archive-handle-file-system-info)
     (file-truename . tramp-archive-handle-file-truename)
+    (file-user-uid . tramp-archive-handle-file-user-uid)
     (file-writable-p . ignore)
     (find-backup-file-name . ignore)
     ;; `get-file-buffer' performed by default handler.
@@ -701,6 +702,12 @@ offered."
     (let ((default-directory (file-name-directory archive)))
       (temporary-file-directory))))
 
+(defun tramp-archive-handle-file-user-uid ()
+  "Like `user-uid' for file archives."
+  (with-parsed-tramp-archive-file-name default-directory nil
+    (let ((default-directory (file-name-directory archive)))
+      (file-user-uid))))
+
 (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 507fd43241..b9d0d96ecc 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -204,6 +204,7 @@ If NAME doesn't belong to an encrypted remote directory, 
return nil."
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-crypt-handle-file-system-info)
     ;; `file-truename' performed by default handler.
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-crypt-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index ea774d0b9b..02ceb2979f 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -798,6 +798,7 @@ It has been changed in GVFS 1.14.")
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-gvfs-handle-file-system-info)
     (file-truename . tramp-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el
index b28f9f6495..9eb2a54cdc 100644
--- a/lisp/net/tramp-rclone.el
+++ b/lisp/net/tramp-rclone.el
@@ -118,6 +118,7 @@
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-rclone-handle-file-system-info)
     (file-truename . tramp-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index acbb6aea13..46b1f61210 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1086,6 +1086,7 @@ Format specifiers \"%s\" are replaced before the script 
is used.")
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-sh-handle-file-system-info)
     (file-truename . tramp-sh-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-sh-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index b3f0344f81..9d03490f1d 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -269,6 +269,7 @@ See `tramp-actions-before-shell' for more info.")
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-smb-handle-file-system-info)
     (file-truename . tramp-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-smb-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index 27b2854e45..65c4bf23c3 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -124,6 +124,7 @@
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-sshfs-handle-file-system-info)
     (file-truename . tramp-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-sshfs-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index ce080918e0..db7ac84287 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -114,6 +114,7 @@ See `tramp-actions-before-shell' for more info.")
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-sudoedit-handle-file-system-info)
     (file-truename . tramp-sudoedit-handle-file-truename)
+    (file-user-uid . tramp-handle-file-user-uid)
     (file-writable-p . tramp-sudoedit-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 169cf1982b..fab1962d2b 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2632,7 +2632,9 @@ Must be handled by the callers."
            '(exec-path make-nearby-temp-file make-process process-file
              shell-command start-file-process temporary-file-directory
              ;; Emacs 29+ only.
-              list-system-processes memory-info process-attributes))
+              list-system-processes memory-info process-attributes
+              ;; Emacs 30+ only.
+             file-user-uid))
     default-directory)
    ;; PROC.
    ((member operation '(file-notify-rm-watch file-notify-valid-p))
@@ -3714,6 +3716,15 @@ Let-bind it when necessary.")
         vec (concat "~" (substring filename (match-beginning 1))))
       (tramp-make-tramp-file-name (tramp-dissect-file-name filename)))))
 
+(defun tramp-handle-file-user-uid ()
+  "Like `user-uid' for Tramp files."
+  (let ((v (tramp-dissect-file-name default-directory)))
+    (or (tramp-get-remote-uid v '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 4b09f41de5..844cfa68b0 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4730,6 +4730,18 @@ Also see the `async-shell-command-buffer' variable."
                      action))
       (user-error "Shell command in progress"))))
 
+(defun file-user-uid ()
+  "Return the connection-local effective uid.
+This is similar to `user-uid', but may invoke a file name handler
+based on `default-directory'.  See Info node `(elisp)Magic File
+Names'.
+
+If a file name handler is unable to retrieve the effective uid,
+this function will instead return -1."
+  (if-let ((handler (find-file-name-handler default-directory 'file-user-uid)))
+      (funcall handler 'file-user-uid)
+    (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 3f602798db..0cc1b92266 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -746,6 +746,10 @@ it, since the setter is nil."
       (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



reply via email to

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