Package: emacs;
Reported by: Dario Gjorgjevski <dario.gjorgjevski <at> gmail.com>
Date: Thu, 15 Apr 2021 14:10:01 UTC
Severity: normal
Merged with 47825
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Dario Gjorgjevski <dario.gjorgjevski <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: psainty <at> orcon.net.nz, 47800 <at> debbugs.gnu.org Subject: bug#47800: [native-comp] could not resolve realpath of "emacs" Date: Fri, 16 Apr 2021 10:57:22 +0200
[Message part 1 (text/plain, inline)]
> Does the untested patch below fix the problem? Hi Eli, Thanks for the patch. Unfortunately it does not help as the raw_name variable in set_invocation_vars is still not resolved according to PATH. The patch I am attaching to this message _does_ resolve the issue, but I am not sure about Windows. Best regards, Dario
[resolve-raw_name.patch (text/x-diff, inline)]
diff --git a/src/emacs.c b/src/emacs.c index a256564..16fdc3c 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -460,8 +460,81 @@ real_filename (char *filename) return real_name; } -/* Set `invocation-name' `invocation-directory'. */ +/* Find a name (absolute or relative) of the Emacs executable whose + name (as passed into this program) is ARGV0. Called early in + initialization by portable dumper loading code, so avoid Lisp and + associated machinery. Return a heap-allocated string giving a name + of the Emacs executable, or an empty heap-allocated string or NULL + if not found. Store into *CANDIDATE_SIZE a lower bound on the size + of any heap allocation. */ +static char * +find_executable (char const *argv0, ptrdiff_t *candidate_size) +{ + *candidate_size = 0; + + /* Use xstrdup etc. to allocate storage, so as to call our private + implementation of malloc, since the caller calls our free. */ +#ifdef WINDOWSNT + char *prog_fname = w32_my_exename (); + return prog_fname ? xstrdup (prog_fname) : NULL; +#else /* !WINDOWSNT */ + char *candidate = NULL; + + /* If the executable name contains a slash, we have some kind of + path already, so just copy it. */ + eassert (argv0); + if (strchr (argv0, DIRECTORY_SEP)) + return xstrdup (argv0); + ptrdiff_t argv0_length = strlen (argv0); + + const char *path = getenv ("PATH"); + if (!path) + { + /* Default PATH is implementation-defined, so we don't know how + to conduct the search. */ + return NULL; + } + + /* Actually try each concatenation of a path element and the + executable basename. */ + do + { + static char const path_sep[] = { SEPCHAR, '\0' }; + ptrdiff_t path_part_length = strcspn (path, path_sep); + const char *path_part = path; + path += path_part_length; + if (path_part_length == 0) + { + path_part = "."; + path_part_length = 1; + } + ptrdiff_t needed = path_part_length + 1 + argv0_length + 1; + if (*candidate_size <= needed) + { + xfree (candidate); + candidate = xpalloc (NULL, candidate_size, + needed - *candidate_size + 1, -1, 1); + } + memcpy (candidate + 0, path_part, path_part_length); + candidate[path_part_length] = DIRECTORY_SEP; + memcpy (candidate + path_part_length + 1, argv0, argv0_length + 1); + struct stat st; + if (file_access_p (candidate, X_OK) + && stat (candidate, &st) == 0 && S_ISREG (st.st_mode)) + { + if (lstat (candidate, &st) == 0 && S_ISLNK (st.st_mode)) + return realpath (candidate, NULL); + return candidate; + } + *candidate = '\0'; + } + while (*path++ != '\0'); + + return candidate; +#endif /* !WINDOWSNT */ +} +/* Set `invocation-name' `invocation-directory'. */ static void set_invocation_vars (char *argv0, char const *original_pwd) { @@ -486,7 +559,9 @@ set_invocation_vars (char *argv0, char const *original_pwd) raw_name = build_unibyte_string (argv0); } #else - raw_name = build_unibyte_string (argv0); + ptrdiff_t bufsize; + char *executable = find_executable (argv0, &bufsize); + raw_name = build_unibyte_string (executable); #endif /* Add /: to the front of the name @@ -785,76 +860,6 @@ dump_error_to_string (int result) } } -/* Find a name (absolute or relative) of the Emacs executable whose - name (as passed into this program) is ARGV0. Called early in - initialization by portable dumper loading code, so avoid Lisp and - associated machinery. Return a heap-allocated string giving a name - of the Emacs executable, or an empty heap-allocated string or NULL - if not found. Store into *CANDIDATE_SIZE a lower bound on the size - of any heap allocation. */ -static char * -load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size) -{ - *candidate_size = 0; - - /* Use xstrdup etc. to allocate storage, so as to call our private - implementation of malloc, since the caller calls our free. */ -#ifdef WINDOWSNT - char *prog_fname = w32_my_exename (); - return prog_fname ? xstrdup (prog_fname) : NULL; -#else /* !WINDOWSNT */ - char *candidate = NULL; - - /* If the executable name contains a slash, we have some kind of - path already, so just copy it. */ - eassert (argv0); - if (strchr (argv0, DIRECTORY_SEP)) - return xstrdup (argv0); - ptrdiff_t argv0_length = strlen (argv0); - - const char *path = getenv ("PATH"); - if (!path) - { - /* Default PATH is implementation-defined, so we don't know how - to conduct the search. */ - return NULL; - } - - /* Actually try each concatenation of a path element and the - executable basename. */ - do - { - static char const path_sep[] = { SEPCHAR, '\0' }; - ptrdiff_t path_part_length = strcspn (path, path_sep); - const char *path_part = path; - path += path_part_length; - if (path_part_length == 0) - { - path_part = "."; - path_part_length = 1; - } - ptrdiff_t needed = path_part_length + 1 + argv0_length + 1; - if (*candidate_size <= needed) - { - xfree (candidate); - candidate = xpalloc (NULL, candidate_size, - needed - *candidate_size + 1, -1, 1); - } - memcpy (candidate + 0, path_part, path_part_length); - candidate[path_part_length] = DIRECTORY_SEP; - memcpy (candidate + path_part_length + 1, argv0, argv0_length + 1); - struct stat st; - if (file_access_p (candidate, X_OK) - && stat (candidate, &st) == 0 && S_ISREG (st.st_mode)) - return candidate; - *candidate = '\0'; - } - while (*path++ != '\0'); - - return candidate; -#endif /* !WINDOWSNT */ -} - static void load_pdump (int argc, char **argv, char const *original_pwd) { @@ -906,7 +911,7 @@ load_pdump (int argc, char **argv, char const *original_pwd) encoding the system natively uses for filesystem access, so there's no need for character set conversion. */ ptrdiff_t bufsize; - dump_file = load_pdump_find_executable (argv[0], &bufsize); + dump_file = find_executable (argv[0], &bufsize); /* If we couldn't find our executable, go straight to looking for the dump in the hardcoded location. */
[Message part 3 (text/plain, inline)]
-- $ keyserver=hkps://hkps.pool.sks-keyservers.net $ keyid=744A4F0B4F1C9371 $ gpg --keyserver $keyserver --search-keys $keyid
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.