* 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.
@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
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;
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)
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)
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;
}
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))
{
}
#endif
\f
-static bool
+bool
file_name_absolute_p (const char *filename)
{
return
/* 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,
}
err = PDUMPER_LOAD_OOM;
- dump_filename_copy = strdup (dump_filename);
+ dump_filename_copy = xstrdup (dump_filename);
if (!dump_filename_copy)
goto out;
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,
#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));
}
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