commit 0aece3e1181e66f2a1a067ae876e55bdaa45edd5 (HEAD, refs/remotes/origin/master) Author: Martin Rudalics Date: Thu Jan 17 10:21:07 2019 +0100 Expand spectrum of window change functions * src/window.c (run_window_change_functions): Run window change functions for Qwindow_state_change_functions. (resize_frame_windows): Set frame's window_change slot when single-window frames change size. (Qwindow_state_change_functions): New symbol. (Vwindow_state_change_functions): New Lisp variable. * doc/lispref/windows.texi (Selecting Windows): Mention 'window-selection/state-change-functions' and add reference to Window Hooks. (Window Hooks): Document 'window-state-change-functions'. * etc/NEWS: Mention new hook 'window-state-change-functions'. diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 6b5aa66a95..afb81e6874 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -1758,7 +1758,7 @@ raise the frame or make sure input focus is directed to that frame. @xref{Input Focus}. @end defun -@cindex select window hook +@cindex select window hooks @cindex running a hook when a window gets selected For historical reasons, Emacs does not run a separate hook whenever a window gets selected. Applications and internal routines often @@ -1774,8 +1774,8 @@ useful. However, when its @var{norecord} argument is @code{nil}, @code{select-window} updates the buffer list and thus indirectly runs the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}). -Consequently, that hook provides a reasonable way to run a function -whenever a window gets selected more ``permanently''. +Consequently, that hook provides one way to run a function whenever a +window gets selected more ``permanently''. Since @code{buffer-list-update-hook} is also run by functions that are not related to window management, it will usually make sense to save the @@ -1787,6 +1787,13 @@ temporarily passes a non-@code{nil} @var{norecord} argument. If possible, the macro @code{with-selected-window} (see below) should be used in such cases. + Emacs also runs the hook @code{window-selection-change-functions} +whenever the redisplay routine detects that another window has been +selected since last redisplay. @xref{Window Hooks}, for a detailed +explanation. @code{window-state-change-functions} (described in the +same section) is another abnormal hook run after a different window +has been selected but is triggered by other window changes as well. + @cindex most recently selected windows The sequence of calls to @code{select-window} with a non-@code{nil} @var{norecord} argument determines an ordering of windows by their @@ -6039,7 +6046,7 @@ buffer are (re)fontified because a window was scrolled or its size changed. @xref{Other Font Lock Variables}. @cindex window change functions - The remainder of this section covers four hooks that are called at + The remainder of this section covers five hooks that are called at the end of redisplay provided a significant, non-scrolling change of a window has been detected. For simplicity, these hooks and the functions they call will be collectively referred to as @dfn{window @@ -6108,10 +6115,37 @@ window has changed since the last time window change functions were run. In this case the frame is passed as argument. @end defvar +@cindex window state change +The fourth of these hooks is run after a @dfn{window state change} has +been detected, which means that at least one of the three preceding +window changes has occurred. + +@defvar window-state-change-functions +This variable specifies functions called at the end of redisplay when +a window buffer or size change occurred or the selected window or a +frame's selected window has changed. The value should be a list of +functions that take one argument. + +Functions specified buffer-locally are called for any window showing +the corresponding buffer if that window has been added or assigned +another buffer, total or body size or has been selected or deselected +(among all windows or among all windows on its frame) since the last +time window change functions were run. In this case the window is +passed as argument. + +Functions specified by the default value are called for a frame if at +least one window on that frame has been added, deleted or assigned +another buffer, total or body size or that frame has been selected or +deselected or the frame's selected window has changed since the last +time window change functions were run. In this case the frame is +passed as argument. +@end defvar + @cindex window configuration change -The fourth of these hooks is run when a @dfn{window configuration +The fifth of these hooks is run when a @dfn{window configuration change} has been detected which means that either the buffer or the -size of a window changed. +size of a window changed. It differs from the four preceding hooks in +the way it is run. @defvar window-configuration-change-hook This variable specifies functions called at the end of redisplay when diff --git a/etc/NEWS b/etc/NEWS index 02503073c1..10bcc5a2ec 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1303,14 +1303,17 @@ of the Emacs Lisp Reference manual for more detail. +++ ** Window change functions have been redesigned completely. + Hooks reacting to window changes run now only when redisplay detects -that a change has actually occurred. The four hooks provided are: +that a change has actually occurred. The five hooks provided are: 'window-buffer-change-functions' (run after window buffers have changed), 'window-size-change-functions' (run after a window was assigned a new buffer or size), 'window-configuration-change-hook' -(like the former but run also when a window was deleted) and +(like the former but run also when a window was deleted), 'window-selection-change-functions' (run when the selected window -changed). 'window-scroll-functions' are unaffected by these changes. +changed) and 'window-state-change-functions' (run when any of the +preceding ones is run). 'window-scroll-functions' are unaffected by +these changes. In addition, a number of functions now allow the caller to detect what has changed since last redisplay: 'window-old-buffer' returns for any diff --git a/src/window.c b/src/window.c index 7eb532f78c..c0d745995a 100644 --- a/src/window.c +++ b/src/window.c @@ -3799,7 +3799,7 @@ run_window_change_functions (void) run_window_change_functions_1 (Qwindow_size_change_functions, buffer, window); - /* This window's selection has changed when it it was + /* This window's selection has changed when it was (de-)selected as its frame's or the globally selected window. */ if (((frame_selected_change @@ -3811,6 +3811,21 @@ run_window_change_functions (void) && WINDOW_LIVE_P (window)) run_window_change_functions_1 (Qwindow_selection_change_functions, buffer, window); + + /* This window's state has changed when its buffer or size + changed or it was (de-)selected as its frame's or the + globally selected window. */ + if ((window_buffer_change + || window_size_change + || ((frame_selected_change + && (EQ (window, old_selected_window) + || EQ (window, selected_window))) + || (frame_selected_window_change + && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) + || EQ (window, FRAME_SELECTED_WINDOW (f)))))) + && WINDOW_LIVE_P (window)) + run_window_change_functions_1 + (Qwindow_state_change_functions, buffer, window); } /* When the number of windows on a frame has decreased, at least @@ -3840,6 +3855,15 @@ run_window_change_functions (void) run_window_change_functions_1 (Qwindow_selection_change_functions, Qnil, frame); + /* A frame has changed state when a size or buffer change + occurrd or its selected window has changed or when it was + (de-)selected. */ + if ((frame_selected_change || frame_selected_window_change + || frame_buffer_change || window_deleted || frame_size_change) + && FRAME_LIVE_P (f)) + run_window_change_functions_1 + (Qwindow_state_change_functions, Qnil, frame); + /* A frame's configuration changed when one of its windows has changed buffer or size or at least one window was deleted. */ if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f)) @@ -4650,16 +4674,26 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) /* For a leaf root window just set the size. */ if (horflag) { + bool changed = r->pixel_width != new_pixel_size; + r->total_cols = new_size; r->pixel_width = new_pixel_size; + + if (changed && !WINDOW_PSEUDO_P (r)) + FRAME_WINDOW_CHANGE (f) = true; } else { + bool changed = r->pixel_height != new_pixel_size; + r->top_line = FRAME_TOP_MARGIN (f); r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); r->total_lines = new_size; r->pixel_height = new_pixel_size; + + if (changed && !WINDOW_PSEUDO_P (r)) + FRAME_WINDOW_CHANGE (f) = true; } else { @@ -7953,6 +7987,7 @@ syms_of_window (void) Fput (Qscroll_down, Qscroll_command, Qt); DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook"); + DEFSYM (Qwindow_state_change_functions, "window-state-change-functions"); DEFSYM (Qwindow_size_change_functions, "window-size-change-functions"); DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions"); DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions"); @@ -8074,6 +8109,22 @@ the frame's selected window has changed since the last redisplay. In this case the frame is passed as argument. */); Vwindow_selection_change_functions = Qnil; + DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions, + doc: /* Functions called during redisplay when the window state changed. +The value should be a list of functions that take one argument. + +Functions specified buffer-locally are called for each window showing +the corresponding buffer if and only if that window has been added, +resized, changed its buffer or has been (de-)selected since the last +redisplay. In this case the window is passed as argument. + +Functions specified by the default value are called for each frame if +at least one window on that frame has been added, deleted, changed its +buffer or its total or body size or the frame has been (de-)selected +or its selected window has changed since the last redisplay. In this +case the frame is passed as argument. */); + Vwindow_selection_change_functions = Qnil; + DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook, doc: /* Functions called during redisplay when window configuration has changed. The value should be a list of functions that take no argument. commit 978cf88bda9c9b41f1cc20cf8e53a9e6caeb91be Author: Paul Eggert Date: Wed Jan 16 17:34:45 2019 -0800 Port pdumper to older GNU/Linux Problem reported by Colin Baxter in: https://lists.gnu.org/r/emacs-devel/2019-01/msg00321.html * src/alloc.c (my_heap_start): Also define if GNU_LINUX && CANNOT_DUMP && DOUG_LEA_MALLOC. diff --git a/src/alloc.c b/src/alloc.c index 8054aa5ae5..5ea466beca 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -103,24 +103,12 @@ along with GNU Emacs. If not, see . */ #include "w32heap.h" /* for sbrk */ #endif -#if defined GNU_LINUX && !defined CANNOT_DUMP -/* The address where the heap starts. */ -void * -my_heap_start (void) -{ - static void *start; - if (! start) - start = sbrk (0); - return start; -} -#endif - #ifdef DOUG_LEA_MALLOC /* Specify maximum number of areas to mmap. It would be nice to use a value that explicitly means "no limit". */ -#define MMAP_MAX_AREAS 100000000 +# define MMAP_MAX_AREAS 100000000 /* A pointer to the memory allocated that copies that static data inside glibc's malloc. */ @@ -136,9 +124,9 @@ malloc_initialize_hook (void) if (! initialized) { -#ifdef GNU_LINUX +# ifdef GNU_LINUX my_heap_start (); -#endif +# endif malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL; } else @@ -201,6 +189,20 @@ alloc_unexec_post (void) free (malloc_state_ptr); # endif } + +# ifdef GNU_LINUX + +/* The address where the heap starts. */ +void * +my_heap_start (void) +{ + static void *start; + if (! start) + start = sbrk (0); + return start; +} +# endif + #endif /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer commit 191a5568db35f3a56f26431ca4722175d38c684f Author: Daniel Colascione Date: Wed Jan 16 20:26:19 2019 -0500 Fix segfault in profiler after pdump load Move initialization of the profiler's hash test to static initialization from the syms function so that pdumper doesn't need to bother capturing it in any special way. * src/profiler.c (cmpfn_profiler, hashfn_profiler): forward declare. (hashtest_profiler): statically initialize. (syms_of_profiler): remove dynamic initialization of hashtest_profiler. diff --git a/src/profiler.c b/src/profiler.c index 76245750ad..a98d967b2a 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -36,7 +36,20 @@ saturated_add (EMACS_INT a, EMACS_INT b) typedef struct Lisp_Hash_Table log_t; -static struct hash_table_test hashtest_profiler; +static bool cmpfn_profiler ( + struct hash_table_test *, Lisp_Object, Lisp_Object); + +static EMACS_UINT hashfn_profiler ( + struct hash_table_test *, Lisp_Object); + +static const struct hash_table_test hashtest_profiler = + { + LISPSYM_INITIALLY (Qprofiler_backtrace_equal), + LISPSYM_INITIALLY (Qnil) /* user_hash_function */, + LISPSYM_INITIALLY (Qnil) /* user_cmp_function */, + cmpfn_profiler, + hashfn_profiler, + }; static Lisp_Object make_log (EMACS_INT heap_size, EMACS_INT max_stack_depth) @@ -587,12 +600,6 @@ to make room for new entries. */); DEFSYM (Qprofiler_backtrace_equal, "profiler-backtrace-equal"); - hashtest_profiler.name = Qprofiler_backtrace_equal; - hashtest_profiler.user_hash_function = Qnil; - hashtest_profiler.user_cmp_function = Qnil; - hashtest_profiler.cmpfn = cmpfn_profiler; - hashtest_profiler.hashfn = hashfn_profiler; - defsubr (&Sfunction_equal); #ifdef PROFILER_CPU_SUPPORT commit 27f53bd6886c1a76ac7058ae7b90cacc317aadea Author: Paul Eggert Date: Wed Jan 16 10:31:21 2019 -0800 * doc/lispref/processes.texi (Accepting Output): Simplify. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index afda8aede8..fd6686e882 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1870,13 +1870,13 @@ process has exited. Therefore, although the following loop: @end example @noindent -will often work, it has a race condition and can miss some output if -@code{process-live-p} returns @code{nil} while the connection still -contains data. Better is to write the loop like this: +will often read all output from @var{process}, it has a race condition +and can miss some output if @code{process-live-p} returns @code{nil} +while the connection still contains data. Better is to write the loop +like this: @example -(while (or (accept-process-output process) - (process-live-p process))) +(while (accept-process-output process)) @end example @node Processes and Threads commit 3fd369becdc3854e8d81b25b2241e2cd252eea16 Author: Daniel Colascione Date: Wed Jan 16 14:44:45 2019 -0500 Fix previous change: use correct pdumper function diff --git a/src/coding.c b/src/coding.c index 441c85f81a..6de8dcd1ff 100644 --- a/src/coding.c +++ b/src/coding.c @@ -11319,7 +11319,7 @@ internal character representation. */); #endif staticpro (&system_eol_type); - pdumper_do_now_and_after_load_impl (reset_coding_after_pdumper_load); + pdumper_do_now_and_after_load (reset_coding_after_pdumper_load); } static void commit ece563e8eda4aac77923df13c5e8e8032c69b9b3 Author: Daniel Colascione Date: Wed Jan 16 14:37:21 2019 -0500 Fix crash in charset detection after pdumper load * src/coding.c: (reset_coding_after_pdumper_load): new function re-init character classes after pdumper load. (syms_of_coding): Call it. diff --git a/src/coding.c b/src/coding.c index 665aefa34c..441c85f81a 100644 --- a/src/coding.c +++ b/src/coding.c @@ -10774,6 +10774,8 @@ init_coding_once (void) PDUMPER_REMEMBER_SCALAR (emacs_mule_bytes); } +static void reset_coding_after_pdumper_load (void); + void syms_of_coding (void) { @@ -11316,4 +11318,27 @@ internal character representation. */); system_eol_type = Qunix; #endif staticpro (&system_eol_type); + + pdumper_do_now_and_after_load_impl (reset_coding_after_pdumper_load); +} + +static void +reset_coding_after_pdumper_load (void) +{ + if (!dumped_with_pdumper_p ()) + return; + for (struct coding_system *this = &coding_categories[0]; + this < &coding_categories[coding_category_max]; + ++this) + { + int id = this->id; + if (id >= 0) + { + /* Need to rebuild the coding system object because we + persisted it as a scalar and it's full of gunk that's now + invalid. */ + memset (this, 0, sizeof (*this)); + setup_coding_system (CODING_ID_NAME (id), this); + } + } } commit 8bf51c380acc04f25fba8f8aa3d1cc08b45f3e69 Author: Andy Moreton Date: Wed Jan 16 17:44:10 2019 +0000 Avoid compilation warnings in MS-Windows build * src/pdumper.c (dump_cold_bignum): * src/emacs.c(load_pdump) [WINDOWSNT]: Avoid compiler warnings due to 64-bit vs 32-bit data type mismatches. diff --git a/src/emacs.c b/src/emacs.c index c1133f2460..834f55b6f3 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -749,7 +749,7 @@ load_pdump (int argc, char **argv) /* Remove the .exe extension if present. */ argv0_len = strlen (argv[0]); if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0) - sprintf (dump_file, "%.*s%s", argv0_len - 4, argv[0], suffix); + sprintf (dump_file, "%.*s%s", (int)(argv0_len - 4), argv[0], suffix); else #endif sprintf (dump_file, "%s%s", argv[0], suffix); diff --git a/src/pdumper.c b/src/pdumper.c index 3787408e6d..db66e1ba26 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -3442,7 +3442,7 @@ dump_cold_bignum (struct dump_context *ctx, Lisp_Object object) dump_off_to_lisp ((mpz_sgn (bignum->value) < 0 ? -nlimbs : nlimbs))); Fputhash (object, descriptor, ctx->bignum_data); - for (size_t i = 0; i < nlimbs; ++i) + for (mp_size_t i = 0; i < nlimbs; ++i) { mp_limb_t limb = mpz_getlimbn (bignum->value, i); dump_write (ctx, &limb, sizeof (limb)); commit ebd174e218f46e2d3e30646a8426f6ec1ae9e8d1 Author: Eli Zaretskii Date: Wed Jan 16 17:55:53 2019 +0200 Improve documentation of pdumper; minor code cleanup * src/emacs.c (usage_message): Add the --dump-file option. (string_starts_with_p, find_argument): Functions removed; use 'argmatch' instead. (PDUMP_FILE_ARG): Macro removed; use literal strings instead, as with other command-line options. Use HAVE_PDUMPER for cpp conditionals which used PDUMP_FILE_ARG. (load_pdump, main): Use 'argmatch' for "--dump-file" and "--temacs" arguments, thus supporting the "-dump-file" and "-temacs" variants, for consistency with other options. (main): Remove the extra fatal error for using --dump-file in unexec'ed Emacs: load_pdump does that anyway. (standard_args): Add --dump-file and --temacs, with appropriate priorities. * etc/NEWS: Expand on the pdumper support. * doc/emacs/cmdargs.texi (Initial Options): Document the '--dump-file' command-line option. diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index d51d97b48a..b49126764a 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -383,6 +383,17 @@ verify that their module conforms to the module API requirements. The option makes Emacs abort if a module-related assertion triggers. @xref{Writing Dynamic Modules,, Writing Dynamically-Loaded Modules, 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 +that file. @end table @node Command Example diff --git a/etc/NEWS b/etc/NEWS index 5af0c1fab0..02503073c1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -59,10 +59,24 @@ option '--enable-check-lisp-object-type' is therefore no longer as useful and so is no longer enabled by default in developer builds, to reduce differences between developer and production builds. -** Emacs by default uses a "portable dumper" instead of unexec, -improving compatibility with modern systems and supporting ASLR. -Emacs now needs an "emacs.pdmp" file, generated during the built, in -its data directory at runtime. ++++ +** Emacs now uses a "portable dumper" instead of unexec. +This improves compatibility with memory allocation on modern systems, +and in particular better supports the Address Space Layout +Randomization (ASLR) feature, a security technique used by most modern +operating systems. + +Portable dumping can be disabled at configure time via the configure +option '--with-pdumper=no' (but we don't recommend that, unless the +portable dumping doesn't work on your system for some reason---please +report such systems to the Emacs developers as bugs). + +When built with the portable dumping support (which is the default), +Emacs looks for the 'emacs.pdmp' file, generated during the build, in +its data directory at startup, and loads the dumped state from there. +The new command-line argument '--dump-file=FILE' allows to specify a +non-default '.pdmp' file to load the state from; see the node "Initial +Options" in the Emacs manual for more information. ** Ibuffer diff --git a/src/emacs.c b/src/emacs.c index 9c88b6e3f1..c1133f2460 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -230,6 +230,11 @@ Initialization options:\n\ "\ --module-assertions assert behavior of dynamic modules\n\ ", +#endif +#ifdef HAVE_PDUMPER + "\ +--dump-file FILE read dumped state from FILE\n\ +", #endif "\ --no-build-details do not add build details such as time stamps\n\ @@ -650,43 +655,6 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr, } } -static bool -string_starts_with_p (const char* string, const char* prefix) -{ - return strncmp (string, prefix, strlen (prefix)) == 0; -} - -/* Return the value of GNU-style long argument ARGUMENT if given on - command line. ARGUMENT must begin with "-". If ARGUMENT is not - given, return NULL. */ -static char * -find_argument (const char *argument, int argc, char **argv) -{ - char *found = NULL; - int i; - - eassert (argument[0] == '-'); - - for (i = 1; i < argc; ++i) - if (string_starts_with_p (argv[i], argument) && - ((argv[i] + strlen (argument))[0] == '=' || - (argv[i] + strlen (argument))[0] == '\0')) - { - int j = i; - found = argv[j++] + strlen (argument); - if (*found == '=') - ++found; - else if (i < argc) - found = argv[j++]; - else - fatal ("no argument given for %s", argument); - break; - } - else if (strcmp (argv[i], "--") == 0) - break; - return found; -} - /* Close standard output and standard error, reporting any write errors as best we can. This is intended for use with atexit. */ static void @@ -731,8 +699,6 @@ dump_error_to_string (enum pdumper_load_result result) } } -#define PDUMP_FILE_ARG "--dump-file" - static enum pdumper_load_result load_pdump (int argc, char **argv) { @@ -753,7 +719,16 @@ load_pdump (int argc, char **argv) /* Look for an explicitly-specified dump file. */ const char *path_exec = PATH_EXEC; - char *dump_file = find_argument (PDUMP_FILE_ARG, argc, argv); + char *dump_file = NULL; + int skip_args = 0; + while (skip_args < argc - 1) + { + if (argmatch (argv, argc, "-dump-file", "--dump-file", 6, + &dump_file, &skip_args) + || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args)) + break; + skip_args++; + } result = PDUMPER_NOT_LOADED; if (dump_file) @@ -822,7 +797,6 @@ main (int argc, char **argv) void *stack_bottom_variable; bool do_initial_setlocale; - int skip_args = 0; bool no_loadup = false; char *junk = 0; char *dname_arg = 0; @@ -838,7 +812,15 @@ main (int argc, char **argv) stack_bottom = (char *) &stack_bottom_variable; const char *dump_mode = NULL; - const char *temacs = find_argument ("--temacs", argc, argv); + int skip_args = 0; + char *temacs = NULL; + while (skip_args < argc - 1) + { + if (argmatch (argv, argc, "-temacs", "--temacs", 8, &temacs, &skip_args) + || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args)) + break; + skip_args++; + } #ifdef HAVE_PDUMPER bool attempt_load_pdump = false; #endif @@ -874,18 +856,11 @@ main (int argc, char **argv) { fatal ("--temacs not supported for unexeced emacs"); } - else if (initialized) - { -#ifdef HAVE_PDUMPER - if (find_argument (PDUMP_FILE_ARG, argc, argv)) - fatal ("%s not supported in unexeced emacs", PDUMP_FILE_ARG); -#endif - } else { eassert (!initialized); eassert (!temacs); -#ifdef PDUMP_FILE_ARG +#ifdef HAVE_PDUMPER attempt_load_pdump = true; #endif } @@ -948,6 +923,7 @@ main (int argc, char **argv) argc = 0; while (argv[argc]) argc++; + skip_args = 0; if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args)) { const char *version, *copyright; @@ -1992,6 +1968,12 @@ static const struct standard_args standard_args[] = { "-color", "--color", 5, 0}, { "-no-splash", "--no-splash", 3, 0 }, { "-no-desktop", "--no-desktop", 3, 0 }, + /* The following two must be just above the file-name args, to get + them out of our way, but without mixing them with file names. */ + { "-temacs", "--temacs", 1, 1 }, +#ifdef HAVE_PDUMPER + { "-dump-file", "--dump-file", 1, 1 }, +#endif #ifdef HAVE_NS { "-NSAutoLaunch", 0, 5, 1 }, { "-NXAutoLaunch", 0, 5, 1 }, commit e96a54eb3bdfd75bafbe795ec6dd7b94ff65b8ac Author: Eli Zaretskii Date: Wed Jan 16 17:26:15 2019 +0200 Fix minor glitch with producing 'emacs' executable * src/Makefile.in (LC_ALL) [!DUMPING]: Don't overwrite previous emacs-X.Y.Z executables with new ones. diff --git a/src/Makefile.in b/src/Makefile.in index 980bd6d10e..1d6faf9c53 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -564,7 +564,7 @@ ifeq ($(DUMPING),unexec) endif cp -f $@ bootstrap-emacs$(EXEEXT) else - cp -f temacs$(EXEEXT) emacs$(EXEEXT) + rm -f $@ && cp -f temacs$(EXEEXT) $@ endif ifeq ($(DUMPING),pdumper) commit 8832de4f937aafdc58f5fa5a07b3aca549314901 Merge: b2497ef695 655badc33e Author: Michael Albinus Date: Wed Jan 16 13:57:00 2019 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit b2497ef6952134022ad799247bc5a31f7559ef87 Author: Michael Albinus Date: Wed Jan 16 13:56:38 2019 +0100 Some accept-process-output cleanups in Tramp * lisp/net/tramp.el (tramp-action-out-of-band): Read process output in a loop. (tramp-accept-process-output): Return result. (tramp-interrupt-process): * lisp/net/tramp-adb.el (tramp-adb-parse-device-names): * lisp/net/tramp-rclone.el (tramp-rclone-parse-device-names): Remove FIXME. * lisp/net/tramp-sh.el (tramp-local-coding-commands): Fix docstring. * lisp/net/tramp-smb.el (tramp-smb-wait-for-output): Adapt docstring. Simplify code. * lisp/net/tramp-sudoedit.el (tramp-sudoedit-action-sudo): Adapt docstring. Read process output in a loop. * test/lisp/net/tramp-tests.el (tramp-test43-asynchronous-requests): Remove :unstable tag on emba. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index ca47601e4b..0a357e1ae2 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -206,7 +206,6 @@ pass to the OPERATION." (tramp-message v 6 "%s" (mapconcat 'identity (process-command p) " ")) (process-put p 'adjust-window-size-function 'ignore) (set-process-query-on-exit-flag p nil) - ;; FIXME: Either remove " 0.1", or comment why it's needed. (while (or (accept-process-output p 0.1) (process-live-p p))) (tramp-message v 6 "\n%s" (buffer-string)) @@ -471,7 +470,7 @@ Convert (\"-al\") to (\"-a\" \"-l\"). Remove arguments like \"--dired\"." (apply 'concat (mapcar (lambda (s) (replace-regexp-in-string - "\\(.\\)" " -\\1" (replace-regexp-in-string "^-" "" s))) + "\\(.\\)" " -\\1" (replace-regexp-in-string "^-" "" s))) ;; FIXME: Warning about removed switches (long and non-dash). (delq nil (mapcar @@ -590,7 +589,7 @@ Emacs dired can't find files." (delq nil (mapcar - (lambda (l) (and (not (string-match-p "^[[:space:]]*$" l)) l)) + (lambda (l) (and (not (string-match-p "^[[:space:]]*$" l)) l)) (split-string (buffer-string) "\n"))))))))))) (defun tramp-adb-handle-file-local-copy (filename) @@ -1327,7 +1326,7 @@ connection if a previous connection has died for some reason." ;; Wait for initial prompt. (tramp-adb-wait-for-output p 30) (unless (process-live-p p) - (tramp-error vec 'file-error "Terminated!")) + (tramp-error vec 'file-error "Terminated!")) (process-put p 'vector vec) (process-put p 'adjust-window-size-function 'ignore) (set-process-query-on-exit-flag p nil) diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 7366057296..f5d184af69 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -183,7 +183,6 @@ pass to the OPERATION." (tramp-message v 6 "%s" (mapconcat 'identity (process-command p) " ")) (process-put p 'adjust-window-size-function 'ignore) (set-process-query-on-exit-flag p nil) - ;; FIXME: Either remove " 0.1", or comment why it's needed. (while (or (accept-process-output p 0.1) (process-live-p p))) (tramp-message v 6 "\n%s" (buffer-string)) @@ -461,7 +460,7 @@ file names." (expand-file-name (concat tramp-temp-name-prefix (tramp-file-name-method vec) - "." (tramp-file-name-host vec)) + "." (tramp-file-name-host vec)) (tramp-compat-temporary-file-directory))) (defun tramp-rclone-mounted-p (vec) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 134ae7a201..022ecb3d79 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4340,7 +4340,7 @@ Each item is a list that looks like this: \(FORMAT ENCODING DECODING) -FORMAT is symbol describing the encoding/decoding format. It can be +FORMAT is a symbol describing the encoding/decoding format. It can be `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing. ENCODING and DECODING can be strings, giving commands, or symbols, @@ -4722,7 +4722,7 @@ Goes through the list `tramp-inline-compress-commands'." (ignore-errors (when (executable-find "ssh") (with-tramp-progress-reporter - vec 4 "Computing ControlMaster options" + vec 4 "Computing ControlMaster options" (with-temp-buffer (tramp-call-process vec "ssh" nil t nil "-o" "ControlMaster") (goto-char (point-min)) @@ -5933,5 +5933,9 @@ function cell is returned to be applied on a buffer." ;; which could immediately be passed on to the remote side, and ;; later on checks the return value of those calls as and when ;; needed. (Stefan Monnier) +;; +;; * Implement detaching/re-attaching remote sessions. By this, a +;; session could be reused after a connection loss. Use dtach, or +;; screen, or tmux, or mosh. ;;; tramp-sh.el ends here diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index abf3248a35..8198930abc 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1087,7 +1087,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; Half a year. (time-since (nth 3 x)) (days-to-time 183)) "%b %e %R" - "%b %e %Y") + "%b %e %Y") (nth 3 x))))) ; date ;; We mark the file name. The inserted name could be @@ -2026,54 +2026,25 @@ If ARGUMENT is non-nil, use it as argument for ;; We don't use timeouts. If needed, the caller shall wrap around. (defun tramp-smb-wait-for-output (vec) "Wait for output from smbclient command. -Returns nil if an error message has appeared." +Removes smb prompt. Returns nil if an error message has appeared." (with-current-buffer (tramp-get-connection-buffer vec) (let ((p (get-buffer-process (current-buffer))) - (found (progn (goto-char (point-min)) - (re-search-forward tramp-smb-prompt nil t))) - (err (progn (goto-char (point-min)) - (re-search-forward tramp-smb-errors nil t))) buffer-read-only) - ;; Algorithm: get waiting output. See if last line contains - ;; `tramp-smb-prompt' sentinel or `tramp-smb-errors' strings. - ;; If not, wait a bit and again get waiting output. - ;; FIXME: Either remove " 0.1", or comment why it's needed. - (while (and (not found) (not err) - (or (tramp-accept-process-output p 0.1) - (process-live-p p))) - - ;; Search for prompt. - (goto-char (point-min)) - (setq found (re-search-forward tramp-smb-prompt nil t)) - - ;; Search for errors. - (goto-char (point-min)) - (setq err (re-search-forward tramp-smb-errors nil t))) - - ;; When the process is still alive, read pending output. - ;; FIXME: This loop should be folded into the previous loop. - ;; Also, ERR should be set just once, after the combined - ;; loop has finished. - ;; FIXME: Either remove " 0.1", or comment why it's needed. - (while (and (not found) - (or (tramp-accept-process-output p 0.1) - (process-live-p p))) - - ;; Search for prompt. - (goto-char (point-min)) - (setq found (re-search-forward tramp-smb-prompt nil t))) - + ;; Read pending output. + (while (tramp-accept-process-output p 0.1)) (tramp-message vec 6 "\n%s" (buffer-string)) ;; Remove prompt. - (when found + (goto-char (point-min)) + (when (re-search-forward tramp-smb-prompt nil t) (goto-char (point-max)) (re-search-backward tramp-smb-prompt nil t) (delete-region (point) (point-max))) ;; Return value is whether no error message has appeared. - (not err)))) + (goto-char (point-min)) + (not (re-search-forward tramp-smb-errors nil t))))) (defun tramp-smb-kill-winexe-function () "Send SIGKILL to the winexe process." diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index e1e5ab091a..ff3a7d7913 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -744,11 +744,10 @@ ID-FORMAT valid values are `string' and `integer'." ;; Used in `tramp-sudoedit-sudo-actions'. (defun tramp-sudoedit-action-sudo (proc vec) - "Check, whether a sudo process copy has finished." + "Check, whether a sudo process has finished. +Remove unneeded output." ;; There might be pending output for the exit status. - ;; FIXME: Either remove " 0.1", or comment why it's needed. - ;; FIXME: There's a race here. Shouldn't the next two lines be interchanged? - (tramp-accept-process-output proc 0.1) + (while (tramp-accept-process-output proc 0.1)) (when (not (process-live-p proc)) ;; Delete narrowed region, it would be in the way reading a Lisp form. (goto-char (point-min)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 7632d656a0..3b235095d3 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3457,7 +3457,7 @@ User is always nil." start (or (text-property-any start (point-at-eol) 'dired-filename t) (point-at-eol))) - (if (= (point-at-bol) (point-at-eol)) + (if (= (point-at-bol) (point-at-eol)) ;; Empty line. (delete-region (point) (progn (forward-line) (point))) (forward-line))))))))) @@ -3977,9 +3977,7 @@ The terminal type can be configured with `tramp-terminal-type'." (defun tramp-action-out-of-band (proc vec) "Check, whether an out-of-band copy has finished." ;; There might be pending output for the exit status. - ;; FIXME: Either remove " 0.1", or comment why it's needed. - ;; FIXME: Shouldn't the following line be wrapped inside (while ...)? - (tramp-accept-process-output proc 0.1) + (while (tramp-accept-process-output proc 0.1)) (cond ((and (not (process-live-p proc)) (zerop (process-exit-status proc))) (tramp-message vec 3 "Process has finished.") @@ -4087,7 +4085,8 @@ for process communication also." (with-current-buffer (process-buffer proc) (let (buffer-read-only last-coding-system-used ;; We do not want to run timers. - timer-list timer-idle-list) + timer-list timer-idle-list + result) ;; Under Windows XP, `accept-process-output' doesn't return ;; sometimes. So we add an additional timeout. JUST-THIS-ONE ;; is set due to Bug#12145. It is an integer, in order to avoid @@ -4095,9 +4094,10 @@ for process communication also." (tramp-message proc 10 "%s %s %s\n%s" proc (process-status proc) - (with-timeout (timeout) - (accept-process-output proc timeout nil 0)) - (buffer-string))))) + (setq result (with-timeout (timeout) + (accept-process-output proc timeout nil 0))) + (buffer-string)) + result))) (defun tramp-check-for-regexp (proc regexp) "Check, whether REGEXP is contained in process buffer of PROC. @@ -4641,7 +4641,7 @@ are written with verbosity of 6." It always returns a return code. The Lisp error raised when PROGRAM is nil is trapped also, returning 1. Furthermore, traces are written with verbosity of 6." - (let ((default-directory (tramp-compat-temporary-file-directory)) + (let ((default-directory (tramp-compat-temporary-file-directory)) (buffer (if (eq buffer t) (current-buffer) buffer)) result) (tramp-message @@ -4812,7 +4812,7 @@ Only works for Bourne-like shells." pid) ;; If it's a Tramp process, send the INT signal remotely. (when (and (processp proc) (setq pid (process-get proc 'remote-pid))) - (if (not (process-live-p proc)) + (if (not (process-live-p proc)) (tramp-error proc 'error "Process %s is not active" proc) (tramp-message proc 5 "Interrupt process %s with pid %s" proc pid) ;; This is for tramp-sh.el. Other backends do not support this (yet). @@ -4824,7 +4824,6 @@ Only works for Bourne-like shells." ;; fall back to the default implementation. (with-timeout (1 (ignore)) ;; We cannot run `tramp-accept-process-output', it blocks timers. - ;; FIXME: Either remove " 0.1", or comment why it's needed. (while (or (accept-process-output proc 0.1) (process-live-p proc))) ;; Report success. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index ff63dc18fb..2893506286 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -405,7 +405,7 @@ handled properly. BODY shall not contain a timeout." tramp-default-user-alist tramp-default-host-alist ;; Suppress check for multihops. - (tramp-cache-data (make-hash-table :test 'equal)) + (tramp-cache-data (make-hash-table :test 'equal)) (tramp-connection-properties '((nil "login-program" t)))) ;; Expand `tramp-default-user' and `tramp-default-host'. (should (string-equal @@ -844,7 +844,7 @@ handled properly. BODY shall not contain a timeout." tramp-default-user-alist tramp-default-host-alist ;; Suppress check for multihops. - (tramp-cache-data (make-hash-table :test 'equal)) + (tramp-cache-data (make-hash-table :test 'equal)) (tramp-connection-properties '((nil "login-program" t))) (syntax tramp-syntax)) (unwind-protect @@ -1168,7 +1168,7 @@ handled properly. BODY shall not contain a timeout." tramp-default-user-alist tramp-default-host-alist ;; Suppress check for multihops. - (tramp-cache-data (make-hash-table :test 'equal)) + (tramp-cache-data (make-hash-table :test 'equal)) (tramp-connection-properties '((nil "login-program" t))) (syntax tramp-syntax)) (unwind-protect @@ -5212,7 +5212,13 @@ Use the `ls' command." "Check parallel asynchronous requests. Such requests could arrive from timers, process filters and process sentinels. They shall not disturb each other." - :tags '(:expensive-test :unstable) + ;; The test fails from time to time, w/o a reproducible pattern. So + ;; we mark it as unstable. + ;; Recent investigations have uncovered a race condition in + ;; `accept-process-output'. Let's check on emba, whether this has + ;; been solved. + :tags + (if (getenv "EMACS_EMBA_CI") '(:expensive-test) '(:expensive-test :unstable)) (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p))