]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve pdump file search and 'pdumper-stats'
authorEli Zaretskii <eliz@gnu.org>
Sat, 26 Jan 2019 10:08:56 +0000 (12:08 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 26 Jan 2019 10:08:56 +0000 (12:08 +0200)
* 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.

doc/emacs/cmdargs.texi
src/emacs.c
src/fileio.c
src/lisp.h
src/pdumper.c
src/pdumper.h

index b49126764a67fc8945340165befdfc4cb33706e8..00d5be70eb260661cdfdd52017ea50cc54b4ad2c 100644 (file)
@@ -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
 
index 2738c7ca3f520c813af486a046aaaa31cd82a87f..8a440de28a7e35a61452f3d2eb7e1b320b2421f2 100644 (file)
@@ -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))
     {
index 87442905b181b479393df7c76754f2a90203bba6..aececcda3055f43cef9436c2be6a6e68280a6d1b 100644 (file)
@@ -1626,7 +1626,7 @@ See also the function `substitute-in-file-name'.")
 }
 #endif
 \f
-static bool
+bool
 file_name_absolute_p (const char *filename)
 {
   return
index 5c48905232fbacf5a1b727d859f38ff820c24eb1..78bc423bed74459d07b81c07956054580073172e 100644 (file)
@@ -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,
index 976d35d47d1a3cfd11dc96027d6a0b5db0db29e0..f9638d435797127e1c12b8e6625cb47688d402ec 100644 (file)
@@ -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));
 }
 
index 7b52c64b9742ec27573e3ed5efbe2175d8b98c7f..90c744f0a4ee8a0facc4ef4681e56edc476446d1 100644 (file)
@@ -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