aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2019-01-26 12:08:56 +0200
committerEli Zaretskii2019-01-26 12:08:56 +0200
commita7974933dd818194de3c9387b95dbd122bcf506c (patch)
tree313d57e1561420c541114795150193c4c199570b
parentbf4099b23738f0a481fb6020337039d84506fda4 (diff)
downloademacs-a7974933dd818194de3c9387b95dbd122bcf506c.tar.gz
emacs-a7974933dd818194de3c9387b95dbd122bcf506c.zip
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.
-rw-r--r--doc/emacs/cmdargs.texi16
-rw-r--r--src/emacs.c51
-rw-r--r--src/fileio.c2
-rw-r--r--src/lisp.h1
-rw-r--r--src/pdumper.c27
-rw-r--r--src/pdumper.h4
6 files changed, 79 insertions, 22 deletions
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}.
387@item --dump-file=@var{file} 387@item --dump-file=@var{file}
388@opindex --dump-file 388@opindex --dump-file
389@cindex specify dump file 389@cindex specify dump file
390Load the dumped Emacs state from the named @var{file}. By default, 390Load the dumped Emacs state from the named @var{file}. By default, an
391Emacs will look for its dump state in a file named 391installed Emacs will look for its dump state in a file named
392@file{@var{emacs}.pdmp} in the directory of the executable, where 392@file{@var{emacs}.pdmp} in the directory where the Emacs installation
393@var{emacs} is the name of the Emacs executable file, normally just 393puts the architecture-dependent files; the variable
394@file{emacs}. However, if you rename or move the dump file to a 394@code{exec-directory} holds the name of that directory. @var{emacs}
395different place, you can use this option to tell Emacs where to find 395is the name of the Emacs executable file, normally just @file{emacs}.
396(When you invoke Emacs from the @file{src} directory where it was
397built without installing it, it will look for the dump file in the
398directory of the executable.) If you rename or move the dump file to
399a different place, you can use this option to tell Emacs where to find
396that file. 400that file.
397@end table 401@end table
398 402
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
703load_pdump (int argc, char **argv) 703load_pdump (int argc, char **argv)
704{ 704{
705 const char *const suffix = ".pdmp"; 705 const char *const suffix = ".pdmp";
706 const char *const argv0_base = "emacs";
707 enum pdumper_load_result result; 706 enum pdumper_load_result result;
708#ifdef WINDOWSNT 707#ifdef WINDOWSNT
709 size_t argv0_len; 708 size_t argv0_len;
@@ -746,7 +745,7 @@ load_pdump (int argc, char **argv)
746 should have the same basename. */ 745 should have the same basename. */
747 746
748 dump_file = alloca (strlen (argv[0]) + strlen (suffix) + 1); 747 dump_file = alloca (strlen (argv[0]) + strlen (suffix) + 1);
749#ifdef WINDOWSNT 748#ifdef DOS_NT
750 /* Remove the .exe extension if present. */ 749 /* Remove the .exe extension if present. */
751 argv0_len = strlen (argv[0]); 750 argv0_len = strlen (argv[0]);
752 if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0) 751 if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0)
@@ -763,16 +762,16 @@ load_pdump (int argc, char **argv)
763 fatal ("could not load dump file \"%s\": %s", 762 fatal ("could not load dump file \"%s\": %s",
764 dump_file, dump_error_to_string (result)); 763 dump_file, dump_error_to_string (result));
765 764
766 /* Finally, look for "emacs.pdmp" in PATH_EXEC. We hardcode
767 "emacs" in "emacs.pdmp" so that the Emacs binary still works
768 if the user copies and renames it.
769
770 FIXME: this doesn't work with emacs-XX.YY.ZZ.pdmp versioned files. */
771#ifdef WINDOWSNT 765#ifdef WINDOWSNT
772 /* On MS-Windows, PATH_EXEC normally starts with a literal 766 /* On MS-Windows, PATH_EXEC normally starts with a literal
773 "%emacs_dir%", so it will never work without some tweaking. */ 767 "%emacs_dir%", so it will never work without some tweaking. */
774 path_exec = w32_relocate (path_exec); 768 path_exec = w32_relocate (path_exec);
775#endif 769#endif
770
771 /* Look for "emacs.pdmp" in PATH_EXEC. We hardcode "emacs" in
772 "emacs.pdmp" so that the Emacs binary still works if the user
773 copies and renames it. */
774 const char *argv0_base = "emacs";
776 dump_file = alloca (strlen (path_exec) 775 dump_file = alloca (strlen (path_exec)
777 + 1 776 + 1
778 + strlen (argv0_base) 777 + strlen (argv0_base)
@@ -781,6 +780,40 @@ load_pdump (int argc, char **argv)
781 sprintf (dump_file, "%s%c%s%s", 780 sprintf (dump_file, "%s%c%s%s",
782 path_exec, DIRECTORY_SEP, argv0_base, suffix); 781 path_exec, DIRECTORY_SEP, argv0_base, suffix);
783 result = pdumper_load (dump_file); 782 result = pdumper_load (dump_file);
783
784 if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
785 fatal ("could not load dump file \"%s\": %s",
786 dump_file, dump_error_to_string (result));
787 if (result != PDUMPER_LOAD_SUCCESS)
788 {
789 /* Finally, look for basename(argv[0])+".pdmp" in PATH_EXEC.
790 This way, they can rename both the executable and its pdump
791 file in PATH_EXEC, and have several Emacs configurations in
792 the same versioned libexec subdirectory. */
793 char *p, *last_sep = NULL;
794 for (p = argv[0]; *p; p++)
795 {
796 if (IS_DIRECTORY_SEP (*p))
797 last_sep = p;
798 }
799 argv0_base = last_sep ? last_sep + 1 : argv[0];
800 dump_file = alloca (strlen (path_exec)
801 + 1
802 + strlen (argv0_base)
803 + strlen (suffix)
804 + 1);
805#ifdef DOS_NT
806 argv0_len = strlen (argv0_base);
807 if (argv0_len >= 4
808 && c_strcasecmp (argv0_base + argv0_len - 4, ".exe") == 0)
809 sprintf (dump_file, "%s%c%.*s%s", path_exec, DIRECTORY_SEP,
810 (int)(argv0_len - 4), argv0_base, suffix);
811 else
812#endif
813 sprintf (dump_file, "%s%c%s%s",
814 path_exec, DIRECTORY_SEP, argv0_base, suffix);
815 result = pdumper_load (dump_file);
816 }
784 if (result != PDUMPER_LOAD_SUCCESS) 817 if (result != PDUMPER_LOAD_SUCCESS)
785 dump_file = NULL; 818 dump_file = NULL;
786 819
@@ -982,6 +1015,10 @@ main (int argc, char **argv)
982 } 1015 }
983 1016
984 emacs_wd = emacs_get_current_dir_name (); 1017 emacs_wd = emacs_get_current_dir_name ();
1018#ifdef HAVE_PDUMPER
1019 if (dumped_with_pdumper_p ())
1020 pdumper_record_wd (emacs_wd);
1021#endif
985 1022
986 if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args)) 1023 if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
987 { 1024 {
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'.")
1626} 1626}
1627#endif 1627#endif
1628 1628
1629static bool 1629bool
1630file_name_absolute_p (const char *filename) 1630file_name_absolute_p (const char *filename)
1631{ 1631{
1632 return 1632 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);
4224/* Defined in fileio.c. */ 4224/* Defined in fileio.c. */
4225 4225
4226extern char *splice_dir_file (char *, char const *, char const *); 4226extern char *splice_dir_file (char *, char const *, char const *);
4227extern bool file_name_absolute_p (const char *);
4227extern char const *get_homedir (void); 4228extern char const *get_homedir (void);
4228extern Lisp_Object expand_and_dir_to_file (Lisp_Object); 4229extern Lisp_Object expand_and_dir_to_file (Lisp_Object);
4229extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, 4230extern 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)
5471 } 5471 }
5472 5472
5473 err = PDUMPER_LOAD_OOM; 5473 err = PDUMPER_LOAD_OOM;
5474 dump_filename_copy = strdup (dump_filename); 5474 dump_filename_copy = xstrdup (dump_filename);
5475 if (!dump_filename_copy) 5475 if (!dump_filename_copy)
5476 goto out; 5476 goto out;
5477 5477
@@ -5556,10 +5556,24 @@ pdumper_load (const char *dump_filename)
5556 dump_bitset_destroy (&mark_bits); 5556 dump_bitset_destroy (&mark_bits);
5557 if (dump_fd >= 0) 5557 if (dump_fd >= 0)
5558 emacs_close (dump_fd); 5558 emacs_close (dump_fd);
5559 free (dump_filename_copy);
5560 return err; 5559 return err;
5561} 5560}
5562 5561
5562/* Prepend the Emacs startup directory to dump_filename, if that is
5563 relative, so that we could later make it absolute correctly. */
5564void
5565pdumper_record_wd (const char *wd)
5566{
5567 if (wd && !file_name_absolute_p (dump_private.dump_filename))
5568 {
5569 char *dfn = xmalloc (strlen (wd) + 1
5570 + strlen (dump_private.dump_filename) + 1);
5571 splice_dir_file (dfn, wd, dump_private.dump_filename);
5572 xfree (dump_private.dump_filename);
5573 dump_private.dump_filename = dfn;
5574 }
5575}
5576
5563DEFUN ("pdumper-stats", Fpdumper_stats, Spdumper_stats, 0, 0, 0, 5577DEFUN ("pdumper-stats", Fpdumper_stats, Spdumper_stats, 0, 0, 0,
5564 doc: /* Return statistics about portable dumping used by this session. 5578 doc: /* Return statistics about portable dumping used by this session.
5565If this Emacs sesion was started from a portable dump file, 5579If 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.*/)
5579#ifdef WINDOWSNT 5593#ifdef WINDOWSNT
5580 char dump_fn_utf8[MAX_UTF8_PATH]; 5594 char dump_fn_utf8[MAX_UTF8_PATH];
5581 if (filename_from_ansi (dump_private.dump_filename, dump_fn_utf8) == 0) 5595 if (filename_from_ansi (dump_private.dump_filename, dump_fn_utf8) == 0)
5582 { 5596 dump_fn = DECODE_FILE (build_unibyte_string (dump_fn_utf8));
5583 dostounix_filename (dump_fn_utf8);
5584 dump_fn = DECODE_FILE (build_unibyte_string (dump_fn_utf8));
5585 }
5586 else 5597 else
5587 dump_fn = build_unibyte_string (dump_private.dump_filename); 5598 dump_fn = build_unibyte_string (dump_private.dump_filename);
5588#else 5599#else
5589 dump_fn = DECODE_FILE (build_unibyte_string (dump_private.dump_filename)); 5600 dump_fn = DECODE_FILE (build_unibyte_string (dump_private.dump_filename));
5590#endif 5601#endif
5591 5602
5603 dump_fn = Fexpand_file_name (dump_fn, Qnil);
5604
5592 return CALLN (Flist, 5605 return CALLN (Flist,
5593 Fcons (Qdumped_with_pdumper, Qt), 5606 Fcons (Qdumped_with_pdumper, Qt),
5594 Fcons (Qload_time, make_float (dump_private.load_time)), 5607 Fcons (Qload_time, make_float (dump_private.load_time)),
5595 /* FIXME: dump_fn should be expanded relative to the
5596 original pwd where Emacs started. */
5597 Fcons (Qdump_file_name, dump_fn)); 5608 Fcons (Qdump_file_name, dump_fn));
5598} 5609}
5599 5610
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)
260 and execution should resume. */ 260 and execution should resume. */
261bool pdumper_handle_page_fault (void *fault_addr_ptr); 261bool pdumper_handle_page_fault (void *fault_addr_ptr);
262 262
263/* Record the Emacs startup directory, relative to which the pdump
264 file was loaded. */
265extern void pdumper_record_wd (const char *);
266
263void syms_of_pdumper (void); 267void syms_of_pdumper (void);
264 268
265INLINE_HEADER_END 269INLINE_HEADER_END