commit f9250c5ebc1730bf3bed4382549433f52f7ef9ca (HEAD, refs/remotes/origin/master) Author: Jim Porter Date: Mon Aug 22 09:53:24 2022 -0700 Handle 'eshell-pipe-broken' when evaluating Lisp forms in Eshell * lisp/eshell/esh-cmd.el (eshell-exec-lisp): Handle 'eshell-pipe-broken'. * lisp/eshell/esh-io.el (eshell-output-object-to-target): Only signal 'eshell-pipe-broken' if the process being written to has finished. * test/lisp/eshell/esh-proc-tests.el (esh-proc-test/pipeline-connection-type/middle) (esh-proc-test/pipeline-connection-type/last): Remove ':unstable'. Ref: https://lists.gnu.org/archive/html/emacs-devel/2022-08/msg00524.html diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 2f77f3f497..a43ad77213 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1347,6 +1347,15 @@ case." (apply func-or-form args))))) (and result (funcall printer result)) result) + (eshell-pipe-broken + ;; If FUNC-OR-FORM tried and failed to write some output to a + ;; process, it will raise an `eshell-pipe-broken' signal (this is + ;; analogous to SIGPIPE on POSIX systems). In this case, set the + ;; command status to some non-zero value to indicate an error; to + ;; match GNU/Linux, we use 141, which the numeric value of + ;; SIGPIPE on GNU/Linux (13) with the high bit (2^7) set. + (setq eshell-last-command-status 141) + nil) (error (setq eshell-last-command-status 1) (let ((msg (error-message-string err))) diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index e5977c9580..d54be55c13 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -498,10 +498,16 @@ Returns what was actually sent, or nil if nothing was sent." ((eshell-processp target) (unless (stringp object) (setq object (eshell-stringify object))) - (condition-case nil + (condition-case err (process-send-string target object) - ;; If `process-send-string' raises an error, treat it as a broken pipe. - (error (signal 'eshell-pipe-broken (list target))))) + (error + ;; If `process-send-string' raises an error and the process has + ;; finished, treat it as a broken pipe. Otherwise, just + ;; re-throw the signal. + (if (memq (process-status target) + '(run stop open closed)) + (signal (car err) (cdr err)) + (signal 'eshell-pipe-broken (list target)))))) ((consp target) (apply (car target) object (cdr target)))) diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el index 62e784e8f6..2369bb5cc0 100644 --- a/test/lisp/eshell/esh-proc-tests.el +++ b/test/lisp/eshell/esh-proc-tests.el @@ -74,8 +74,6 @@ (ert-deftest esh-proc-test/pipeline-connection-type/middle () "Test that all streams are pipes when a command is in the middle of a pipeline." - ;; Repeated unreproducible errors. - :tags '(:unstable) (skip-unless (and (executable-find "sh") (executable-find "cat"))) (eshell-command-result-equal @@ -84,8 +82,6 @@ pipeline." (ert-deftest esh-proc-test/pipeline-connection-type/last () "Test that only output streams are PTYs when a command ends a pipeline." - ;; Repeated unreproducible errors. - :tags '(:unstable) (skip-unless (executable-find "sh")) (eshell-command-result-equal (concat "echo | " esh-proc-test--detect-pty-cmd) commit 9f692bcd84e2b6e450e154361e1058186e6481a8 Author: Stefan Kangas Date: Mon Aug 29 19:26:39 2022 +0200 Improve point-at-{bol,eol} obsoletion message * lisp/subr.el (point-at-eol, point-at-bol): Mention 'pos-eol' and 'pos-bol' in obsoletion message. diff --git a/lisp/subr.el b/lisp/subr.el index 36f5e2fee4..2ffc594997 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1913,8 +1913,10 @@ be a list of the form returned by `event-start' and `event-end'." (defalias 'mkdir #'make-directory) ;; These were the XEmacs names, now obsolete: -(define-obsolete-function-alias 'point-at-eol #'line-end-position "29.1") -(define-obsolete-function-alias 'point-at-bol #'line-beginning-position "29.1") +(defalias 'point-at-eol #'line-end-position) +(make-obsolete 'point-at-eol "use `line-end-position' or `pos-eol' instead." "29.1") +(defalias 'point-at-bol #'line-beginning-position) +(make-obsolete 'point-at-bol "use `line-beginning-position' or `pos-bol' instead." "29.1") (define-obsolete-function-alias 'user-original-login-name #'user-login-name "28.1") ;; These are in obsolete/autoload.el, but are commonly used by commit c0bb1aac102f8727484763370b154f635a6a1fd1 Author: Mattias EngdegÄrd Date: Mon Aug 29 17:44:31 2022 +0200 Fix reader memory leak upon error (bug#56623) Reported by Tom Gillespie; error found by Greg Hendershott. * src/lread.c (read_stack_reset): New. (read0): Reset read stack when unwinding from an error. diff --git a/src/lread.c b/src/lread.c index ccccd79cd7..15bbf46f78 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3686,6 +3686,12 @@ read_stack_push (struct read_stack_entry e) rdstack.stack[rdstack.sp++] = e; } +static void +read_stack_reset (intmax_t sp) +{ + eassert (sp <= rdstack.sp); + rdstack.sp = sp; +} /* Read a Lisp object. If LOCATE_SYMS is true, symbols are read with position. */ @@ -3699,6 +3705,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms) specpdl_ref count = SPECPDL_INDEX (); ptrdiff_t base_sp = rdstack.sp; + record_unwind_protect_intmax (read_stack_reset, base_sp); bool uninterned_symbol; bool skip_shorthand; commit df62a3f85ac71bde3b045c19867f142d8e1ead67 Author: Jake Moss Date: Mon Aug 29 17:23:46 2022 +0200 Show gdb-mi disassembly over tramp * lisp/progmodes/gdb-mi.el (gdb-invalidate-disassembly): Show gdb-mi disassembly over tramp (bug#57464). Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index bab80719db..6e8032b7ea 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -4033,11 +4033,12 @@ DOC is an optional documentation string." (file (gdb-mi--field frame 'fullname)) (line (gdb-mi--field frame 'line))) (if file - (format "-data-disassemble -f %s -l %s -n -1 -- 0" file line) - ;; If we're unable to get a file name / line for $PC, simply - ;; follow $PC, disassembling the next 10 (x ~15 (on IA) == - ;; 150 bytes) instructions. - "-data-disassemble -s $pc -e \"$pc + 150\" -- 0")) + (format "-data-disassemble -f %s -l %s -n -1 -- 0" + (file-local-name file) line) + ;; If we're unable to get a file name / line for $PC, simply + ;; follow $PC, disassembling the next 10 (x ~15 (on IA) == + ;; 150 bytes) instructions. + "-data-disassemble -s $pc -e \"$pc + 150\" -- 0")) gdb-disassembly-handler ;; We update disassembly only after we have actual frame information ;; about all threads, so no there's `update' signal in this list commit 46a49b748eaf5553a6eb45215b14baebc090b33b Author: Lars Ingebrigtsen Date: Mon Aug 29 17:15:17 2022 +0200 Work around `&' dired command when using the fish shell * lisp/dired-aux.el (dired-shell-stuff-it): Add a space before &wait; this apparently makes the `&' command work with the fish shell (bug#57472). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 06f0b86fc4..0e8062af52 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -987,7 +987,7 @@ Also see the `dired-confirm-shell-command' variable." ;; Add 'wait' to force those POSIX shells to wait until ;; all commands finish. (or (and parallel-in-background (not w32-shell) - "&wait") + " &wait") ""))) (t (let ((files (mapconcat #'shell-quote-argument @@ -999,7 +999,7 @@ Also see the `dired-confirm-shell-command' variable." ;; Be consistent in how we treat inputs to commands -- do ;; the same here as in the `on-each' case. (if (and in-background (not w32-shell)) - "&wait" + " &wait" ""))))) (or (and in-background "&") "")))) commit 6f57cb6d8141e35fee39ea31f08d4ce5cf6c51e5 Author: Eli Zaretskii Date: Mon Aug 29 16:52:07 2022 +0300 Fix point adjustment in recreated *Messages* buffers * lisp/startup.el (normal-top-level): Move setting of 'window-point-insertion-type' from here... * lisp/simple.el (messages-buffer-mode): ...to here. This is so any *Messages* buffers we create instead of the original one, if it's killed, will have the same type of the window-point marker. (Bug#57466) diff --git a/lisp/simple.el b/lisp/simple.el index daacf697ff..2512397b24 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10431,7 +10431,9 @@ and setting it to nil." map)) (define-derived-mode messages-buffer-mode special-mode "Messages" - "Major mode used in the \"*Messages*\" buffer.") + "Major mode used in the \"*Messages*\" buffer." + ;; Make it easy to do like "tail -f". + (setq-local window-point-insertion-type t)) (defun messages-buffer () "Return the \"*Messages*\" buffer. diff --git a/lisp/startup.el b/lisp/startup.el index b0fbf7a34c..50a8f491d8 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -718,8 +718,6 @@ It is the default value of the variable `top-level'." (let ((dir default-directory)) (with-current-buffer "*Messages*" (messages-buffer-mode) - ;; Make it easy to do like "tail -f". - (setq-local window-point-insertion-type t) ;; Give *Messages* the same default-directory as *scratch*, ;; just to keep things predictable. (setq default-directory (or dir (expand-file-name "~/"))))) commit 5cae71834bd55e0bf90689b12b801206ee8c9da9 Author: Stefan Monnier Date: Mon Aug 29 09:03:34 2022 -0400 * src/keyboard.c (safe_run_hooks*): Simplify and generalize (safe_run_hooks_1, safe_run_hook_funcall): Simplify and generalize to arbitrary `nargs`. (safe_run_hooks_error): Remove unneeded assertion. diff --git a/src/keyboard.c b/src/keyboard.c index 1d7125a0a3..77280d08c5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1827,21 +1827,15 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified) } } -/* Subroutine for safe_run_hooks: run the hook, which is ARGS[1]. */ +/* Subroutine for safe_run_hooks: run the hook's function. + ARGS[0] holds the name of the hook, which we don't need here (we only use + it in the failure case of the internal_condition_case_n). */ static Lisp_Object safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args) { - eassert (nargs >= 2 && nargs <= 4); - switch (nargs) - { - case 2: - return call0 (args[1]); - case 3: - return call1 (args[1], args[2]); - default: - return call2 (args[1], args[2], args[3]); - } + eassert (nargs >= 2); + return Ffuncall (nargs - 1, args + 1); } /* Subroutine for safe_run_hooks: handle an error by clearing out the function @@ -1850,7 +1844,7 @@ safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args) static Lisp_Object safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) { - eassert (nargs >= 2 && nargs <= 4); + eassert (nargs >= 2); AUTO_STRING (format, "Error in %s (%S): %S"); Lisp_Object hook = args[0]; Lisp_Object fun = args[1]; @@ -1886,27 +1880,13 @@ safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) static Lisp_Object safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args) { - eassert (nargs >= 2 && nargs <= 4); - /* Yes, run_hook_with_args works with args in the other order. */ - switch (nargs) - { - case 2: - internal_condition_case_n (safe_run_hooks_1, - 2, ((Lisp_Object []) {args[1], args[0]}), - Qt, safe_run_hooks_error); - break; - case 3: - internal_condition_case_n (safe_run_hooks_1, - 3, ((Lisp_Object []) {args[1], args[0], args[2]}), - Qt, safe_run_hooks_error); - break; - default: - internal_condition_case_n (safe_run_hooks_1, - 4, ((Lisp_Object []) - {args[1], args[0], args[2], args[3]}), - Qt, safe_run_hooks_error); - break; - } + eassert (nargs >= 2); + /* We need to swap args[0] and args[1] here or in `safe_run_hooks_1`. + It's more convenient to do it here. */ + Lisp_Object fun = args[0], hook = args[1]; + args[0] = hook, args[1] = fun; + internal_condition_case_n (safe_run_hooks_1, nargs, args, + Qt, safe_run_hooks_error); return Qnil; } @@ -1920,7 +1900,8 @@ safe_run_hooks (Lisp_Object hook) specpdl_ref count = SPECPDL_INDEX (); specbind (Qinhibit_quit, Qt); - run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall); + run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), + safe_run_hook_funcall); unbind_to (count, Qnil); } @@ -1936,7 +1917,8 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w) make_fixnum (get_narrowed_zv (w, PT)), true); - run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall); + run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), + safe_run_hook_funcall); unbind_to (count, Qnil); } commit 19ec23e82cbbc59a9900f524cdb292dce46821b4 Author: Michael Albinus Date: Mon Aug 29 12:05:02 2022 +0200 Do not connect unreachable remote hosts in recentf * lisp/recentf.el (recentf-expand-file-name): Protect against stalled remote hosts. (Bug#57336) diff --git a/lisp/recentf.el b/lisp/recentf.el index b80ee3dd7d..32badb1a37 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -411,7 +411,8 @@ returned nil." "Convert file NAME to absolute, and canonicalize it. NAME is first passed to the function `expand-file-name', then to `recentf-filename-handlers' to post process it." - (recentf-apply-filename-handlers (expand-file-name name))) + (let ((non-essential t)) + (recentf-apply-filename-handlers (expand-file-name name)))) (defun recentf-include-p (filename) "Return non-nil if FILENAME should be included in the recent list. commit 18d5eadf2c3460ce85655211f9870a4035c202c0 Author: Po Lu Date: Mon Aug 29 17:23:18 2022 +0800 Unify floating point handling when reading XI motion events * src/xterm.c (handle_one_xevent): Always round values as recommended, instead of just truncating them. Also fixes weird "jitter" during drag-and-drop on some clients. diff --git a/src/xterm.c b/src/xterm.c index 7a0a21b136..e0a8e13b24 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -21333,26 +21333,26 @@ handle_one_xevent (struct x_display_info *dpyinfo, /* Also remember the mouse glyph and set mouse_moved. */ if (f != dpyinfo->last_mouse_glyph_frame - || xev->event_x < r->x - || xev->event_x >= r->x + r->width - || xev->event_y < r->y - || xev->event_y >= r->y + r->height) + || lrint (xev->event_x) < r->x + || lrint (xev->event_x) >= r->x + r->width + || lrint (xev->event_y) < r->y + || lrint (xev->event_y) >= r->y + r->height) { f->mouse_moved = true; f->last_mouse_device = (source ? source->name : Qnil); dpyinfo->last_mouse_scroll_bar = NULL; - remember_mouse_glyph (f, xev->event_x, - xev->event_y, r); + remember_mouse_glyph (f, lrint (xev->event_x), + lrint (xev->event_y), r); dpyinfo->last_mouse_glyph_frame = f; } } if (xev->root == dpyinfo->root_window) target = x_dnd_get_target_window (dpyinfo, - xev->root_x, - xev->root_y, + lrint (xev->root_x), + lrint (xev->root_y), &target_proto, &motif_style, &toplevel, @@ -21490,14 +21490,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (x_dnd_last_window_is_frame && target != None) x_dnd_note_self_position (dpyinfo, target, - xev->root_x, xev->root_y); + lrint (xev->root_x), + lrint (xev->root_y)); else if (x_dnd_last_protocol_version != -1 && target != None) { dnd_state = xi_convert_event_state (xev); x_dnd_send_position (x_dnd_frame, target, x_dnd_last_protocol_version, - xev->root_x, xev->root_y, + lrint (xev->root_x), + lrint (xev->root_y), x_dnd_selection_timestamp, x_dnd_wanted_action, 0, dnd_state); @@ -21705,7 +21707,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif x_dnd_note_self_wheel (dpyinfo, x_dnd_last_seen_window, - xev->root_x, xev->root_y, + lrint (xev->root_x), + lrint (xev->root_y), xev->detail, dnd_state, xev->time); } @@ -21713,7 +21716,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_position (x_dnd_frame, x_dnd_last_seen_window, x_dnd_last_protocol_version, - xev->root_x, xev->root_y, + lrint (xev->root_x), + lrint (xev->root_y), xev->time, x_dnd_wanted_action, xev->detail, dnd_state); @@ -21756,7 +21760,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, { x_dnd_waiting_for_finish = false; x_dnd_note_self_drop (dpyinfo, x_dnd_last_seen_window, - xev->root_x, xev->root_y, xev->time); + lrint (xev->root_x), + lrint (xev->root_y), xev->time); } else if (x_dnd_last_seen_window != None && x_dnd_last_protocol_version != -1) @@ -21831,12 +21836,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None ? x_dnd_last_seen_toplevel : x_dnd_last_seen_window), - xev->root_x, xev->root_y, xev->time); + lrint (xev->root_x), + lrint (xev->root_y), xev->time); } else if (x_dnd_last_seen_toplevel != None) x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel, - xev->root_x, xev->root_y, + lrint (xev->root_x), + lrint (xev->root_y), xev->time); x_dnd_last_protocol_version = -1;