emacs-diffs
[Top][All Lists]
Advanced

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

master d3817ad: Fix resolution of symlinks during dumping


From: Eli Zaretskii
Subject: master d3817ad: Fix resolution of symlinks during dumping
Date: Thu, 27 May 2021 09:32:03 -0400 (EDT)

branch: master
commit d3817ad6ce7b719c89d4049bdd12b168e3053a76
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Fix resolution of symlinks during dumping
    
    * src/comp.c (Fcomp_el_to_eln_rel_filename): Don't use
    'file-truename', as it is only available once files.el is loaded,
    which doesn't work during dumping, until loadup loads files.el.
    Instead, use 'realpath'.  (Bug#48578)
    * src/w32.c (realpath): New function.
    * src/w32.h (realpath): Add prototype.
    
    * nt/mingw-cfg.site (ac_cv_func_realpath)
    (gl_cv_func_realpath_works): Define to "yes", as this function is
    now implemented in w32.c.
---
 nt/mingw-cfg.site |  5 +++--
 src/comp.c        | 19 ++++++++++---------
 src/w32.c         | 39 +++++++++++++++++++++++++++++++++++++++
 src/w32.h         |  1 +
 4 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site
index 431fdab..6ab81e9 100644
--- a/nt/mingw-cfg.site
+++ b/nt/mingw-cfg.site
@@ -90,8 +90,9 @@ ac_cv_func_readlinkat=yes
 ac_cv_func_faccessat=yes
 # Avoid compiling Gnulib's canonicalize-lgpl.c, which fails
 ac_cv_func_canonicalize_file_name=yes
-ac_cv_func_realpath="not-needed"
-gl_cv_func_realpath_works="no-but-not-needed-so-yes"
+# Implemented in w32.c
+ac_cv_func_realpath=yes
+gl_cv_func_realpath_works=yes
 # Implemented in w32.c
 ac_cv_func_fcntl=yes
 gl_cv_func_fcntl_f_dupfd_cloexec=yes
diff --git a/src/comp.c b/src/comp.c
index 340ed85..056d086 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -4008,15 +4008,16 @@ DEFUN ("comp-el-to-eln-rel-filename", 
Fcomp_el_to_eln_rel_filename,
 {
   CHECK_STRING (filename);
 
-  /* Use `file-truename' or fall back to `expand-file-name' when the
-     first is not available (bug#44701).
-
-     `file-truename' is not available only for a short phases of the
-     bootstrap before file.el is loaded, given we do not symlink
-     inside the build directory this should work.  */
-  filename = NILP (Ffboundp (intern_c_string ("file-truename")))
-    ? Fexpand_file_name (filename, Qnil)
-    : CALL1I (file-truename, filename);
+  /* Resolve possible symlinks in FILENAME, so that path_hash below
+     always compares equal. (Bug#44701).  */
+  filename = Fexpand_file_name (filename, Qnil);
+  char *file_normalized = realpath (SSDATA (ENCODE_FILE (filename)), NULL);
+  if (file_normalized)
+    {
+      filename = DECODE_FILE (make_unibyte_string (file_normalized,
+                                                  strlen (file_normalized)));
+      xfree (file_normalized);
+    }
 
   if (NILP (Ffile_exists_p (filename)))
     xsignal1 (Qfile_missing, filename);
diff --git a/src/w32.c b/src/w32.c
index 26cc28f..968b4bb 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10587,6 +10587,45 @@ w32_my_exename (void)
   return exename;
 }
 
+/* Emulate Posix 'realpath'.  This is needed in
+   comp-el-to-eln-rel-filename.  */
+char *
+realpath (const char *file_name, char *resolved_name)
+{
+  char *tgt = chase_symlinks (file_name);
+  char target[MAX_UTF8_PATH];
+
+  if (tgt == file_name)
+    {
+      /* If FILE_NAME is not a symlink, chase_symlinks returns its
+        argument, possibly not in canonical absolute form.  Make sure
+        we return a canonical file name.  */
+      if (w32_unicode_filenames)
+       {
+         wchar_t file_w[MAX_PATH], tgt_w[MAX_PATH];
+
+         filename_to_utf16 (file_name, file_w);
+         if (GetFullPathNameW (file_w, MAX_PATH, tgt_w, NULL) == 0)
+           return NULL;
+         filename_from_utf16 (tgt_w, target);
+       }
+      else
+       {
+         char file_a[MAX_PATH], tgt_a[MAX_PATH];
+
+         filename_to_ansi (file_name, file_a);
+         if (GetFullPathNameA (file_a, MAX_PATH, tgt_a, NULL) == 0)
+           return NULL;
+         filename_from_ansi (tgt_a, target);
+       }
+      tgt = target;
+    }
+
+  if (resolved_name)
+    return strcpy (resolved_name, tgt);
+  return xstrdup (tgt);
+}
+
 /*
        globals_of_w32 is used to initialize those global variables that
        must always be initialized on startup even when the global variable
diff --git a/src/w32.h b/src/w32.h
index a382dbe..ffa145b 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -187,6 +187,7 @@ extern DWORD multiByteToWideCharFlags;
 
 extern char *w32_my_exename (void);
 extern const char *w32_relocate (const char *);
+extern char *realpath (const char *, char *);
 
 extern void init_environment (char **);
 extern void check_windows_init_file (void);



reply via email to

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