From: Eli Zaretskii Date: Sat, 26 Jan 2019 10:08:56 +0000 (+0200) Subject: Improve pdump file search and 'pdumper-stats' X-Git-Tag: emacs-27.0.90~3728 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a7974933dd818194de3c9387b95dbd122bcf506c;p=emacs.git 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. --- diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index b49126764a6..00d5be70eb2 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -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 diff --git a/src/emacs.c b/src/emacs.c index 2738c7ca3f5..8a440de28a7 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -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)) { diff --git a/src/fileio.c b/src/fileio.c index 87442905b18..aececcda305 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1626,7 +1626,7 @@ See also the function `substitute-in-file-name'.") } #endif -static bool +bool file_name_absolute_p (const char *filename) { return diff --git a/src/lisp.h b/src/lisp.h index 5c48905232f..78bc423bed7 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -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, diff --git a/src/pdumper.c b/src/pdumper.c index 976d35d47d1..f9638d43579 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -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)); } diff --git a/src/pdumper.h b/src/pdumper.h index 7b52c64b974..90c744f0a4e 100644 --- a/src/pdumper.h +++ b/src/pdumper.h @@ -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