emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 21f54fe: Do not hardcode "/bin/sh" in compile. Bug#


From: Michael Albinus
Subject: [Emacs-diffs] master 21f54fe: Do not hardcode "/bin/sh" in compile. Bug#24338, Bug#29723
Date: Sat, 9 Mar 2019 10:44:32 -0500 (EST)

branch: master
commit 21f54feee8c83e2c5fd8eeb6741cbd479a7b19eb
Author: Michael Albinus <address@hidden>
Commit: Michael Albinus <address@hidden>

    Do not hardcode "/bin/sh" in compile.  Bug#24338, Bug#29723
    
    * doc/emacs/custom.texi (Connection Variables): New node.
    
    * doc/emacs/emacs.texi (Top): Add entry for Connection Variables.
    
    * doc/emacs/misc.texi (Single Shell): Mention default value for
    remote buffers.
    
    * doc/lispref/variables.texi (Connection Local Variables):
    Describe `with-connection-local-variables' instead of
    `with-connection-local-profiles'.
    
    * doc/misc/tramp.texi (Remote processes): Refer to Emacs manual.
    Mention default connection-local settings for `shell-file-name'
    and `shell-command-switch'.
    
    * etc/NEWS: Mention connection-local variables changes.
    
    * lisp/files-x.el (hack-connection-local-variables):
    Push connection-local variables to `file-local-variables-alist'.
    (connection-local-criteria-for-default-directory): New defsubst.
    (with-connection-local-variables): Rename from
    `with-connection-local-profiles'.  Adapt implementation.
    
    * lisp/files.el (hack-local-variables):
    Call `hack-connection-local-variables'.
    
    * lisp/shell.el (shell): Use `with-connection-local-variables'.
    
    * lisp/subr.el (start-file-process-shell-command):
    * lisp/progmodes/compile.el (compilation-start):
    Use `with-connection-local-variables'.  Do not set "/bin/sh" for
    remote buffers, trust settings of `shell-file-name'.  (Bug#24338),
    (Bug#29723)
    
    * lisp/net/ange-ftp.el (ange-ftp-compress, ange-ftp-uncompress):
    Use `shell-command-switch'.
    
    * lisp/net/tramp-adb.el (tramp-adb-connection-local-default-profile):
    New defvar.  Add it to connection-local profiles after loading "shell".
    
    * lisp/net/tramp-integration.el (tramp-compat): Require tramp-compat.
    (tramp-compat-exec-path): Do not declare anymore.
    (tramp-connection-local-safe-shell-file-names): New defvar.
    (tramp-connection-local-default-profile): New defconst.  Activate
    it after loading "shell".
    (shell-file-name, shell-command-switch): Add safe-local-variable
    property.
    
    * lisp/net/tramp-sh.el (tramp-display-escape-sequence-regexp):
    Add tramp-autoload cookie.
    
    * test/lisp/files-x-tests.el (remote-shell-file-name):
    Add safe-local-variable property to remote-* variables.
    (tramp-connection-local-default-profile): Declare.
    (files-x-test-with-connection-local-variables):
    Rename from `files-x-test-with-connection-local-profiles'.  Adapt
    implementation.
    
    * test/lisp/net/tramp-tests.el
    (tramp-test34-connection-local-variables): New test.
    (tramp-test34-explicit-shell-file-name): Run it also for tramp-adb.
    Bind connection-local-{profile,criteria}-alist.  Use tramp-adb
    specific `shell-file-name'.  Add safe-local-variable property to
    `explicit-shell-file-name' and `explicit-sh-args'.
---
 doc/emacs/custom.texi         | 48 +++++++++++++++++++++++
 doc/emacs/emacs.texi          |  2 +
 doc/emacs/misc.texi           |  4 ++
 doc/lispref/variables.texi    | 17 ++++++---
 doc/misc/tramp.texi           | 10 ++++-
 etc/NEWS                      | 16 ++++++++
 lisp/files-x.el               | 51 ++++++++++++++++---------
 lisp/files.el                 |  5 +++
 lisp/net/ange-ftp.el          |  4 +-
 lisp/net/tramp-adb.el         | 20 ++++++++++
 lisp/net/tramp-integration.el | 34 ++++++++++++++++-
 lisp/net/tramp-sh.el          |  1 +
 lisp/progmodes/compile.el     | 19 ++++-----
 lisp/shell.el                 | 27 ++++++-------
 lisp/subr.el                  | 11 +++---
 test/lisp/files-x-tests.el    | 89 ++++++++++++++++++++++++-------------------
 test/lisp/net/tramp-tests.el  | 77 +++++++++++++++++++++++++++++++++++--
 17 files changed, 334 insertions(+), 101 deletions(-)

diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 474149f..c649c17 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -765,6 +765,8 @@ expects (@pxref{Examining}).
 * Locals::              Per-buffer values of variables.
 * File Variables::      How files can specify variable values.
 * Directory Variables:: How variable values can be specified by directory.
+* Connection Variables:: Variables which are valid for buffers with a
+                           remote default directory.
 @end menu
 
 @node Examining
@@ -1421,6 +1423,52 @@ variables are handled in the same way as unsafe 
file-local variables
 do not visit a file directly but perform work within a directory, such
 as Dired buffers (@pxref{Dired}).
 
address@hidden Connection Variables
address@hidden Per-Connection Local Variables
address@hidden local variables, for all remote connections
address@hidden connection-local variables
address@hidden per-connection local variables
+
+  Most of the variables reflect the situation on the local machine.
+Often, they must use a different value when you operate in buffers
+with a remote default directory.  Think about the shell to be applied
+when calling @code{shell} -- it might be @file{/bin/bash} on your
+local machine, and @file{/bin/ksh} on a remote machine.
+
+  This can be accomplished with @dfn{connection-local variables}.
+Directory and file local variables override connection-local
+variables.  Unsafe connection-local variables are handled in the same
+way as unsafe file-local variables (@pxref{Safe File Variables}).
+
address@hidden connection-local-set-profile-variables
address@hidden connection-local-set-profiles
+  Connection-local variables are declared as a group of
+variables/value pairs in a @dfn{profile}, using the
address@hidden function.  The function
address@hidden activates profiles for a given
+criteria, identifying a remote machine:
+
address@hidden
+(connection-local-set-profile-variables 'remote-ksh
+   '((shell-file-name . "/bin/ksh")
+     (shell-command-switch . "-c")))
+
+(connection-local-set-profile-variables 'remote-bash
+   '((shell-file-name . "/bin/bash")
+     (shell-command-switch . "-c")))
+
+(connection-local-set-profiles
+   '(:application tramp :machine "remotemachine") 'remote-ksh)
address@hidden example
+
+  This code declares two different profiles, @code{remote-ksh} and
address@hidden The profile @code{remote-ksh} is applied to all
+buffers which have a remote default directory matching the regexp
address@hidden"remotemachine} as host name.  Such a criteria can also
+discriminate for the properties @code{:protocol} (this is the Tramp
+method) or @code{:user} (a remote user name).  The @code{nil} criteria
+matches all buffers with a remote default directory.
+
 @node Key Bindings
 @section Customizing Key Bindings
 @cindex key bindings
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 950ddc0..7edc1a5 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -1135,6 +1135,8 @@ Variables
 * Locals::              Per-buffer values of variables.
 * File Variables::      How files can specify variable values.
 * Directory Variables:: How variable values can be specified by directory.
+* Connection Variables:: Variables which are valid for buffers with a
+                           remote default directory.
 
 Local Variables in Files
 
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index a3aa71e..7d7065a 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -795,6 +795,10 @@ to @command{gpg}.  This will output the list of keys to the
 name is relative, Emacs searches the directories listed in
 @code{exec-path} (@pxref{Shell}).
 
+  If the default directory is remote (@pxref{Remote Files}), the
+default value is @file{/bin/sh}.  This can be changed by declaring
address@hidden connection-local (@pxref{Connection Variables}).
+
   To specify a coding system for @kbd{M-!} or @kbd{M-|}, use the command
 @kbd{C-x @key{RET} c} immediately beforehand.  @xref{Communication Coding}.
 
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index f1e0e37..aca7d2f 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -2191,9 +2191,9 @@ This function looks for connection-local variables 
according to
 @var{criteria}, and immediately applies them in the current buffer.
 @end defun
 
address@hidden with-connection-local-profiles profiles &rest body
-All connection-local variables, which are specified by a connection
-profile in @var{profiles}, are applied.
address@hidden with-connection-local-variables &rest body
+All connection-local variables, which are specified by
address@hidden, are applied.
 
 After that, @var{body} is executed, and the connection-local variables
 are unwound.  Example:
@@ -2207,8 +2207,15 @@ are unwound.  Example:
 @end group
 
 @group
-(with-connection-local-profiles '(remote-perl)
-  do something useful)
+(connection-local-set-profiles
+  '(:application 'tramp :protocol "ssh" :machine "remotehost")
+  'remote-perl)
address@hidden group
+
address@hidden
+(let ((default-directory "/ssh:remotehost:/working/dir/"))
+  (with-connection-local-variables
+    do something useful))
 @end group
 @end example
 @end defmac
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index db3b3f7..ea6ad15 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -2970,7 +2970,7 @@ Starting with Emacs 26, you could use connection-local 
variables for
 setting different values of @code{explicit-shell-file-name} for
 different remote hosts.
 @ifinfo
address@hidden Local Variables, , , elisp}
address@hidden Variables, , , emacs}
 @end ifinfo
 
 @lisp
@@ -3023,6 +3023,14 @@ host.  Example:
 @kbd{M-x auto-revert-tail-mode @key{RET}} runs similarly showing
 continuous output.
 
address@hidden uses the variables @code{shell-file-name} and
address@hidden in order to determine which shell to run.
+For remote hosts, their default values are @file{/bin/sh} and
address@hidden, respectively (except for the @option{adb} method, which
+uses @file{/system/bin/sh}).  Like the variables in the previous
+section, these variables can be changed via connection-local
+variables.
+
 
 @subsection Running @code{eshell} on a remote host
 @cindex @code{eshell}
diff --git a/etc/NEWS b/etc/NEWS
index 1095ecc..0a1d9ea 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -279,6 +279,17 @@ matches strings where the pattern appears as a 
subsequence.  Put
 simply, makes "foo" complete to both "barfoo" and "frodo".  Add 'flex'
 to 'completion-styles' or 'completion-category-overrides' to use it.
 
+** Connection-local variables
+
++++
+*** Connection-local variables are applied by default like file-local
+and directory-local variables.
+
++++
+*** The macro 'with-connection-local-variables' has been renamed from
+'with-connection-local-profiles'.  No argument 'profiles' needed any
+longer.
+
 
 * Editing Changes in Emacs 27.1
 
@@ -994,7 +1005,12 @@ followed when Emacs writes the relevant history variables 
to the disk.
 ---
 *** Program name completion inside remote shells works now as expected.
 
++++
+*** The variable 'shell-file-name' can be set now as connection-local
+variable for remote shells.  It still defaults to "/bin/sh".
+
 ** Pcomplete
+
 *** The function 'pcomplete-uniquify-list' has been renamed from
 'pcomplete-uniqify-list'.
 
diff --git a/lisp/files-x.el b/lisp/files-x.el
index c9abb69..eedf630 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -582,7 +582,7 @@ changed by the user.")
 (setq ignored-local-variables
       (cons 'connection-local-variables-alist ignored-local-variables))
 
-(defvar connection-local-profile-alist '()
+(defvar connection-local-profile-alist nil
   "Alist mapping connection profiles to variable lists.
 Each element in this list has the form (PROFILE VARIABLES).
 PROFILE is the name of a connection profile (a symbol).
@@ -590,7 +590,7 @@ VARIABLES is a list that declares connection-local 
variables for
 PROFILE.  An element in VARIABLES is an alist whose elements are
 of the form (VAR . VALUE).")
 
-(defvar connection-local-criteria-alist '()
+(defvar connection-local-criteria-alist nil
   "Alist mapping connection criteria to connection profiles.
 Each element in this list has the form (CRITERIA PROFILES).
 CRITERIA is a plist identifying a connection and the application
@@ -685,7 +685,9 @@ This does nothing if `enable-connection-local-variables' is 
nil."
       ;; Loop over variables.
       (dolist (variable (connection-local-get-profile-variables profile))
         (unless (assq (car variable) connection-local-variables-alist)
-          (push variable connection-local-variables-alist))))))
+          (push variable connection-local-variables-alist))))
+    ;; Push them to `file-local-variables-alist'.
+    (hack-local-variables-filter connection-local-variables-alist nil)))
 
 ;;;###autoload
 (defun hack-connection-local-variables-apply (criteria)
@@ -697,24 +699,35 @@ will not be changed."
         (copy-tree connection-local-variables-alist)))
    (hack-local-variables-apply)))
 
+(defsubst connection-local-criteria-for-default-directory ()
+  "Return a connection-local criteria, which represents `default-directory'."
+  (when (file-remote-p default-directory)
+    `(:application tramp
+       :protocol ,(file-remote-p default-directory 'method)
+       :user     ,(file-remote-p default-directory 'user)
+       :machine  ,(file-remote-p default-directory 'host))))
+
 ;;;###autoload
-(defmacro with-connection-local-profiles (profiles &rest body)
-  "Apply connection-local variables according to PROFILES in current buffer.
+(defmacro with-connection-local-variables (&rest body)
+  "Apply connection-local variables according to `default-directory'.
 Execute BODY, and unwind connection-local variables."
-  (declare (indent 1) (debug t))
-  `(let ((enable-connection-local-variables t)
-         (old-buffer-local-variables (buffer-local-variables))
-        connection-local-variables-alist connection-local-criteria-alist)
-     (apply 'connection-local-set-profiles nil ,profiles)
-     (hack-connection-local-variables-apply nil)
-     (unwind-protect
-         (progn ,@body)
-       ;; Cleanup.
-       (dolist (variable connection-local-variables-alist)
-        (let ((elt (assq (car variable) old-buffer-local-variables)))
-          (if elt
-              (set (make-local-variable (car elt)) (cdr elt))
-           (kill-local-variable (car variable))))))))
+  (declare (debug t))
+  `(if (file-remote-p default-directory)
+       (let ((enable-connection-local-variables t)
+             (old-buffer-local-variables (buffer-local-variables))
+            connection-local-variables-alist)
+        (hack-connection-local-variables-apply
+         (connection-local-criteria-for-default-directory))
+        (unwind-protect
+             (progn ,@body)
+          ;; Cleanup.
+          (dolist (variable connection-local-variables-alist)
+            (let ((elt (assq (car variable) old-buffer-local-variables)))
+              (if elt
+                  (set (make-local-variable (car elt)) (cdr elt))
+                (kill-local-variable (car variable)))))))
+     ;; No connection-local variables to apply.
+     ,@body))
 
 
 
diff --git a/lisp/files.el b/lisp/files.el
index 9948bd4..77a194b 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3590,6 +3590,11 @@ local variables, but directory-local variables may still 
be applied."
        result)
     (unless (eq handle-mode t)
       (setq file-local-variables-alist nil)
+      (when (file-remote-p default-directory)
+        (with-demoted-errors "Connection-local variables error: %s"
+         ;; Note this is a no-op if enable-local-variables is nil.
+         (hack-connection-local-variables
+           (connection-local-criteria-for-default-directory))))
       (with-demoted-errors "Directory-local variables error: %s"
        ;; Note this is a no-op if enable-local-variables is nil.
        (hack-dir-local-variables)))
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index 428bf32..5af9ea7 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -4277,7 +4277,7 @@ NEWNAME should be the name to give the new compressed or 
uncompressed file.")
                               nil
                               t
                               nil
-                              "-c"
+                              shell-command-switch
                               (format "compress -f -c < %s > %s" tmp1 tmp2))
          (and ange-ftp-process-verbose
               (ange-ftp-message "Compressing %s...done" abbr))
@@ -4313,7 +4313,7 @@ NEWNAME should be the name to give the new compressed or 
uncompressed file.")
                               nil
                               t
                               nil
-                              "-c"
+                              shell-command-switch
                               (format "uncompress -c < %s > %s" tmp1 tmp2))
          (and ange-ftp-process-verbose
               (ange-ftp-message "Uncompressing %s...done" abbr))
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index eb3295e..b40e69e 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -1370,6 +1370,26 @@ connection if a previous connection has died for some 
reason."
            ;; Mark it as connected.
            (tramp-set-connection-property p "connected" t)))))))
 
+;; Default settings for connection-local variables.
+(defconst tramp-adb-connection-local-default-profile
+  '((shell-file-name . "/system/bin/sh")
+    (shell-command-switch . "-c"))
+  "Default connection-local variables for remote adb connections.")
+(add-to-list 'tramp-connection-local-safe-shell-file-names "/system/bin/sh")
+
+;; `connection-local-set-profile-variables' and
+;; `connection-local-set-profiles' exists since Emacs 26.1.
+(eval-after-load "shell"
+  '(progn
+     (tramp-compat-funcall
+      'connection-local-set-profile-variables
+      'tramp-adb-connection-local-default-profile
+      tramp-adb-connection-local-default-profile)
+     (tramp-compat-funcall
+      'connection-local-set-profiles
+      `(:application tramp :protocol ,tramp-adb-method)
+      'tramp-adb-connection-local-default-profile)))
+
 (add-hook 'tramp-unload-hook
          (lambda ()
            (unload-feature 'tramp-adb 'force)))
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index 2a46176..946d7f8 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -27,9 +27,10 @@
 
 ;;; Code:
 
+(require 'tramp-compat)
+
 ;; Pacify byte-compiler.
 (require 'cl-lib)
-(declare-function tramp-compat-exec-path "tramp")
 (declare-function tramp-dissect-file-name "tramp")
 (declare-function tramp-file-name-equal-p "tramp")
 (declare-function tramp-tramp-file-p "tramp")
@@ -170,6 +171,37 @@ NAME must be equal to `tramp-current-connection'."
                 (remove-hook 'tramp-cleanup-all-connections-hook
                              #'tramp-recentf-cleanup-all)))))
 
+;;; Default connection-local variables for Tramp:
+
+;;;###tramp-autoload
+(defvar tramp-connection-local-safe-shell-file-names nil
+  "List of safe `shell-file-name' values for remote hosts.")
+(add-to-list 'tramp-connection-local-safe-shell-file-names "/bin/sh")
+
+(defconst tramp-connection-local-default-profile
+  '((shell-file-name . "/bin/sh")
+    (shell-command-switch . "-c"))
+  "Default connection-local variables for remote connections.")
+(put 'shell-file-name 'safe-local-variable
+     (lambda (item)
+       (and (stringp item)
+           (member item tramp-connection-local-safe-shell-file-names))))
+(put 'shell-command-switch 'safe-local-variable
+     (lambda (item) (and (stringp item) (string-equal item "-c"))))
+
+;; `connection-local-set-profile-variables' and
+;; `connection-local-set-profiles' exists since Emacs 26.1.
+(eval-after-load "shell"
+  '(progn
+     (tramp-compat-funcall
+      'connection-local-set-profile-variables
+      'tramp-connection-local-default-profile
+      tramp-connection-local-default-profile)
+     (tramp-compat-funcall
+      'connection-local-set-profiles
+      `(:application tramp)
+      'tramp-connection-local-default-profile)))
+
 (add-hook 'tramp-unload-hook
          (lambda () (unload-feature 'tramp-integration 'force)))
 
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index ee16138..d9edcb1 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -81,6 +81,7 @@ the default storage location, e.g. \"$HOME/.sh_history\"."
                  (const :tag "Unset HISTFILE" t)
                  (string :tag "Redirect to a file")))
 
+;;;###tramp-autoload
 (defconst tramp-display-escape-sequence-regexp "\e[[;0-9]+m"
   "Terminal control escape sequences for display attributes.")
 
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index b3f32c8..3650b05 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1754,15 +1754,16 @@ Returns the compilation buffer created."
        (if (fboundp 'make-process)
            (let ((proc
                   (if (eq mode t)
-                      ;; comint uses `start-file-process'.
-                      (get-buffer-process
-                       (with-no-warnings
-                         (comint-exec
-                          outbuf (downcase mode-name)
-                          (if (file-remote-p default-directory)
-                              "/bin/sh"
-                            shell-file-name)
-                          nil `("-c" ,command))))
+                       ;; On remote hosts, the local `shell-file-name'
+                       ;; might be useless.
+                       (with-connection-local-variables
+                       ;; comint uses `start-file-process'.
+                       (get-buffer-process
+                        (with-no-warnings
+                          (comint-exec
+                           outbuf (downcase mode-name)
+                           shell-file-name
+                           nil `(,shell-command-switch ,command)))))
                     (start-file-process-shell-command (downcase mode-name)
                                                       outbuf command))))
               ;; Make the buffer's mode line show process state.
diff --git a/lisp/shell.el b/lisp/shell.el
index 524a884..8a2d448 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -99,6 +99,7 @@
 
 (require 'comint)
 (require 'pcomplete)
+(eval-when-compile (require 'files-x)) ;with-connection-local-variables
 
 ;;; Customization and Buffer Variables
 
@@ -721,23 +722,17 @@ Otherwise, one argument `-i' is passed to the shell.
 
   (with-current-buffer buffer
     (when (file-remote-p default-directory)
-      ;; Apply connection-local variables.
-      (hack-connection-local-variables-apply
-       `(:application tramp
-         :protocol ,(file-remote-p default-directory 'method)
-         :user ,(file-remote-p default-directory 'user)
-         :machine ,(file-remote-p default-directory 'host)))
-
       ;; On remote hosts, the local `shell-file-name' might be useless.
-      (if (and (called-interactively-p 'any)
-               (null explicit-shell-file-name)
-               (null (getenv "ESHELL")))
-          (set (make-local-variable 'explicit-shell-file-name)
-               (file-local-name
-               (expand-file-name
-                 (read-file-name
-                  "Remote shell path: " default-directory shell-file-name
-                  t shell-file-name)))))))
+      (with-connection-local-variables
+       (if (and (called-interactively-p 'any)
+                (null explicit-shell-file-name)
+                (null (getenv "ESHELL")))
+           (set (make-local-variable 'explicit-shell-file-name)
+                (file-local-name
+                (expand-file-name
+                  (read-file-name
+                   "Remote shell path: " default-directory shell-file-name
+                   t shell-file-name))))))))
 
   ;; The buffer's window must be correctly set when we call comint
   ;; (so that comint sets the COLUMNS env var properly).
diff --git a/lisp/subr.el b/lisp/subr.el
index 5b03307..4024c68 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3185,11 +3185,12 @@ discouraged."
   "Start a program in a subprocess.  Return the process object for it.
 Similar to `start-process-shell-command', but calls `start-file-process'."
   (declare (advertised-calling-convention (name buffer command) "23.1"))
-  (start-file-process
-   name buffer
-   (if (file-remote-p default-directory) "/bin/sh" shell-file-name)
-   (if (file-remote-p default-directory) "-c" shell-command-switch)
-   (mapconcat 'identity args " ")))
+  ;; On remote hosts, the local `shell-file-name' might be useless.
+  (with-connection-local-variables
+   (start-file-process
+    name buffer
+    shell-file-name shell-command-switch
+    (mapconcat 'identity args " "))))
 
 (defun call-process-shell-command (command &optional infile buffer display
                                           &rest args)
diff --git a/test/lisp/files-x-tests.el b/test/lisp/files-x-tests.el
index d678be4..568a898 100644
--- a/test/lisp/files-x-tests.el
+++ b/test/lisp/files-x-tests.el
@@ -35,6 +35,11 @@
   '((remote-null-device . "/dev/null")))
 (defconst files-x-test--variables4
   '((remote-null-device . "null")))
+(put 'remote-shell-file-name 'safe-local-variable #'identity)
+(put 'remote-shell-command-switch 'safe-local-variable #'identity)
+(put 'remote-shell-interactive-switch 'safe-local-variable #'identity)
+(put 'remote-shell-login-switch 'safe-local-variable #'identity)
+(put 'remote-null-device 'safe-local-variable #'identity)
 
 (defconst files-x-test--application '(:application 'my-application))
 (defconst files-x-test--another-application
@@ -268,7 +273,9 @@
         (should-not (local-variable-p 'remote-shell-file-name))
         (should-not (boundp 'remote-shell-file-name))))))
 
-(ert-deftest files-x-test-with-connection-local-profiles ()
+(defvar tramp-connection-local-default-profile)
+
+(ert-deftest files-x-test-with-connection-local-variables ()
   "Test setting connection-local variables."
 
   (let (connection-local-profile-alist connection-local-criteria-alist)
@@ -303,46 +310,48 @@
          (string-equal (symbol-value 'remote-null-device) "/dev/null"))
 
        ;; A candidate connection-local variable is not bound yet.
-        (should-not (local-variable-p 'remote-shell-command-switch))
-
-       ;; Use the macro.
-        (with-connection-local-profiles '(remote-bash remote-ksh)
-          ;; All connection-local variables are set.  They apply in
-          ;; reverse order in `connection-local-variables-alist'.
-          ;; This variable keeps only the variables to be set inside
-          ;; the macro.
-          (should
-           (equal connection-local-variables-alist
-                  (nreverse (copy-tree files-x-test--variables1))))
-          ;; The variables exist also as local variables.
-          (should (local-variable-p 'remote-shell-file-name))
-          (should (local-variable-p 'remote-shell-command-switch))
-          ;; The proper variable values are set.  The settings from
-          ;; `remote-bash' overwrite the same variables as in
-          ;; `remote-ksh'.
-          (should
-           (string-equal (symbol-value 'remote-shell-file-name) "/bin/bash"))
-          (should
-           (string-equal (symbol-value 'remote-shell-command-switch) "-c")))
-
-        ;; Everything is rewound.  The old variable values are reset.
-        (should
-         (equal connection-local-variables-alist
-               (append
-                (nreverse (copy-tree files-x-test--variables3))
-                (nreverse (copy-tree files-x-test--variables2)))))
-        ;; The variables exist also as local variables.
-        (should (local-variable-p 'remote-shell-file-name))
-        (should (local-variable-p 'remote-null-device))
-        ;; The proper variable values are set.  The settings from
-       ;; `remote-ksh' are back.
-        (should
-         (string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))
-        (should
-         (string-equal (symbol-value 'remote-null-device) "/dev/null"))
+        (should-not (local-variable-p 'remote-shell-command-switch))))
 
-       ;; The variable set temporarily is not unbound, again.
-        (should-not (local-variable-p 'remote-shell-command-switch))))))
+    (with-temp-buffer
+      ;; Use the macro.  We need a remote `default-directory'.
+      (let ((enable-connection-local-variables t)
+           (default-directory "/method:host:")
+           (remote-null-device "null"))
+        (should-not connection-local-variables-alist)
+        (should-not (local-variable-p 'remote-shell-file-name))
+        (should-not (local-variable-p 'remote-null-device))
+        (should-not (boundp 'remote-shell-file-name))
+        (should (string-equal (symbol-value 'remote-null-device) "null"))
+
+       (with-connection-local-variables
+        ;; All connection-local variables are set.  They apply in
+        ;; reverse order in `connection-local-variables-alist'.
+        ;; Since we ha a remote default directory, Tramp's settings
+        ;; are appended as well.
+         (should
+          (equal
+           connection-local-variables-alist
+          (append
+           (nreverse (copy-tree files-x-test--variables3))
+           (nreverse (copy-tree files-x-test--variables2))
+            (nreverse (copy-tree tramp-connection-local-default-profile)))))
+         ;; The variables exist also as local variables.
+         (should (local-variable-p 'remote-shell-file-name))
+         (should (local-variable-p 'remote-null-device))
+         ;; The proper variable values are set.
+         (should
+          (string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))
+         (should
+          (string-equal (symbol-value 'remote-null-device) "/dev/null")))
+
+       ;; Everything is rewound.  The old variable values are reset.
+       (should-not connection-local-variables-alist)
+       ;; The variables don't exist as local variables.
+       (should-not (local-variable-p 'remote-shell-file-name))
+       (should-not (local-variable-p 'remote-null-device))
+       ;; The variable values are reset.
+       (should-not (boundp 'remote-shell-file-name))
+       (should (string-equal (symbol-value 'remote-null-device) "null"))))))
 
 (provide 'files-x-tests)
 ;;; files-x-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 69d5ba8..bf7cdfa 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -4274,12 +4274,78 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
     (dolist (dir '("/mock:localhost#11111:" "/mock:localhost#22222:"))
       (tramp-cleanup-connection (tramp-dissect-file-name dir)))))
 
+;; Connection-local variables are enabled per default since Emacs 27.1.
+(ert-deftest tramp-test34-connection-local-variables ()
+  "Check that connection-local variables are enabled."
+  :tags '(:expensive-test)
+  (skip-unless (tramp--test-enabled))
+  ;; Since Emacs 27.1.
+  (skip-unless (fboundp 'with-connection-local-variables))
+
+  ;; `connection-local-set-profile-variables' and
+  ;; `connection-local-set-profiles' exist since Emacs 26.1.  We don't
+  ;; want to see compiler warnings for older Emacsen.
+  (let* ((default-directory tramp-test-temporary-file-directory)
+        (tmp-name1 (tramp--test-make-temp-name))
+        (tmp-name2 (expand-file-name "foo" tmp-name1))
+        (enable-local-variables :all)
+        (enable-remote-dir-locals t)
+        kill-buffer-query-functions
+        connection-local-profile-alist connection-local-criteria-alist)
+    (unwind-protect
+       (progn
+         (make-directory tmp-name1)
+          (should (file-directory-p tmp-name1))
+
+         ;; `local-variable' is buffer-local due to explicit setting.
+         (with-no-warnings
+           (defvar-local local-variable 'buffer))
+         (with-temp-buffer
+           (should (eq local-variable 'buffer)))
+
+         ;; `local-variable' is connection-local due to Tramp.
+         (write-region "foo" nil tmp-name2)
+         (should (file-exists-p tmp-name2))
+         (with-no-warnings
+           (connection-local-set-profile-variables
+            'local-variable-profile
+            '((local-variable . connect)))
+           (connection-local-set-profiles
+            `(:application tramp
+              :protocol ,(file-remote-p default-directory 'method)
+              :user ,(file-remote-p default-directory 'user)
+              :machine ,(file-remote-p default-directory 'host))
+            'local-variable-profile))
+         (with-current-buffer (find-file-noselect tmp-name2)
+           (should (eq local-variable 'connect))
+           (kill-buffer (current-buffer)))
+
+         ;; `local-variable' is dir-local due to existence of .dir-locals.el.
+         (write-region
+          "((nil . ((local-variable . dir))))" nil
+          (expand-file-name ".dir-locals.el" tmp-name1))
+         (should (file-exists-p (expand-file-name ".dir-locals.el" tmp-name1)))
+         (with-current-buffer (find-file-noselect tmp-name2)
+           (should (eq local-variable 'dir))
+           (kill-buffer (current-buffer)))
+
+         ;; `local-variable' is file-local due to specifying as file variable.
+         (write-region
+          "-*- mode: comint; local-variable: file; -*-" nil tmp-name2)
+          (should (file-exists-p tmp-name2))
+         (with-current-buffer (find-file-noselect tmp-name2)
+           (should (eq local-variable 'file))
+           (kill-buffer (current-buffer))))
+
+      ;; Cleanup.
+      (ignore-errors (delete-directory tmp-name1 'recursive)))))
+
 ;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test34-explicit-shell-file-name ()
   "Check that connection-local `explicit-shell-file-name' is set."
   :tags '(:expensive-test)
   (skip-unless (tramp--test-enabled))
-  (skip-unless (tramp--test-sh-p))
+  (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p)))
   ;; Since Emacs 26.1.
   (skip-unless (and (fboundp 'connection-local-set-profile-variables)
                    (fboundp 'connection-local-set-profiles)))
@@ -4288,7 +4354,8 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
   ;; `connection-local-set-profiles' exist since Emacs 26.1.  We don't
   ;; want to see compiler warnings for older Emacsen.
   (let ((default-directory tramp-test-temporary-file-directory)
-       explicit-shell-file-name kill-buffer-query-functions)
+       explicit-shell-file-name kill-buffer-query-functions
+       connection-local-profile-alist connection-local-criteria-alist)
     (unwind-protect
        (progn
          ;; `shell-mode' would ruin our test, because it deletes all
@@ -4298,7 +4365,8 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
          (with-no-warnings
            (connection-local-set-profile-variables
             'remote-sh
-            '((explicit-shell-file-name . "/bin/sh")
+            `((explicit-shell-file-name
+               . ,(if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
               (explicit-sh-args . ("-i"))))
            (connection-local-set-profiles
             `(:application tramp
@@ -4306,6 +4374,8 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
               :user ,(file-remote-p default-directory 'user)
               :machine ,(file-remote-p default-directory 'host))
             'remote-sh))
+         (put 'explicit-shell-file-name 'safe-local-variable #'identity)
+         (put 'explicit-sh-args 'safe-local-variable #'identity)
 
          ;; Run interactive shell.  Since the default directory is
          ;; remote, `explicit-shell-file-name' shall be set in order
@@ -4316,6 +4386,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
            (call-interactively #'shell)
            (should explicit-shell-file-name)))
 
+      ;; Cleanup.
       (put 'explicit-shell-file-name 'permanent-local nil)
       (kill-buffer "*shell*"))))
 



reply via email to

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