From 088cb6115f9e3c4637b1eafbffa022873a70d7e9 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 18 Apr 2022 11:31:28 +0200 Subject: [PATCH] Make `restart-emacs' work when Emacs is started with --chdir * src/emacs.c (find_emacs_executable): Rename from load_pdump_find_executable and always define. (load_pdump): Return the executable. (main): Store the executable. (Fkill_emacs): Use the stored executable so that --chdir works with relative executable names, and so that we attempt to restart the same executable and not some other Emacs from PATH. --- src/emacs.c | 80 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/src/emacs.c b/src/emacs.c index e65ed125b9d..2fb62cb69af 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -233,6 +233,7 @@ HANDLE w32_daemon_event; /* Save argv and argc. */ char **initial_argv; int initial_argc; +static char *initial_emacs_executable = NULL; /* The name of the working directory, or NULL if this info is unavailable. */ char const *emacs_wd; @@ -714,34 +715,6 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr, } } -#ifdef HAVE_PDUMPER - -static const char * -dump_error_to_string (int result) -{ - switch (result) - { - case PDUMPER_LOAD_SUCCESS: - return "success"; - case PDUMPER_LOAD_OOM: - return "out of memory"; - case PDUMPER_NOT_LOADED: - return "not loaded"; - case PDUMPER_LOAD_FILE_NOT_FOUND: - return "could not open file"; - case PDUMPER_LOAD_BAD_FILE_TYPE: - return "not a dump file"; - case PDUMPER_LOAD_FAILED_DUMP: - return "dump file is result of failed dump attempt"; - case PDUMPER_LOAD_VERSION_MISMATCH: - return "not built for this Emacs executable"; - default: - return (result <= PDUMPER_LOAD_ERROR - ? "generic error" - : strerror (result - PDUMPER_LOAD_ERROR)); - } -} - /* 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 @@ -750,7 +723,7 @@ dump_error_to_string (int result) 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) +find_emacs_executable (char const *argv0, ptrdiff_t *candidate_size) { *candidate_size = 0; @@ -841,7 +814,36 @@ load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size) #endif /* !WINDOWSNT */ } -static void +#ifdef HAVE_PDUMPER + +static const char * +dump_error_to_string (int result) +{ + switch (result) + { + case PDUMPER_LOAD_SUCCESS: + return "success"; + case PDUMPER_LOAD_OOM: + return "out of memory"; + case PDUMPER_NOT_LOADED: + return "not loaded"; + case PDUMPER_LOAD_FILE_NOT_FOUND: + return "could not open file"; + case PDUMPER_LOAD_BAD_FILE_TYPE: + return "not a dump file"; + case PDUMPER_LOAD_FAILED_DUMP: + return "dump file is result of failed dump attempt"; + case PDUMPER_LOAD_VERSION_MISMATCH: + return "not built for this Emacs executable"; + default: + return (result <= PDUMPER_LOAD_ERROR + ? "generic error" + : strerror (result - PDUMPER_LOAD_ERROR)); + } +} + +/* This function returns the Emacs executable. */ +static char * load_pdump (int argc, char **argv) { const char *const suffix = ".pdmp"; @@ -890,7 +892,7 @@ load_pdump (int argc, char **argv) #ifndef NS_SELF_CONTAINED ptrdiff_t exec_bufsize; #endif - emacs_executable = load_pdump_find_executable (argv[0], &bufsize); + emacs_executable = find_emacs_executable (argv[0], &bufsize); #ifndef NS_SELF_CONTAINED exec_bufsize = bufsize; #endif @@ -907,7 +909,7 @@ load_pdump (int argc, char **argv) if (result != PDUMPER_LOAD_SUCCESS) fatal ("could not load dump file \"%s\": %s", dump_file, dump_error_to_string (result)); - return; + return emacs_executable; } /* Look for a dump file in the same directory as the executable; it @@ -1032,7 +1034,8 @@ load_pdump (int argc, char **argv) out: xfree (dump_file); - xfree (emacs_executable); + + return emacs_executable; } #endif /* HAVE_PDUMPER */ @@ -1346,7 +1349,10 @@ main (int argc, char **argv) #ifdef HAVE_PDUMPER if (attempt_load_pdump) - load_pdump (argc, argv); + initial_emacs_executable = load_pdump (argc, argv); +#else + ptrdiff_t bufsize; + initial_emacs_executable = find_emacs_executable (argv[0], &bufsize); #endif argc = maybe_disable_address_randomization (argc, argv); @@ -2781,7 +2787,10 @@ killed. */ error ("No command line arguments known; unable to re-execute Emacs"); /* Check that the binary hasn't gone away. */ - if (!file_access_p (initial_argv[0], F_OK)) + if (!initial_emacs_executable) + error ("Unknown Emacs executable"); + + if (!file_access_p (initial_emacs_executable, F_OK)) error ("Emacs executable \"%s\" can't be found", initial_argv[0]); } #endif @@ -2834,6 +2843,7 @@ killed. */ #ifdef WINDOWSNT if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0) #else + initial_argv[0] = initial_emacs_executable; if (execvp (*initial_argv, initial_argv) < 1) #endif emacs_perror ("Unable to re-execute Emacs"); -- 2.39.2