Commit a7974933 authored by Eli Zaretskii's avatar Eli Zaretskii

Improve pdump file search and 'pdumper-stats'

* src/pdumper.c (pdumper_record_wd): New function.
(pdumper_load): Use xstrdup instead of strdup, as on
MS-Windows the latter uses the wrong heap.  Don't free a
NULL pointer.
* src/emacs.c (load_pdump): Support the use case where the
Emacs binary was renamed: look in exec-directory for the
pdump file whose base name is derived from the Emacs binary,
in addition to just emacs.pdmp.
(main): Call pdumper_record_wd to prepend CWD to the pdump
file name.
* src/fileio.c (file_name_absolute_p): Now extern.
* src/lisp.h (file_name_absolute_p): Add prototype.
* src/pdumper.h (pdumper_record_wd): Add prototype.

* doc/emacs/cmdargs.texi (Initial Options): Update the
documentation of where Emacs looks for the dump file.
parent bf4099b2
Pipeline #625 passed with stage
in 55 minutes and 38 seconds
......@@ -387,12 +387,16 @@ elisp, The GNU Emacs Lisp Reference Manual}.
@item --dump-file=@var{file}
@opindex --dump-file
@cindex specify dump file
Load the dumped Emacs state from the named @var{file}. By default,
Emacs will look for its dump state in a file named
@file{@var{emacs}.pdmp} in the directory of the executable, where
@var{emacs} is the name of the Emacs executable file, normally just
@file{emacs}. However, if you rename or move the dump file to a
different place, you can use this option to tell Emacs where to find
Load the dumped Emacs state from the named @var{file}. By default, an
installed Emacs will look for its dump state in a file named
@file{@var{emacs}.pdmp} in the directory where the Emacs installation
puts the architecture-dependent files; the variable
@code{exec-directory} holds the name of that directory. @var{emacs}
is the name of the Emacs executable file, normally just @file{emacs}.
(When you invoke Emacs from the @file{src} directory where it was
built without installing it, it will look for the dump file in the
directory of the executable.) If you rename or move the dump file to
a different place, you can use this option to tell Emacs where to find
that file.
@end table
......
......@@ -703,7 +703,6 @@ static enum pdumper_load_result
load_pdump (int argc, char **argv)
{
const char *const suffix = ".pdmp";
const char *const argv0_base = "emacs";
enum pdumper_load_result result;
#ifdef WINDOWSNT
size_t argv0_len;
......@@ -746,7 +745,7 @@ load_pdump (int argc, char **argv)
should have the same basename. */
dump_file = alloca (strlen (argv[0]) + strlen (suffix) + 1);
#ifdef WINDOWSNT
#ifdef DOS_NT
/* Remove the .exe extension if present. */
argv0_len = strlen (argv[0]);
if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0)
......@@ -763,16 +762,16 @@ load_pdump (int argc, char **argv)
fatal ("could not load dump file \"%s\": %s",
dump_file, dump_error_to_string (result));
/* Finally, look for "emacs.pdmp" in PATH_EXEC. We hardcode
"emacs" in "emacs.pdmp" so that the Emacs binary still works
if the user copies and renames it.
FIXME: this doesn't work with emacs-XX.YY.ZZ.pdmp versioned files. */
#ifdef WINDOWSNT
/* On MS-Windows, PATH_EXEC normally starts with a literal
"%emacs_dir%", so it will never work without some tweaking. */
path_exec = w32_relocate (path_exec);
#endif
/* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in
"emacs.pdmp" so that the Emacs binary still works if the user
copies and renames it. */
const char *argv0_base = "emacs";
dump_file = alloca (strlen (path_exec)
+ 1
+ strlen (argv0_base)
......@@ -781,6 +780,40 @@ load_pdump (int argc, char **argv)
sprintf (dump_file, "%s%c%s%s",
path_exec, DIRECTORY_SEP, argv0_base, suffix);
result = pdumper_load (dump_file);
if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
fatal ("could not load dump file \"%s\": %s",
dump_file, dump_error_to_string (result));
if (result != PDUMPER_LOAD_SUCCESS)
{
/* Finally, look for basename(argv[0])+".pdmp" in PATH_EXEC.
This way, they can rename both the executable and its pdump
file in PATH_EXEC, and have several Emacs configurations in
the same versioned libexec subdirectory. */
char *p, *last_sep = NULL;
for (p = argv[0]; *p; p++)
{
if (IS_DIRECTORY_SEP (*p))
last_sep = p;
}
argv0_base = last_sep ? last_sep + 1 : argv[0];
dump_file = alloca (strlen (path_exec)
+ 1
+ strlen (argv0_base)
+ strlen (suffix)
+ 1);
#ifdef DOS_NT
argv0_len = strlen (argv0_base);
if (argv0_len >= 4
&& c_strcasecmp (argv0_base + argv0_len - 4, ".exe") == 0)
sprintf (dump_file, "%s%c%.*s%s", path_exec, DIRECTORY_SEP,
(int)(argv0_len - 4), argv0_base, suffix);
else
#endif
sprintf (dump_file, "%s%c%s%s",
path_exec, DIRECTORY_SEP, argv0_base, suffix);
result = pdumper_load (dump_file);
}
if (result != PDUMPER_LOAD_SUCCESS)
dump_file = NULL;
......@@ -982,6 +1015,10 @@ main (int argc, char **argv)
}
emacs_wd = emacs_get_current_dir_name ();
#ifdef HAVE_PDUMPER
if (dumped_with_pdumper_p ())
pdumper_record_wd (emacs_wd);
#endif
if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
{
......
......@@ -1626,7 +1626,7 @@ See also the function `substitute-in-file-name'.")
}
#endif
static bool
bool
file_name_absolute_p (const char *filename)
{
return
......
......@@ -4224,6 +4224,7 @@ extern void syms_of_marker (void);
/* Defined in fileio.c. */
extern char *splice_dir_file (char *, char const *, char const *);
extern bool file_name_absolute_p (const char *);
extern char const *get_homedir (void);
extern Lisp_Object expand_and_dir_to_file (Lisp_Object);
extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
......
......@@ -5471,7 +5471,7 @@ pdumper_load (const char *dump_filename)
}
err = PDUMPER_LOAD_OOM;
dump_filename_copy = strdup (dump_filename);
dump_filename_copy = xstrdup (dump_filename);
if (!dump_filename_copy)
goto out;
......@@ -5556,10 +5556,24 @@ pdumper_load (const char *dump_filename)
dump_bitset_destroy (&mark_bits);
if (dump_fd >= 0)
emacs_close (dump_fd);
free (dump_filename_copy);
return err;
}
/* Prepend the Emacs startup directory to dump_filename, if that is
relative, so that we could later make it absolute correctly. */
void
pdumper_record_wd (const char *wd)
{
if (wd && !file_name_absolute_p (dump_private.dump_filename))
{
char *dfn = xmalloc (strlen (wd) + 1
+ strlen (dump_private.dump_filename) + 1);
splice_dir_file (dfn, wd, dump_private.dump_filename);
xfree (dump_private.dump_filename);
dump_private.dump_filename = dfn;
}
}
DEFUN ("pdumper-stats", Fpdumper_stats, Spdumper_stats, 0, 0, 0,
doc: /* Return statistics about portable dumping used by this session.
If this Emacs sesion was started from a portable dump file,
......@@ -5579,21 +5593,18 @@ Value is nil if this session was not started using a portable dump file.*/)
#ifdef WINDOWSNT
char dump_fn_utf8[MAX_UTF8_PATH];
if (filename_from_ansi (dump_private.dump_filename, dump_fn_utf8) == 0)
{
dostounix_filename (dump_fn_utf8);
dump_fn = DECODE_FILE (build_unibyte_string (dump_fn_utf8));
}
dump_fn = DECODE_FILE (build_unibyte_string (dump_fn_utf8));
else
dump_fn = build_unibyte_string (dump_private.dump_filename);
#else
dump_fn = DECODE_FILE (build_unibyte_string (dump_private.dump_filename));
#endif
dump_fn = Fexpand_file_name (dump_fn, Qnil);
return CALLN (Flist,
Fcons (Qdumped_with_pdumper, Qt),
Fcons (Qload_time, make_float (dump_private.load_time)),
/* FIXME: dump_fn should be expanded relative to the
original pwd where Emacs started. */
Fcons (Qdump_file_name, dump_fn));
}
......
......@@ -260,6 +260,10 @@ pdumper_clear_marks (void)
and execution should resume. */
bool pdumper_handle_page_fault (void *fault_addr_ptr);
/* Record the Emacs startup directory, relative to which the pdump
file was loaded. */
extern void pdumper_record_wd (const char *);
void syms_of_pdumper (void);
INLINE_HEADER_END
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment