emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master a797493: Improve pdump file search and 'pdumper-sta


From: Eli Zaretskii
Subject: [Emacs-diffs] master a797493: Improve pdump file search and 'pdumper-stats'
Date: Sat, 26 Jan 2019 05:12:33 -0500 (EST)

branch: master
commit a7974933dd818194de3c9387b95dbd122bcf506c
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 doc/emacs/cmdargs.texi | 16 ++++++++++------
 src/emacs.c            | 51 +++++++++++++++++++++++++++++++++++++++++++-------
 src/fileio.c           |  2 +-
 src/lisp.h             |  1 +
 src/pdumper.c          | 27 ++++++++++++++++++--------
 src/pdumper.h          |  4 ++++
 6 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index b491267..00d5be7 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -387,12 +387,16 @@ elisp, The GNU Emacs Lisp Reference Manual}.
 @item address@hidden
 @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
address@hidden@var{emacs}.pdmp} in the directory of the executable, where
address@hidden is the name of the Emacs executable file, normally just
address@hidden  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
address@hidden@var{emacs}.pdmp} in the directory where the Emacs installation
+puts the architecture-dependent files; the variable
address@hidden 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 2738c7c..8a440de 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 8744290..aececcd 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 5c48905..78bc423 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 976d35d..f9638d4 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 7b52c64..90c744f 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]