commit 4eb78a47e0be59c6d7b886cfe82ce56b276a52bd (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sat Jan 26 19:48:33 2019 +0200 * src/emacs.c (load_pdump): Fix a thinko in last change. diff --git a/src/emacs.c b/src/emacs.c index 8a440de28a..aed4e0d150 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -780,11 +780,10 @@ 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_SUCCESS) + goto out; - 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) + if (result == PDUMPER_LOAD_FILE_NOT_FOUND) { /* Finally, look for basename(argv[0])+".pdmp" in PATH_EXEC. This way, they can rename both the executable and its pdump @@ -814,6 +813,10 @@ load_pdump (int argc, char **argv) path_exec, DIRECTORY_SEP, argv0_base, suffix); result = pdumper_load (dump_file); } + else + fatal ("could not load dump file \"%s\": %s", + dump_file, dump_error_to_string (result)); + if (result != PDUMPER_LOAD_SUCCESS) dump_file = NULL; commit a7974933dd818194de3c9387b95dbd122bcf506c Author: Eli Zaretskii Date: Sat Jan 26 12:08:56 2019 +0200 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 b49126764a..00d5be70eb 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 2738c7ca3f..8a440de28a 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 87442905b1..aececcda30 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 5c48905232..78bc423bed 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 976d35d47d..f9638d4357 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 7b52c64b97..90c744f0a4 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 commit bf4099b23738f0a481fb6020337039d84506fda4 Author: Eli Zaretskii Date: Sat Jan 26 12:07:27 2019 +0200 Fix face initializations in pdump'ed Emacs * src/dispnew.c (init_display_interactive): Call init_faces_initial in the daemon if dumped with pdumper. (Bug#34114) diff --git a/src/dispnew.c b/src/dispnew.c index 88783cd5da..300f1c2d70 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -6035,10 +6035,21 @@ init_display_interactive (void) /* If running as a daemon, no need to initialize any frames/terminal, except on Windows, where we at least want to initialize it. */ -#ifndef WINDOWSNT if (IS_DAEMON) + { + /* Pdump'ed Emacs doesn't record the initial frame from temacs, + so the non-basic faces realized for that frame in temacs + aren't in emacs. This causes errors when users try to + customize those faces in their init file. The call to + init_faces_initial will realize these faces now. (Non-daemon + Emacs does this either near the end of this function or when + the GUI frame is created.) */ + if (dumped_with_pdumper_p ()) + init_faces_initial (); +#ifndef WINDOWSNT return; #endif + } /* If the user wants to use a window system, we shouldn't bother initializing the terminal. This is especially important when the