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.
This commit is contained in:
Lars Ingebrigtsen 2022-04-18 11:31:28 +02:00
parent 9fc3b00373
commit 088cb6115f

View file

@ -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");