summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nt/mingw-cfg.site5
-rw-r--r--src/comp.c19
-rw-r--r--src/w32.c39
-rw-r--r--src/w32.h1
4 files changed, 53 insertions, 11 deletions
diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site
index 431fdab51bb..6ab81e943f1 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 340ed850387..056d0860d8a 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 26cc28f877c..968b4bbe489 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 a382dbe791a..ffa145b1484 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);