]> git.eshelyaron.com Git - emacs.git/commitdiff
Support invoking Emacs via a symlink on MS-Windows
authorEli Zaretskii <eliz@gnu.org>
Wed, 26 Jun 2019 16:23:34 +0000 (19:23 +0300)
committerEli Zaretskii <eliz@gnu.org>
Wed, 26 Jun 2019 16:23:34 +0000 (19:23 +0300)
* src/w32.c (w32_my_exename): Resolve symlinks in the
executable name, to support searching for the pdumper file
when the executable is found via a symlink.
* src/emacs.c (load_pdump): Add a comment about symlink
resolution on Windows.

src/emacs.c
src/w32.c

index 231acc0ef329e2b4522dc1a9f396c66426dd07ed..d5eccf78d80faea6d8bba44ab96c0fcf866e4710 100644 (file)
@@ -868,6 +868,8 @@ load_pdump (int argc, char **argv)
   if (exename)
     {
 #ifdef WINDOWSNT
+      /* w32_my_exename resolves symlinks internally, so no need to
+        call realpath.  */
       real_exename = exename;
       exename = NULL;
 #else
index b2d1ffcf82b9ff2ff5f98106f81612b8d8ed8689..36a5a37496eb9fe65b7ceff9244994e928f10bce 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -9988,18 +9988,34 @@ w32_relocate (const char *epath_dir)
   return epath_dir;
 }
 
-/* Return the full absolute name of the running executable.
+/* Return the full absolute name of the running executable.  If the
+   executable is a symlink, resolve it.
 
    Note: this function is called early during startup, when Unicode
-   file name are not yet supported.  */
+   file names are not yet supported.  Thus the result must be an
+   ANSI-encoded string.  */
 char *
 w32_my_exename (void)
 {
   static char exename[MAX_PATH];
   if (!GetModuleFileNameA (NULL, exename, MAX_PATH))
     return NULL;
-  /* FIXME: Resolve possible symlinks in the last component of
-     exename, i.e. if the executable itself is a symlink.  */
+  /* The caller expects us to resolve all possible symlinks in the
+     last component of exename, i.e. if the executable itself is a
+     symlink to a file in another directory.  */
+  if (get_volume_info (exename, NULL)
+      && (volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0)
+    {
+      /* chase_symlinks wants its argument in UTF-8.  */
+      char exename_utf8[MAX_UTF8_PATH];
+      filename_from_ansi (exename, exename_utf8);
+
+      /* If EXENAME is a symlink, replace it with its target.  */
+      char *tgt = chase_symlinks (exename_utf8);
+      if (tgt != exename_utf8)
+       filename_to_ansi (tgt, exename);
+    }
+
   return exename;
 }