commit 565f4e4ad17c929159d646bfeff7d1adb4c9b727 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Wed Jul 3 21:36:00 2024 +0200 ; Delete redundant comment in rst.el * lisp/textmodes/rst.el: Delete redundant comment. diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index 5fbff4ba888..1e09d3a6eb6 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -102,7 +102,6 @@ ;; FIXME: Embed complicated `defconst's in `eval-when-compile'. -;; Common Lisp stuff (require 'cl-lib) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; commit f7725d85f3132fb684032438f81defcb481892b7 Author: Spencer Baugh Date: Wed Jul 3 15:39:23 2024 +0200 Prefer to run find and grep in parallel in rgrep (bug#71094) * lisp/progmodes/grep.el (grep-compute-defaults): Prefer `gnu' for grep-find-use-xargs over `exec-plus', but not on Windows. (bug#71094) diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index e8d1e692d0f..d2d0baa235c 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -827,15 +827,23 @@ The value depends on `grep-command', `grep-template', (unless grep-find-use-xargs (setq grep-find-use-xargs (cond - ((grep-probe find-program - `(nil nil nil ,(null-device) "-exec" "echo" - "{}" "+")) - 'exec-plus) + ;; For performance, we want: + ;; A. Run grep on batches of files (instead of one grep per file) + ;; B. If the directory is large and we need multiple batches, + ;; run find in parallel with a running grep. + ;; "find | xargs grep" gives both A and B ((and + (not (eq system-type 'windows-nt)) (grep-probe find-program `(nil nil nil ,(null-device) "-print0")) (grep-probe xargs-program '(nil nil nil "-0" "echo"))) 'gnu) + ;; "find -exec {} +" gives A but not B + ((grep-probe find-program + `(nil nil nil ,(null-device) "-exec" "echo" + "{}" "+")) + 'exec-plus) + ;; "find -exec {} ;" gives neither A nor B. (t 'exec)))) (unless grep-find-command commit 65bd41d1cf6d8ea6b95b69d9c60b0111a1c33392 Author: Po Lu Date: Wed Jul 3 17:05:24 2024 +0800 Adapt doc-view-set-slice-using-mouse to touch-screen input * doc/lispref/commands.texi (Touchscreen Events): Document means of unconditionally enabling simple conversion. * lisp/doc-view.el (doc-view-set-slice-using-mouse): Bind touch-screen-simple-mouse-conversion to t, and read translated mouse events with read-key rather than read-event. * lisp/subr.el (read-key): Don't permit idle timer to interfere with reporting of translated mouse events. * lisp/touch-screen.el (touch-screen-simple-mouse-conversion): New variable. (touch-screen-handle-point-up, touch-screen-handle-touch): Unconditionally enable `mouse-drag' translation if set. Decide whether to send drag or mouse events by the values of the two touchpoints' XY positions and point and double-click-fuzz, as in make_lispy_event. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index a9da6c75367..6ddb70a3b9f 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2128,7 +2128,7 @@ motion and mouse motion. However, some commands bound to @code{down-mouse-1}--@code{mouse-drag-region}, for example--either conflict with defined touch screen gestures (such as ``long-press to -drag''), or with user expectations for touch input, and shouldn't +drag''), or with user expectations for touch input, and should not subject the touch sequence to simple translation. If a command whose name contains the property (@pxref{Symbol Properties}) @code{ignored-mouse-command} is encountered or there is no command @@ -2146,13 +2146,20 @@ compromise for packages which assume @code{mouse-drag-region} has already set point to the location of any mouse click and selected the window where it took place. -To prevent unwanted @code{mouse-1} events arriving after a mouse menu -is dismissed (@pxref{Mouse Menus}), Emacs also avoids simple +To prevent unwanted @code{mouse-1} events from arriving after a mouse +menu is dismissed (@pxref{Mouse Menus}), Emacs also disables simple translation if @code{down-mouse-1} is bound to a keymap, making it a prefix key. In lieu of simple translation, it translates the closing -@code{touchscreen-end} to a @code{down-mouse-1} event with the -starting position of the touch sequence, consequently displaying -the mouse menu. +@code{touchscreen-end} to a @code{down-mouse-1} event with the starting +position of the touch sequence, consequently displaying the mouse menu. + +@vindex @code{touch-screen-simple-mouse-conversion} +Simple conversion will be enabled without regard to the existence of +command or menu bindings if the variable +@code{touch-screen-simple-mouse-conversion} is bound or set to a +non-@code{nil} value, as, for example, it may be by a caller of +@code{read-key} expecting to receive @code{mouse-movement} and +@code{drag-mouse-1} events. @cindex @code{mouse-1-menu-command}, a symbol property Since certain commands are also bound to @code{down-mouse-1} for the diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 4ae9a5e6629..f96b1bad886 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -1511,15 +1511,18 @@ to do that. To reset the slice use `doc-view-reset-slice'." ;; Redisplay (doc-view-goto-page (doc-view-current-page))) +(defvar touch-screen-simple-mouse-conversion) ; Defined in touch-screen.el. + (defun doc-view-set-slice-using-mouse () "Set the slice of the images that should be displayed. You set the slice by pressing mouse-1 at its top-left corner and dragging it to its bottom-right corner. See also `doc-view-set-slice' and `doc-view-reset-slice'." (interactive) - (let (x y w h done) + (let ((touch-screen-simple-mouse-conversion t) + x y w h done) (while (not done) - (let ((e (read-event + (let ((e (read-key (concat "Press mouse-1 at the top-left corner and " "drag it to the bottom-right corner!")))) (when (eq (car e) 'drag-mouse-1) diff --git a/lisp/subr.el b/lisp/subr.el index ab388630a91..36b5353b577 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3338,7 +3338,15 @@ only unbound fallback disabled is downcasing of the last event." ;; though read-key-sequence thinks we should wait ;; for more input to decide how to interpret the ;; current input. - (throw 'read-key keys))))))) + ;; + ;; As this treatment will completely defeat the + ;; purpose of touch screen event conversion, + ;; dispense with this timeout when the first + ;; event in this vector is a touch-screen event. + (unless (memq (car-safe (aref keys 0)) '(touchscreen-begin + touchscreen-update + touchscreen-end)) + (throw 'read-key keys)))))))) (unwind-protect (progn (use-global-map diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el index c5918efb800..57eff075e73 100644 --- a/lisp/touch-screen.el +++ b/lisp/touch-screen.el @@ -157,13 +157,22 @@ dragging.") ;; Should this variable be documented? (defvar-local touch-screen-keyboard-function nil "Function that decides whether to display the on screen keyboard. -If set, this function is called with point set to the position of the -tap involved when a command listed in `touch-screen-set-point-commands' -is about to be invoked in response to a tap, the current buffer, or the -text beneath point (in the case of an `inhibit-read-only' text -property), is not read only, and `touch-screen-display-keyboard' is nil, -and should return non-nil if it is appropriate to display the on-screen -keyboard afterwards.") +If set, this function is called with point set to the position +of the tap involved when a command listed in +`touch-screen-set-point-commands' is about to be invoked in +response to a tap, the current buffer, or the text beneath +point (in the case of an `inhibit-read-only' text property), is +not read only, and `touch-screen-display-keyboard' is nil, and +should return non-nil if it is appropriate to display the +on-screen keyboard afterwards.") + +(defvar touch-screen-simple-mouse-conversion nil + "Whether to unconditionally enable simple mouse event translation. +If non-nil, touch screen event conversion will always proceed as +though a command was bound to `down-mouse-1' at the position of +the initial tap. That is to say, taps, mouse motion, and +touchpoint removals will be unconditionally converted into +mouse-down, mouse motion, mouse drag, and mouse button events.") @@ -1418,36 +1427,27 @@ is not read-only." (new-point (posn-point posn)) (old-posn (nth 4 touch-screen-current-tool)) (old-window (posn-window posn)) - (old-point (posn-point posn))) + (old-point (posn-point posn)) + (new-relative-xy (touch-screen-relative-xy + posn new-window)) + (old-relative-xy (touch-screen-relative-xy + old-posn new-window))) (throw 'input-event - ;; If the position of the touch point hasn't - ;; changed, or it doesn't start or end on a - ;; window... - (if (and (not old-point) (not new-point)) - ;; Should old-point and new-point both equal - ;; nil, compare the posn areas and nominal - ;; column position. If either are - ;; different, generate a drag event. - (let ((new-col-row (posn-col-row posn)) - (new-area (posn-area posn)) - (old-col-row (posn-col-row old-posn)) - (old-area (posn-area old-posn))) - (if (and (equal new-col-row old-col-row) - (eq new-area old-area)) - ;; ... generate a mouse-1 event... - (list 'mouse-1 posn) - ;; ... otherwise, generate a - ;; drag-mouse-1 event. - (list 'drag-mouse-1 old-posn posn))) - (if (and (eq new-window old-window) - (eq new-point old-point) - (windowp new-window) - (windowp old-window)) - ;; ... generate a mouse-1 event... - (list 'mouse-1 posn) - ;; ... otherwise, generate a drag-mouse-1 - ;; event. - (list 'drag-mouse-1 old-posn posn))))))) + ;; If the position of the touch point has + ;; changed, or it has moved significantly, as + ;; measured by reference to double-click-fuzz... + (if (or (let ((xdiff (- (car new-relative-xy) + (car old-relative-xy))) + (ydiff (- (cdr new-relative-xy) + (cdr old-relative-xy)))) + (and (>= (abs xdiff) double-click-fuzz) + (>= (abs ydiff) double-click-fuzz))) + (not (eq old-window new-window)) + (not (eq old-point new-point))) + ;; ... generate a drag-mouse-1 event... + (list 'drag-mouse-1 old-posn posn) + ;; ... otherwise, generate a mouse-1 event. + (list 'mouse-1 posn)))))) ((eq what 'mouse-1-menu) ;; Generate a `down-mouse-1' event at the position the tap ;; took place, unless the touch sequence was canceled. @@ -1633,29 +1633,35 @@ functions undertaking event management themselves to call ;; Generate the `restart-drag' event. (throw 'input-event (list 'touchscreen-restart-drag position)))) - ;; Determine if there is a command bound to `down-mouse-1' - ;; at the position of the tap and that command is not a - ;; command whose functionality is replaced by the - ;; long-press mechanism. If so, set the fourth element of - ;; `touch-screen-current-tool' to `mouse-drag' and - ;; generate an emulated `mouse-1' event. + ;; Determine whether there is a command bound to + ;; `down-mouse-1' at the position of the tap and that + ;; command is not a command whose functionality is replaced + ;; by the long-press mechanism. If so, set the fourth + ;; element of `touch-screen-current-tool' to `mouse-drag' + ;; and generate an emulated `mouse-1' event. Likewise if + ;; touch event translation is being invoked by a caller of + ;; `read-key' that expects unprocessed mouse input, ;; - ;; If the command in question is a keymap, set that - ;; element to `mouse-1-menu' instead of `mouse-drag', and - ;; don't generate a `down-mouse-1' event immediately. - ;; Instead, wait for the touch point to be released. + ;; If the command in question is a keymap, set that element + ;; to `mouse-1-menu' instead of `mouse-drag', and don't + ;; generate a `down-mouse-1' event immediately, but wait for + ;; the touch point to be released, so that the menu bar may + ;; not be displayed before the user has released the touch + ;; point and the window system is ready to display a menu. (if (and tool-list - (and (setq binding - (key-binding (if prefix - (vector prefix - 'down-mouse-1) - [down-mouse-1]) - t nil position)) - (not (and (symbolp binding) - (get binding 'ignored-mouse-command))))) - (if (or (keymapp binding) - (and (symbolp binding) - (get binding 'mouse-1-menu-command))) + (or (and (setq binding + (key-binding (if prefix + (vector prefix + 'down-mouse-1) + [down-mouse-1]) + t nil position)) + (not (and (symbolp binding) + (get binding 'ignored-mouse-command)))) + touch-screen-simple-mouse-conversion)) + (if (and (not touch-screen-simple-mouse-conversion) + (or (keymapp binding) + (and (symbolp binding) + (get binding 'mouse-1-menu-command)))) ;; binding is a keymap, or a command that does ;; almost the same thing. If a `mouse-1' event is ;; generated after the keyboard command loop commit 667ca66481c74325f3c8e4391d185ee547fdbb36 Author: Stefan Monnier Date: Tue Jul 2 16:29:07 2024 -0400 (dump_interval_node): Remove unused arg `offset` * src/pdumper.c (dump_interval_node): Remove unused arg `offset`. (dump_overlay): Adjust call accordingly. diff --git a/src/pdumper.c b/src/pdumper.c index 8946c317bf9..138777e7134 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2125,8 +2125,7 @@ dump_marker (struct dump_context *ctx, const struct Lisp_Marker *marker) } static dump_off -dump_interval_node (struct dump_context *ctx, struct itree_node *node, - dump_off parent_offset) +dump_interval_node (struct dump_context *ctx, struct itree_node *node) { #if CHECK_STRUCTS && !defined (HASH_itree_node_50DE304F13) # error "itree_node changed. See CHECK_STRUCTS comment in config.h." @@ -2153,17 +2152,17 @@ dump_interval_node (struct dump_context *ctx, struct itree_node *node, dump_remember_fixup_ptr_raw (ctx, offset + dump_offsetof (struct itree_node, parent), - dump_interval_node (ctx, node->parent, offset)); + dump_interval_node (ctx, node->parent)); if (node->left) dump_remember_fixup_ptr_raw (ctx, offset + dump_offsetof (struct itree_node, left), - dump_interval_node (ctx, node->left, offset)); + dump_interval_node (ctx, node->left)); if (node->right) dump_remember_fixup_ptr_raw (ctx, offset + dump_offsetof (struct itree_node, right), - dump_interval_node (ctx, node->right, offset)); + dump_interval_node (ctx, node->right)); return offset; } @@ -2180,7 +2179,7 @@ dump_overlay (struct dump_context *ctx, const struct Lisp_Overlay *overlay) dump_remember_fixup_ptr_raw (ctx, offset + dump_offsetof (struct Lisp_Overlay, interval), - dump_interval_node (ctx, overlay->interval, offset)); + dump_interval_node (ctx, overlay->interval)); return offset; } commit 0385c0c0820361b71a74988f23d0445238f30473 Author: Stefan Monnier Date: Tue Jul 2 16:28:08 2024 -0400 (buf_*pos_to_*pos): Fix minor off-by one * src/marker.c (buf_charpos_to_bytepos, buf_bytepos_to_charpos): Slightly restructure the markers loop so we check `distance` also before "consider"ing the first marker. diff --git a/src/marker.c b/src/marker.c index 9aaa2e7402c..16fa3bcef3e 100644 --- a/src/marker.c +++ b/src/marker.c @@ -202,19 +202,15 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff) CONSIDER (cached_charpos, cached_bytepos); - for (tail = BUF_MARKERS (b); tail; tail = tail->next) - { - CONSIDER (tail->charpos, tail->bytepos); - - /* If we are down to a range of 50 chars, - don't bother checking any other markers; - scan the intervening chars directly now. */ - if (best_above - charpos < distance - || charpos - best_below < distance) - break; - else - distance += BYTECHAR_DISTANCE_INCREMENT; - } + for (tail = BUF_MARKERS (b); + /* If we are down to a range of DISTANCE chars, + don't bother checking any other markers; + scan the intervening chars directly now. */ + tail && !(best_above - charpos < distance + || charpos - best_below < distance); + tail = tail->next, + distance += BYTECHAR_DISTANCE_INCREMENT) + CONSIDER (tail->charpos, tail->bytepos); /* We get here if we did not exactly hit one of the known places. We have one known above and one known below. @@ -354,19 +350,15 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff) CONSIDER (cached_bytepos, cached_charpos); - for (tail = BUF_MARKERS (b); tail; tail = tail->next) - { - CONSIDER (tail->bytepos, tail->charpos); - - /* If we are down to a range of DISTANCE bytes, - don't bother checking any other markers; - scan the intervening chars directly now. */ - if (best_above_byte - bytepos < distance - || bytepos - best_below_byte < distance) - break; - else - distance += BYTECHAR_DISTANCE_INCREMENT; - } + for (tail = BUF_MARKERS (b); + /* If we are down to a range of DISTANCE bytes, + don't bother checking any other markers; + scan the intervening chars directly now. */ + tail && !(best_above_byte - bytepos < distance + || bytepos - best_below_byte < distance); + tail = tail->next, + distance += BYTECHAR_DISTANCE_INCREMENT) + CONSIDER (tail->bytepos, tail->charpos); /* We get here if we did not exactly hit one of the known places. We have one known above and one known below. commit 4c3e0c990cb9fa06e54223e7eed48c04d1829b66 Merge: 6b5accdc05d b5341831353 Author: Po Lu Date: Tue Jul 2 20:55:22 2024 +0800 Merge from savannah/emacs-30 b5341831353 * etc/NEWS: Fix typos. 850fc68481a ; (grep-read-files): Fix completion table 921d40759e5 Remove a reference to a non-existant variable from a doc-... 4c64b990873 ; * etc/NEWS: Fix level of several entrries. 459e635099b ; * etc/NEWS: Fix typo. 7050128cfe9 ; * src/search.c (Fmatch_beginning, Fmatch_end): Doc fix. # Conflicts: # etc/NEWS commit b534183135397498e66131fbc5414ef1d445a471 Author: Michael Albinus Date: Tue Jul 2 14:28:52 2024 +0200 * etc/NEWS: Fix typos. diff --git a/etc/NEWS b/etc/NEWS index 704c4c7cc29..31d69ddabab 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -37,7 +37,7 @@ compilation, configure Emacs with the option: This requires Emacs to be compiled on another computer. The Android NDK, SDK, and a suitable Java compiler must also be installed. -See the file 'java/INSTALL' for more details. +See the file "java/INSTALL" for more details. --- ** Native JSON support is now always available; libjansson is no longer used. @@ -46,14 +46,14 @@ been removed. 'json-available-p' now always returns non-nil and is only kept for compatibility. --- -** Emacs now defaults to ossaudio library for sound on NetBSD and OpenBSD. -Previously configure used ALSA libraries if installed on the -system when configured '--with-sound=yes' (which is the default), with -fallback to libossaudio. The libossaudio library included with the -base system is now used even if ALSA is found to avoid relying on -external packages and to resolve potential incompatibilities between -Linux and BSD versions of ALSA. Use '--with-sound=alsa' to build with -ALSA on these operating systems instead. +** Emacs now defaults to the ossaudio library for sound on NetBSD and OpenBSD. +Previously, configure used ALSA libraries if installed on the system +when configured '--with-sound=yes' (which is the default), with fallback +to libossaudio. The libossaudio library included with the base system +is now used even if ALSA is found to avoid relying on external packages +and to resolve potential incompatibilities between GNU/Linux and *BSD +versions of ALSA. Use '--with-sound=alsa' to build with ALSA on these +operating systems instead. * Startup Changes in Emacs 30.1 @@ -101,7 +101,7 @@ configuration settings installed via mode hooks are not affected. At those places where the old 'mouse-4/5/6/7' events could still occur (i.e., X11 input in the absence of XInput2, and 'xterm-mouse-mode'), we remap them to the corresponding 'wheel-up/down/left/right' event, -according to the new variable 'mouse-wheel-buttons'. +according to the new user option 'mouse-wheel-buttons'. The old variables 'mouse-wheel-up-event', 'mouse-wheel-down-event', 'mouse-wheel-left-event', and 'mouse-wheel-right-event' are thereby obsolete. @@ -131,7 +131,7 @@ to your init file: ** The default process filter was rewritten in native code. The round-trip through the Lisp function 'internal-default-process-filter' is skipped when the process filter is -the default one. It's reimplemented in native code, reducing GC churn. +the default one. It is reimplemented in native code, reducing GC churn. To undo this change, set 'fast-read-process-output' to nil. +++ @@ -428,16 +428,16 @@ This user option controls outline visibility in the output buffer of 'describe-bindings' when 'describe-bindings-outline' is non-nil. --- -*** 'describe-function' shows function inferred type when available. -For native compiled Lisp functions 'describe-function' prints (after +*** 'describe-function' shows the function inferred type when available. +For native compiled Lisp functions, 'describe-function' prints (after the signature) the automatically inferred function type as well. --- *** 'describe-function' now shows the type of the function object. -The text used to say things like "car is a built-in function" whereas -it now says "car is a primitive-function" where "primitive-function" is -the symbol returned by 'cl-type-of'. You can click on those words to -get information about that type. +The text used to say things like "car is a built-in function" whereas it +now says "car is a primitive-function" where "primitive-function" is the +the name of the symbol returned by 'cl-type-of'. You can click on those +words to get information about that type. --- *** 'C-h m' ('describe-mode') uses outlining by default. @@ -605,8 +605,8 @@ value when installing GNU coreutils using something like ports or Homebrew. +++ -*** 'write-region-inhibit-fsync' now defaults to t in interactive mode, -as it did in batch mode since Emacs 24. +*** 'write-region-inhibit-fsync' now defaults to t in interactive mode. +This is the default in batch mode since Emacs 24. --- *** The default value of 'read-process-output-max' was increased to 65536. @@ -615,7 +615,7 @@ as it did in batch mode since Emacs 24. *** 'url-gateway-broken-resolution' is now obsolete. This option was intended for use on SunOS 4.x and Ultrix systems, neither of which have been supported by Emacs since version 23.1. -The user option 'url-gateway-nslookup-program' and the function +The user option 'url-gateway-nslookup-program' and the command 'url-gateway-nslookup-host' are consequently also obsolete. @@ -740,7 +740,7 @@ The default is unchanged. By default, Text mode no longer binds 'M-TAB' to 'ispell-complete-word'. Instead, this mode arranges for 'completion-at-point', globally bound to 'M-TAB', to perform word completion as well. You can have Text mode -bind 'M-TAB' to 'ispell-complete-word' as it did in previous Emacs +binding 'M-TAB' to 'ispell-complete-word' as it did in previous Emacs versions, or disable Ispell word completion in Text mode altogether, by customizing the new user option 'text-mode-ispell-word-completion'. @@ -769,7 +769,7 @@ encoding. Therefore, the duplicate coding system definition has been dropped in favor of an alias. The mode-line mnemonic for 'vietnamese-vscii' and its aliases is the -lowercase letter 'v'. +lowercase letter "v". --- *** Users in CJK locales can control width of some non-CJK characters. @@ -832,7 +832,7 @@ These input methods can now produce single guillemets "‹" and "›". For --- *** New French language 'C-x 8' key translations for "‹" and "›". -These characters can now be entered using 'C-x 8 ~ <' and 'C-x 8 ~ >' +These characters can now be entered using 'C-x 8 ~ <' and 'C-x 8 ~ >', respectively, after activating French language support via 'iso-transl-set-language'. Double guillemets were already supported via 'C-x 8 <' and 'C-x 8 >' @@ -876,8 +876,8 @@ This requires the 'lzip' program to be installed on your system. +++ *** New user option 'gud-highlight-current-line'. -When enabled, Gud will visually emphasize the line being executed upon -pauses in the debugee's execution, such as those occasioned by +When enabled, GUD will visually emphasize the line being executed upon +pauses in the debuggee's execution, such as those occasioned by breakpoints being hit. +++ @@ -891,8 +891,8 @@ configure the order and max length of various properties in the local variables buffer when using 'gdb-many-windows'. By default, this user option is set to write the properties in the order: -name, type and value, where the name and type are truncated to 20 -characters, and the value is truncated according to the value of +'name', 'type' and 'value', where the 'name' and 'type' are truncated to 20 +characters, and the 'value' is truncated according to the value of 'gdb-locals-value-limit'. If you want to get back the old behavior, set the user option to the value @@ -902,7 +902,7 @@ If you want to get back the old behavior, set the user option to the value +++ *** New user option 'gdb-display-io-buffer'. -If this is nil, 'M-x gdb' will neither create nor display a separate +If this is nil, command 'gdb' will neither create nor display a separate buffer for the I/O of the program being debugged, but will instead redirect the program's interaction to the GDB execution buffer. The default is t, to preserve previous behavior. @@ -913,7 +913,7 @@ default is t, to preserve previous behavior. *** New user option 'grep-use-headings'. When non-nil, the output of Grep is split into sections, one for each file, instead of having file names prefixed to each line. It is -equivalent to the "--heading" option of some tools such as 'git grep' +equivalent to the '--heading' option of some tools such as 'git grep' and 'rg'. The headings are displayed using the new 'grep-heading' face. The default is nil. @@ -951,7 +951,7 @@ The look of the key prompt in the project switcher has been changed slightly. To get the previous one, set this option to 'brackets'. --- -*** 'project-try-vc' tries harder to find the responsible VCS. +*** Function 'project-try-vc' tries harder to find the responsible VCS. When 'project-vc-extra-root-markers' is non-nil, and causes a subdirectory project to be detected which is not a VCS root, Project now additionally traverses the parent directories until a VCS root is found @@ -971,7 +971,7 @@ you can add this to your init script: --- *** New variable 'project-files-relative-names'. -If it's non-nil, 'project-files' can return file names relative to the +If it is non-nil, 'project-files' can return file names relative to the project root. Project backends can use this to improve the performance of their 'project-files' implementation. @@ -998,32 +998,32 @@ The command was previously obsoleted and unbound in Emacs 28. --- *** Support for viewing VC change history across renames. -When a fileset's VC change history ends at a rename, ('C-x v l') now +When a fileset's VC change history ends at a rename, 'C-x v l' now prints the old name(s) and shows a button which jumps to the history of the files under the old names. This feature is supported for Git and Hg. Naturally, 'vc-git-print-log-follow' should be nil for this to work -(or '--follow' should not be in 'vc-hg-print-log-switches', in Hg's -case). Unlike when the '--follow' switch is used, commands to see the -diff of the old revision ('d'), to check out an old file version ('f') -or to annotate it ('a'), also work on revisions which precede renames. +(or '--follow' should not be in 'vc-hg-log-switches', in Hg's case). +Unlike when the '--follow' switch is used, commands to see the diff of +the old revision ('d'), to check out an old file version ('f') or to +annotate it ('a'), also work on revisions which precede renames. --- *** 'vc-annotate' now abbreviates the Git revision in the buffer name. When using the Git backend, 'vc-annotate' will use an abbreviated revision identifier in its buffer name. To restore the previous -behavior, set 'vc-annotate-use-short-revision' to nil. +behavior, set user option 'vc-annotate-use-short-revision' to nil. --- -*** New option 'vc-git-file-name-changes-switches'. +*** New user option 'vc-git-file-name-changes-switches'. It allows tweaking the thresholds for rename and copy detection. ** Diff mode --- *** New user option 'diff-refine-nonmodified'. -When this is non-nil, 'diff-refine' will highlight lines that were added -or removed in their entirety (as opposed to modified lines, where some -parts of the line were modified), using the same faces as for +When this is non-nil, 'diff-refine-hunk' will highlight lines that were +added or removed in their entirety (as opposed to modified lines, where +some parts of the line were modified), using the same faces as for highlighting the words added and removed within modified lines. The default value is nil. @@ -1056,8 +1056,8 @@ the last line will move to the first line). The default is nil. --- *** New user option 'dired-filename-display-length'. -It is an integer representing the maximum display length of filenames. -The middle part of a filename whose length exceeds the restriction is +It is an integer representing the maximum display length of file names. +The middle part of a file name whose length exceeds the restriction is hidden and an ellipsis is displayed instead. A value of 'window' means using the right edge of window as the display restriction. The default is nil. @@ -1289,12 +1289,12 @@ is not in a comment or a string. By default, it is bound to 'M-q' in +++ *** New user option 'imenu-flatten'. -It controls whether to flatten the list of sections in an imenu, and +It controls whether to flatten the list of sections in an imenu, and how to display the sections in the flattened list. +++ *** The sort order of Imenu completions can now be customized. -You can customize the option 'completion-category-overrides' +You can customize the user option 'completion-category-overrides' and set 'display-sort-function' for the category 'imenu'. ** Which Function mode @@ -1475,13 +1475,13 @@ prefix argument, it always displays the readable parts, and with a zero or negative prefix, it always displays the full page. +++ -*** New option 'eww-readable-urls'. +*** New user option 'eww-readable-urls'. This is a list of regular expressions matching the URLs where EWW should display only the readable parts by default. For more details, see "(eww) Basics" in the EWW manual. --- -*** New option 'eww-readable-adds-to-history'. +*** New user option 'eww-readable-adds-to-history'. When non-nil (the default), calling 'eww-readable' adds a new entry to the EWW page history. @@ -1654,7 +1654,7 @@ and 'python-nav-end-of-block' to the inferior Python process. --- *** Default value of 'python-shell-compilation-regexp-alist' is changed. Support for Python's ExceptionGroup has been added, so in the Python -shell, the line indicating the source of error in the error messages +shell, the line indicating the source of an error in the error messages from ExceptionGroup will be recognized as well. ** Eldoc @@ -1666,16 +1666,16 @@ Previously, the entire docstring was not available to eldoc, which made kept by customizing 'eldoc-echo-area-use-multiline-p'. --- -** Scheme mode -Scheme mode now handles regular expression literal '#/regexp/' that is -available in some Scheme implementations. +** Scheme mode. +Scheme mode now handles the regular expression literal '#/regexp/' that +is available in some Scheme implementations. Also, it should now handle nested sexp-comments. ** Use package +++ *** New ':vc' keyword. -This keyword enables the user to install packages using 'package-vc'. +This keyword enables the user to install packages using package-vc.el. +++ *** New user option 'use-package-vc-prefer-newest'. @@ -1697,7 +1697,7 @@ servers. *** The 'nnweb-type' option 'gmane' has been removed. The gmane.org website is, sadly, down since a number of years with no prospect of it coming back. Therefore, it is no longer valid to set -the user option 'nnweb-type' to 'gmane'. +the server variable 'nnweb-type' to 'gmane'. --- *** New user option 'gnus-mode-line-logo'. @@ -1823,7 +1823,7 @@ or use the command 'cperl-set-style'. --- *** New minor mode 'cperl-extra-paired-delimiters-mode'. Perl 5.36 and newer allows using more than 200 non-ASCII paired -delimiters for quote-like constructs, eg. "q«text»". Use this minor +delimiters for quote-like constructs, e.g. "q«text»". Use this minor mode in buffers where this feature is activated. --- @@ -1866,7 +1866,7 @@ You can now configure how thumbnails are named using this option. +++ *** New macro 'skip-when' to skip 'ert-deftest' tests. -This can help avoid some awkward skip conditions. For example +This can help to avoid some awkward skip conditions. For example '(skip-unless (not noninteractive))' can be changed to the easier to read '(skip-when noninteractive)'. @@ -1972,7 +1972,7 @@ will return the URL for that bug. +++ *** New user option 'rcirc-log-time-format'. -This allows for rcirc logs to use a custom timestamp format, than the +This allows for rcirc logs to use a custom timestamp format, which the chat buffers use by default. --- @@ -2092,7 +2092,7 @@ current project configuration, and later updates it as you edit the files and save the changes. +++ -** New package Which-Key +** New package 'which-key'. The 'which-key' package from GNU ELPA is now included in Emacs. It implements the global minor mode 'which-key-mode' that displays a table of key bindings upon entering a partial key chord and waiting for a @@ -2146,7 +2146,7 @@ dark. In addition to these, we now have 'modus-operandi-tinted' and 'modus-operandi-tritanopia', and 'modus-vivendi-tritanopia' to cover the needs of users with red-green or blue-yellow color deficiency. The Info manual "(modus-themes) Top" describes the details and -showcases all their customization options. +showcases all their user options. +++ ** New library PEG. @@ -2209,15 +2209,15 @@ with 'define-derived-mode' are not affected. 'run-mode-hooks' has been the recommended way to run major mode hooks since Emacs 22. +++ -** 'buffer-match-p' and 'match-buffers' take '&rest args'. -They used to take a single '&optional arg' and were documented to use +** 'buffer-match-p' and 'match-buffers' take '&rest ARGS'. +They used to take a single '&optional ARG' and were documented to use an unreliable hack to try and support condition predicates that -don't accept this optional arg. +don't accept this optional ARG. The new semantics makes no such accommodation, but the code still supports it (with a warning) for backward compatibility. --- -** 'post-gc-hook' runs after updating 'gcs-done' and 'gcs-elapsed'. +** 'post-gc-hook' runs after updating 'gcs-done' and 'gc-elapsed'. --- ** Connection-local variables are applied in buffers visiting remote files. @@ -2238,7 +2238,7 @@ advise against relying on this. +++ ** Infinities and NaNs no longer act as symbols on non-IEEE platforms. On old platforms like the VAX that do not support IEEE floating-point, -tokens like 0.0e+NaN and 1.0e+INF are no longer read as symbols. +tokens like '0.0e+NaN' and '1.0e+INF' are no longer read as symbols. Instead, the Lisp reader approximates an infinity with the nearest finite value, and a NaN with some other non-numeric object that provokes an error if used numerically. @@ -2309,7 +2309,7 @@ You may need to recompile your code if it was compiled with Emacs < 24.3. --- ** Old derived.el functions removed. The following functions have been deleted because they were only used -by code compiled with Emacs<21: +by code compiled with Emacs < 21: 'derived-mode-init-mode-variables', 'derived-mode-merge-abbrev-tables', 'derived-mode-merge-keymaps', 'derived-mode-merge-syntax-tables', 'derived-mode-run-hooks', 'derived-mode-set-abbrev-table', @@ -2338,7 +2338,7 @@ which wheel event (if any). +++ ** New hook 'hack-dir-local-get-variables-functions'. This can be used to provide support for other directory-local settings -beside '.dir-locals.el'. +beside ".dir-locals.el". +++ ** 'auto-coding-functions' can know the name of the file. @@ -2347,7 +2347,7 @@ which the text belongs by consulting the variable 'auto-coding-file-name'. +++ ** New user option 'compilation-safety' to control safety of native code. -It's now possible to control how safe is the code generated by native +It is now possible to control how safe is the code generated by native compilation, by customizing this user option. It is also possible to control this at function granularity by using the new 'safety' parameter in the function's 'declare' form. @@ -2593,8 +2593,8 @@ only return that string, and will not use it as a docstring. Example: (defun sing-a-song () "Sing a song.") -The above function returns the string '"Sing a song."' and has no doc -string. Previously, that string was used as both the doc string and +The above function returns the string "Sing a song." and has no +docstring. Previously, that string was used as both the docstring and return value, which was never what the programmer wanted. If you want the string to be a docstring, add an explicit return value. @@ -3015,7 +3015,7 @@ aforementioned functions: ** 'vtable-update-object' updates an existing object with just two arguments. It is now possible to update the representation of an object in a vtable by calling 'vtable-update-object' with just the vtable and the object as -arguments. (Previously the 'old-object' argument was required which, in +arguments. (Previously, the OLD-OBJECT argument was required which, in this case, would mean repeating the object in the argument list.) When replacing an object with a different one, passing both the new and old objects is still necessary. @@ -3108,9 +3108,9 @@ will disregard the system's Dark mode and will always use the default Light mode. --- -*** You can now use Image-Dired even if 'convert' command is not installed. +*** You can now use Image-Dired even if the 'convert' program is not installed. If you don't have GraphicsMagick or ImageMagick installed, and thus the -'gm convert'/'convert' command is not available, Emacs on MS-Windows +'gm convert'/'convert' program is not available, Emacs on MS-Windows will now use its own function 'w32image-create-thumbnail' to create thumbnail images and show them in the thumbnail buffer. Unlike with using 'convert', this fallback method is synchronous, so Emacs will wait commit 850fc68481a75c3c5d97b0c694159110785aa524 Author: Eshel Yaron Date: Tue Jul 2 14:03:01 2024 +0200 ; (grep-read-files): Fix completion table * lisp/progmodes/grep.el (grep-read-files): Cease returning some completion candidates unconditionally. Use 'completion-file-name-table' over 'read-file-name-internal' because the latter uses 'completion-table-with-quoting', and that doesn't blend well with other tables in 'completion-table-merge'. https://lists.gnu.org/archive/html/emacs-devel/2024-06/msg01194.html diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 459f00e6805..e8d1e692d0f 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -1181,9 +1181,7 @@ REGEXP is used as a string in the prompt." (files (completing-read (format-prompt "Search for \"%s\" in files matching wildcard" default regexp) - (completion-table-merge - (lambda (_string _pred _action) defaults) - #'read-file-name-internal) + (completion-table-merge defaults #'completion-file-name-table) nil nil nil 'grep-files-history defaults))) (and files (or (cdr (assoc files grep-files-aliases)) commit 6b5accdc05d007ab4d1804865c1b043260006673 Author: Po Lu Date: Tue Jul 2 12:10:43 2024 +0800 Port seccomp acceleration to Linux 3.5.0 * etc/NEWS: Update correspondingly. * exec/Makefile.in (config-mips.m4): Don't define rule or predicate $(LOADOBJS) on it elsewhere than on MIPS. * exec/README: Direct developers to GDB. * exec/trace.c (finish_exec): Resume the tracee after reporting an error in `exec'. (after_fork): If seccomp is enabled on Android, and the kernel is 4.7 or earlier, detect whether revisions to the sequencing of seccomp events have been backported from 4.8. (exec_waitpid): Resume the process with PTRACE_CONT after receiving an unknown signal. (exec_init): Cease disabling seccomp on Android kernels earlier than 4.8. diff --git a/etc/NEWS b/etc/NEWS index 5c08bc7550f..2b1534c31eb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -59,7 +59,7 @@ default), the 'whitespace-cleanup' function will now add the newline. ** Process execution has been optimized on Android. The run-time performance of subprocesses on recent Android releases where a userspace executable loader is required has been optimized on -systems featuring Linux 4.8.0 and above. +systems featuring Linux 3.5.0 and above. ---------------------------------------------------------------------- diff --git a/exec/Makefile.in b/exec/Makefile.in index 6969039b0a4..7e681c0c3d8 100644 --- a/exec/Makefile.in +++ b/exec/Makefile.in @@ -90,16 +90,16 @@ ifeq ($(is_mips),yes) .s.o: $(M4) $< > $(notdir $<).s $(AS) $(ASFLAGS) $(notdir $<).s -o $@ -else -.s.o: - $(AS) $(ASFLAGS) $< -o $@ -endif # Set up dependencies for config-mips.m4. config-mips.m4: config-mips.m4.in cd $(srcdir) && ./config.status $@ $(LOADOBJS): config-mips.m4 +else +.s.o: + $(AS) $(ASFLAGS) $< -o $@ +endif # Set up rules to build libexec.a. diff --git a/exec/README b/exec/README index f7eb21cfc84..a1534503247 100644 --- a/exec/README +++ b/exec/README @@ -1,3 +1,6 @@ This directory holds the source code to a library used to replace the `execve' and `execveat' system calls, used by the Android port of Emacs to start executables without intervention from the system. + +The most edifying resource for developers will be GDB, or to be precise, +the Linux target implementations for architectures of interest. diff --git a/exec/trace.c b/exec/trace.c index dfbc255a894..2af6d867efe 100644 --- a/exec/trace.c +++ b/exec/trace.c @@ -845,7 +845,12 @@ finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) #else /* !__aarch64__ */ ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs); #endif /* __aarch64__ */ - return; + + /* Continue; not much in the way of remediation is available if + either of PTRACE_SETREGS and this resumption fails. */ + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, 0); + goto error; } /* Write the loader area to the stack, followed by its size and the @@ -1858,6 +1863,10 @@ after_fork (pid_t pid) { int wstatus, rc, flags; struct exec_tracee *tracee; +#if defined HAVE_SECCOMP && __ANDROID__ + int statusarg; + USER_REGS_STRUCT regs; +#endif /* defined HAVE_SECCOMP && __ANDROID__ */ /* First, wait for something to happen to PID. */ again: @@ -1897,14 +1906,86 @@ after_fork (pid_t pid) return 1; } - /* Request that the child stop upon the next system call, or the next - filter event. */ - rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), - pid, 0, 0); +#if defined HAVE_SECCOMP && __ANDROID__ + /* Certain Android kernels have received backports of those new + PTRACE_EVENT_SECCOMP semantics which were introduced in kernel + version 4.8, so that it is necessary to actively establish which + variant is in place. */ + + if (kernel_4_7_or_earlier && use_seccomp_p) + { + /* Request that the child stop upon the next `exec' system call, + one of which is assumed to always be issued by the child, as + below, but await the next stop, and examine its contents. + Anciently, the syscall-stop preceeded events marked + PTRACE_EVENT_SECCOMP, whereas this sequence is reversed in + 4.8+, and in releases with these changes backported. */ + + rc = ptrace (PTRACE_SYSCALL, pid, 0, 0); + if (rc) + return 1; + + while (true) + { + rc = waitpid (pid, &wstatus, __WALL); + if (rc != pid) + return 1; + + if (WIFSTOPPED (wstatus)) + { + /* Verify that this system call is `exec', not one issued + between PTRACE_TRACEME and `exec' intercepted by + PTRACE_SYSCALL. */ +#ifdef __aarch64__ + rc = aarch64_get_regs (pid, ®s); +#else /* !__aarch64__ */ + rc = ptrace (PTRACE_GETREGS, pid, NULL, ®s); +#endif /* __aarch64__ */ + if (rc) + return 1; + + if (regs.SYSCALL_NUM_REG == EXEC_SYSCALL) + { + statusarg = ((wstatus & 0xfff00) >> 8); + + if (statusarg == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))) + { + /* The first event to be delivered is a seccomp + stop, indicating that this is an unmodified + <4.7 kernel. Return to await the subsequent + syscall-stop, which should be received and + acted on by process_system_call. */ + rc = ptrace (PTRACE_SYSCALL, pid, 0, 0); + break; + } + else if (statusarg == (SIGTRAP | 0x80)) + { + /* Syscall-traps take priority. This is a + doctored 4.7 kernel. */ + kernel_4_7_or_earlier = false; + rc = ptrace (PTRACE_CONT, pid, 0, 0); + break; + } + } + + rc = ptrace (PTRACE_SYSCALL, pid, 0, 0); + if (rc) + return 1; + } + else + return 1; + } + } + else +#endif /* HAVE_SECCOMP && __ANDROID__ */ + /* Request that the child stop upon the next system call, or the + next filter event. */ + rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, 0); if (rc) return 1; - /* Enter the child in `tracing_processes'. */ + /* Enroll the child into `tracing_processes'. */ if (free_tracees) { @@ -2064,8 +2145,9 @@ exec_waitpid (pid_t pid, int *wstatus, int options) #endif /* SIGSYS */ default: - /* Continue the process until the next syscall. */ - ptrace (PTRACE_SYSCALL, pid, 0, status); + /* Resume the process as appropriate. */ + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, status); return -1; } } @@ -2117,20 +2199,7 @@ exec_init (const char *loader) else { if (major < 4 || (major == 4 && minor <= 7)) - { -#ifndef __ANDROID__ - kernel_4_7_or_earlier = true; -#else /* __ANDROID __ */ - /* Certain Android kernels have received backports of - those new PTRACE_EVENT_SECCOMP semantics which were - introduced in kernel version 4.8, so that it is - necessary to actively establish which variant is in - place. This being much too involved for code I cannot - test, simply disable seccomp on kernel releases subject - to these uncertainties. */ - use_seccomp_p = false; -#endif /* !__ANDROID__ */ - } + kernel_4_7_or_earlier = true; } } #endif /* HAVE_SECCOMP */ commit 921d40759e54e2fb5685a5b662b862ed614b9bc6 Author: Alan Mackenzie Date: Mon Jul 1 20:37:28 2024 +0000 Remove a reference to a non-existant variable from a doc-string * lisp/progmodes/cc-langs.el (c-opt-extra-label-key): Remove reference to c-nonlabel-decl-prefix-re from the doc string. diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 233d23492b6..72cfdfa8653 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -4396,10 +4396,9 @@ a label construct. This catches C++'s inheritance construct \"class foo (c-lang-defconst c-opt-extra-label-key "Optional regexp matching labels. -Normally, labels are detected according to `c-nonlabel-token-key', -`c-decl-prefix-re' and `c-nonlabel-decl-prefix-re'. This regexp can -be used if there are additional labels that aren't recognized that -way." +Normally, labels are detected according to `c-nonlabel-token-key' and +`c-decl-prefix-re'. This regexp can be used if there are additional +labels that aren't recognized that way." t nil objc (c-make-keywords-re t (c-lang-const c-protection-kwds))) (c-lang-defvar c-opt-extra-label-key (c-lang-const c-opt-extra-label-key)) commit 4c64b990873be1e6b99c0b988f2a117c2e08e784 Author: Eli Zaretskii Date: Mon Jul 1 20:33:52 2024 +0300 ; * etc/NEWS: Fix level of several entrries. diff --git a/etc/NEWS b/etc/NEWS index b99228f5a7a..704c4c7cc29 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -747,7 +747,7 @@ customizing the new user option 'text-mode-ispell-word-completion'. ** Internationalization --- -** Mode-line mnemonics for some coding-systems have changed. +*** Mode-line mnemonics for some coding-systems have changed. The mode-line mnemonic for 'utf-7' is now the lowercase 'u', to be consistent with the other encodings of this family. @@ -763,7 +763,7 @@ previous behavior of showing 'U' in the mode line for 'koi8-u': (coding-system-put 'koi8-u :mnemonic ?U) --- -** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'. +*** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'. VSCII-1 and TCVN-5712 are different names for the same character encoding. Therefore, the duplicate coding system definition has been dropped in favor of an alias. commit 459e635099bad257fc6739ddfccc437cac11bc96 Author: Eli Zaretskii Date: Mon Jul 1 20:30:23 2024 +0300 ; * etc/NEWS: Fix typo. diff --git a/etc/NEWS b/etc/NEWS index 6428ef651aa..b99228f5a7a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -434,7 +434,7 @@ the signature) the automatically inferred function type as well. --- *** 'describe-function' now shows the type of the function object. -The text used to say things like "car is is a built-in function" whereas +The text used to say things like "car is a built-in function" whereas it now says "car is a primitive-function" where "primitive-function" is the symbol returned by 'cl-type-of'. You can click on those words to get information about that type. commit e087d3009bf564446367a1465957d9ea7b699f01 Author: Po Lu Date: Mon Jul 1 22:55:03 2024 +0800 * exec/exec.c (exec_0): Restore erroneously deleted statement. diff --git a/exec/exec.c b/exec/exec.c index fad345c532c..775a8b06b96 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -974,6 +974,9 @@ exec_0 (char *name, struct exec_tracee *tracee, rewrite = buffer1 + link_size; remaining = buffer1 + sizeof buffer1 - rewrite - 1; memcpy (rewrite, name, strnlen (name, remaining)); + + /* Replace name with buffer1. */ + strcpy (name, buffer1); } } commit 085a813c338ed8cc56301c1ad6d797e2f5dbd683 Author: Po Lu Date: Mon Jul 1 21:44:40 2024 +0800 * configure.ac: Provide for invocations where no cache file is set. diff --git a/configure.ac b/configure.ac index fabb4bb232d..f0437d6f8cb 100644 --- a/configure.ac +++ b/configure.ac @@ -200,8 +200,9 @@ AS_IF([test "$XCONFIGURE" = "android"],[ # Derive a name for a cache file for this configure script from the # current, if specified. exec_cache_file= - AS_IF([test -n "$cache_file"], - [exec_cache_file="--cache-file=$cache_file.2"]) + AS_CASE([$cache_file], [/dev/null | ""], [], + [[[\\/]* | ?:[\\/]*]], [exec_cache_file="--cache-file=$cache_file.2"], + [*], [exec_cache_file="--cache-file=../$cache_file.2"]) OLDCWD=`pwd` cd exec $CONFIG_SHELL $emacs_srcdir/exec/configure \ @@ -1270,7 +1271,7 @@ packages targeting Android 2.2.])]) # And derive a name for the recursive configure invocation's cache # file if one should be specified for this. - AS_IF([test -n "$cache_file"], + AS_IF([test -n "$cache_file" && test "$cache_file" != "/dev/null"], [passthrough="$passthrough --cache-file=$cache_file.1"]) AS_IF([test "x$with_mailutils" = "xyes"], [emacs_use_mailutils=yes]) commit e64286f53c4f5b6c0ed385edfd63a782a8c90b9b Author: Po Lu Date: Mon Jul 1 21:35:03 2024 +0800 * configure.ac: Create a cache file for libexec. diff --git a/configure.ac b/configure.ac index d0c5d8b400d..fabb4bb232d 100644 --- a/configure.ac +++ b/configure.ac @@ -197,11 +197,16 @@ AS_IF([test "$XCONFIGURE" = "android"],[ AC_MSG_NOTICE([configuring in `exec']) + # Derive a name for a cache file for this configure script from the + # current, if specified. + exec_cache_file= + AS_IF([test -n "$cache_file"], + [exec_cache_file="--cache-file=$cache_file.2"]) OLDCWD=`pwd` cd exec $CONFIG_SHELL $emacs_srcdir/exec/configure \ --host=$host "CC=$CC" "LD=$CC" "AS=$CC" \ - "AR=$AR" "CFLAGS=$CFLAGS" + "AR=$AR" "CFLAGS=$CFLAGS" $exec_cache_file emacs_val=$? cd $OLDCWD commit 7050128cfe91a86f87dfe495ce8c3a1c82337db6 Author: Eli Zaretskii Date: Mon Jul 1 15:59:05 2024 +0300 ; * src/search.c (Fmatch_beginning, Fmatch_end): Doc fix. diff --git a/src/search.c b/src/search.c index 3c07933b5da..dd813eda913 100644 --- a/src/search.c +++ b/src/search.c @@ -2812,11 +2812,12 @@ match_limit (Lisp_Object num, bool beginningp) DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0, doc: /* Return position of start of text matched by last search. -SUBEXP, a number, specifies which parenthesized expression in the last - regexp. -Value is nil if SUBEXPth pair didn't match, or there were less than - SUBEXP pairs. -Zero means the entire text matched by the whole regexp or whole string. +SUBEXP, a number, specifies the parenthesized subexpression in the last + regexp for which to return the start position. +Value is nil if SUBEXPth subexpression didn't match, or there were fewer + than SUBEXP subexpressions. +SUBEXP zero means the entire text matched by the whole regexp or whole + string. Return value is undefined if the last search failed. */) (Lisp_Object subexp) @@ -2826,11 +2827,12 @@ Return value is undefined if the last search failed. */) DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0, doc: /* Return position of end of text matched by last search. -SUBEXP, a number, specifies which parenthesized expression in the last - regexp. -Value is nil if SUBEXPth pair didn't match, or there were less than - SUBEXP pairs. -Zero means the entire text matched by the whole regexp or whole string. +SUBEXP, a number, specifies the parenthesized subexpression in the last + regexp for which to return the start position. +Value is nil if SUBEXPth subexpression didn't match, or there were fewer + than SUBEXP subexpressions. +SUBEXP zero means the entire text matched by the whole regexp or whole + string. Return value is undefined if the last search failed. */) (Lisp_Object subexp) commit 5965614d3ecb6b09277ea857212467b2f3f9c8bc Author: Po Lu Date: Mon Jul 1 18:22:01 2024 +0800 ; * exec/trace.c (seccomp_system_call): Typo in commentary. diff --git a/exec/trace.c b/exec/trace.c index 7cf95ed5733..dfbc255a894 100644 --- a/exec/trace.c +++ b/exec/trace.c @@ -1605,8 +1605,8 @@ seccomp_system_call (struct exec_tracee *tracee) In this context processes are resumed with PTRACE_CONT unless it is an `open' syscall that is being intercepted, which, if successfully - intercepted, must receive adjustments to their stack pointer upon - completion of said system call. */ + intercepted, they must receive adjustments to their stack pointer + upon completion of said system call. */ assert (!tracee->waiting_for_syscall); /* Save the stack pointer. */ commit 708c6d83fc4774605acfcfc3920a8c66f428027f Author: Po Lu Date: Mon Jul 1 18:15:51 2024 +0800 ; * etc/NEWS: Announce last Android change. diff --git a/etc/NEWS b/etc/NEWS index 8e9e36f47ae..5c08bc7550f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -55,6 +55,12 @@ default), the 'whitespace-cleanup' function will now add the newline. * Changes in Emacs 31.1 on Non-Free Operating Systems +--- +** Process execution has been optimized on Android. +The run-time performance of subprocesses on recent Android releases +where a userspace executable loader is required has been optimized on +systems featuring Linux 4.8.0 and above. + ---------------------------------------------------------------------- This file is part of GNU Emacs. commit 71530ab1ae2609812a32ac531812b57c7b1a40b6 Merge: 311c677343e 1647494c04a Author: Po Lu Date: Mon Jul 1 18:12:40 2024 +0800 Merge from savannah/emacs-30 1647494c04a ; * etc/NEWS: Clarify. b2c966f8396 ; * src/treesit.c (Ftreesit_query_capture): Fix typo. ae385794206 * java/res/mipmap-v26/emacs_icon.xml: Define monospace icon. b2d99c0d0aa Improve `sentence-end-double-space` docstring # Conflicts: # etc/NEWS commit 311c677343e825b0df807d11d4a2bbb146da8af1 Merge: d5cae5ea367 9d62dbc1f79 Author: Po Lu Date: Mon Jul 1 18:12:38 2024 +0800 ; Merge from savannah/emacs-30 The following commit was skipped: 9d62dbc1f79 Backport file backup FAQ item to Emacs <28 commit d5cae5ea3675d05fe5df13f122f302e9993bb803 Merge: ebf5bcb9f0b 2f71460d52f Author: Po Lu Date: Mon Jul 1 18:12:38 2024 +0800 Merge from savannah/emacs-30 2f71460d52f More updates of documentation for Emacs 30 a9df581c403 ; * etc/NEWS: Copy-edit. dfbdd38f701 Revert "; * etc/NEWS: Move items to "Incompatible Lisp Ch... # Conflicts: # etc/NEWS commit ebf5bcb9f0b6adeb97a3918b8f3845844c9091b0 Author: Po Lu Date: Mon Jul 1 18:11:58 2024 +0800 Optimize process execution on Android * exec/configure.ac (REENTRANT): Remove option for reentrancy. (PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the program counter and enable seccomp if its headers are available. * exec/exec.c (write_load_command): Avoid defining unused variable. (exec_0): Remove code specific to REENTRANT configurations. * exec/exec.h (struct exec_tracee) : New fields for loader instructions and their size. * exec/exec1.c (main): Call exec_init before forking. * exec/mipsel-user.h (ELF_NGREG): Delete definition. (struct mipsel_regs): Reduce number of gregs to 32, but introduce separate fields for special registers. * exec/trace.c (use_seccomp_p): New variable; defile to false if !HAVE_SECCOMP. (remove_tracee): Cease providing for non-reentrant configurations. Release executable data if present. (handle_clone_prepare): Likewise. Resume process with PTRACE_CONT if seccomp-based interception is enabled. (handle_clone, check_signal): Resume processes as above. (handle_exec): Divide into two functions, with only rewriting the system call and generating instructions for the loader remaining in the first, and copying such instructions into the loader's stack removed into a new function, `finish_exec'. (finish_exec): New function. (handle_readlinkat, handle_openat): Abolish non-REENTRANT configurations. (process_system_call): Divide exec system calls into two phases, disambiguated by the value of tracee->waiting_for_syscall. Typo fixes. Accommodate syscall-exit-stops where the signal was initially intercepted by `seccomp_system_call'. (interesting_syscalls): New array. (ARRAYELTS): New macro. (seccomp_system_call, establish_seccomp_filter): New function. (tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if this is to be enabled. (after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process with PTRACE_CONT if seccomp-based interception is enabled. (exec_waitpid): Resume process with PTRACE_CONT if seccomp-based interception is enabled. Dispatch stops identifying as PTRACE_EVENT_SECCOMP to `seccomp_system_call'. (exec_init): Establish whether it is possible to enable seccomp. diff --git a/exec/configure.ac b/exec/configure.ac index 5be8a983718..c3e895740be 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -42,11 +42,6 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */]) -AC_ARG_WITH([reentrancy], - [AS_HELP_STRING([--with-reentrancy], - [Generate library which can be used within a signal handler.])], - [AC_DEFINE([REENTRANT], [1])]) - AC_USE_SYSTEM_EXTENSIONS AC_PROG_CC AC_PROG_CPP @@ -74,9 +69,9 @@ AC_CHECK_FUNC([process_vm_readv], ]])])]) AC_CHECK_HEADERS([sys/param.h sys/uio.h]) AC_CHECK_MEMBERS([siginfo_t.si_syscall], [], [], - [[ +[[ #include - ]]) +]]) AH_BOTTOM([ #ifdef HAVE_STDBOOL_H @@ -120,6 +115,7 @@ AH_TEMPLATE([SYSCALL_ARG2_REG], [Define to register holding arg2 to system calls AH_TEMPLATE([SYSCALL_ARG3_REG], [Define to register holding arg3 to system calls.]) AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.]) AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) +AH_TEMPLATE([PROGRAM_COUNTER], [Define to register holding the program counter.]) AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) AH_TEMPLATE([USER_WORD], [Define to word type used by tracees.]) AH_TEMPLATE([USER_SWORD], [Define to signed word type used by tracees.]) @@ -134,7 +130,8 @@ AH_TEMPLATE([READLINK_SYSCALL], [Define to number of the `readlink' system call. AH_TEMPLATE([READLINKAT_SYSCALL], [Define to number of the `readlinkat' system call.]) AH_TEMPLATE([OPEN_SYSCALL], [Define to number of the `open' system call.]) AH_TEMPLATE([OPENAT_SYSCALL], [Define to number of the `openat' system call.]) -AH_TEMPLATE([REENTRANT], [Define to 1 if the library is used within a signal handler.]) +AH_TEMPLATE([HAVE_SECCOMP], [Define to 1 if secure computing filters are available +to accelerate interception of system calls.]) AC_CANONICAL_HOST @@ -250,6 +247,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [rdx]) AC_DEFINE([SYSCALL_ARG3_REG], [r10]) AC_DEFINE([STACK_POINTER], [rsp]) + AC_DEFINE([PROGRAM_COUNTER], [rip]) AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -283,6 +281,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [edx]) AC_DEFINE([SYSCALL_ARG3_REG], [esi]) AC_DEFINE([STACK_POINTER], [esp]) + AC_DEFINE([PROGRAM_COUNTER], [eip]) AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -314,6 +313,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [[regs[2]]]) AC_DEFINE([SYSCALL_ARG3_REG], [[regs[3]]]) AC_DEFINE([STACK_POINTER], [sp]) + AC_DEFINE([PROGRAM_COUNTER], [pc]) AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -346,6 +346,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]]) AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]]) AC_DEFINE([STACK_POINTER], [[uregs[13]]]) + AC_DEFINE([PROGRAM_COUNTER], [[uregs[15]]]) AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -371,6 +372,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]]) AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]]) AC_DEFINE([STACK_POINTER], [[uregs[13]]]) + AC_DEFINE([STACK_POINTER], [[uregs[15]]]) AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -402,6 +404,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2 AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3 AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp + AC_DEFINE([PROGRAM_COUNTER], [[cp0_epc]]) # pc AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -432,6 +435,7 @@ AS_CASE([$host], [x86_64-*linux*], AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2 AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3 AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp + AC_DEFINE([PROGRAM_COUNTER], [[cp0_epc]]) # pc AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) AC_DEFINE([USER_WORD], [uintptr_t]) AC_DEFINE([USER_SWORD], [intptr_t]) @@ -480,6 +484,12 @@ AC_ARG_VAR([LOADERFLAGS], [Flags used to link the loader.]) AC_ARG_VAR([ARFLAGS], [Flags for the archiver.]) AC_ARG_VAR([ASFLAGS], [Flags for the assembler.]) +# Search for seccomp headers and declarations. +AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h], + [AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, SECCOMP_RET_TRACE], + [AC_DEFINE([HAVE_SECCOMP], [1])], [], + [[#include ]])]) + # Make the assembler optimize for code size. Don't do this on MIPS, # as the assembler code manages branch delays manually. diff --git a/exec/exec.c b/exec/exec.c index cbe22d4f18c..fad345c532c 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -292,7 +292,9 @@ write_load_command (program_header *header, bool use_alternate, struct exec_map_command command1; USER_WORD start, end; bool need_command1; +#ifndef PAGE_MASK static long pagesize; +#endif /* !PAGE_MASK */ /* First, write the commands necessary to map the specified segment itself. @@ -306,14 +308,14 @@ write_load_command (program_header *header, bool use_alternate, #ifdef HAVE_GETPAGESIZE if (!pagesize) pagesize = getpagesize (); -#else /* HAVE_GETPAGESIZE */ +#else /* !HAVE_GETPAGESIZE */ if (!pagesize) pagesize = sysconf (_SC_PAGESIZE); -#endif /* HAVE_GETPAGESIZE */ +#endif /* !HAVE_GETPAGESIZE */ #define PAGE_MASK (~(pagesize - 1)) #define PAGE_SIZE (pagesize) -#endif /* PAGE_MASK */ +#endif /* !PAGE_MASK */ start = header->p_vaddr & PAGE_MASK; end = ((header->p_vaddr + header->p_filesz @@ -895,10 +897,6 @@ format_pid (char *in, unsigned int pid) with #!; in that case, find the program to open and use that instead. - If REENTRANT is not defined, NAME is actually a buffer of size - PATH_MAX + 80. In that case, copy over the file name actually - opened. - Next, read the executable header, and add the necessary memory mappings for each file. Finally, return the action data and its size in *SIZE. @@ -976,11 +974,6 @@ exec_0 (char *name, struct exec_tracee *tracee, rewrite = buffer1 + link_size; remaining = buffer1 + sizeof buffer1 - rewrite - 1; memcpy (rewrite, name, strnlen (name, remaining)); - - /* Replace name with buffer1. */ -#ifndef REENTRANT - strcpy (name, buffer1); -#endif /* REENTRANT */ } } diff --git a/exec/exec.h b/exec/exec.h index 3ce06c35311..59963587573 100644 --- a/exec/exec.h +++ b/exec/exec.h @@ -152,6 +152,16 @@ struct exec_tracee completion. */ USER_WORD sp; + /* Name of the executable being run. */ + char *exec_file; + + /* Pointer to a storage area holding instructions for loading an + executable if an `exec' system call is outstanding, or NULL. */ + char *exec_data; + + /* Number of bytes in exec_data. */ + size_t data_size; + /* The thread ID of this process. */ pid_t pid; @@ -162,11 +172,6 @@ struct exec_tracee /* Whether or not the tracee has been created but is not yet processed by `handle_clone'. */ bool new_child : 1; - -#ifndef REENTRANT - /* Name of the executable being run. */ - char *exec_file; -#endif /* !REENTRANT */ }; diff --git a/exec/exec1.c b/exec/exec1.c index aaff9a94c62..cbd756d3d5c 100644 --- a/exec/exec1.c +++ b/exec/exec1.c @@ -42,6 +42,9 @@ main (int argc, char **argv) extern char **environ; int wstatus; + /* Provide the file name of the loader. */ + exec_init (argv[1]); + pid1 = getpid (); pid = fork (); @@ -58,9 +61,6 @@ main (int argc, char **argv) } else { - /* Provide the file name of the loader. */ - exec_init (argv[1]); - if (after_fork (pid)) exit (127); diff --git a/exec/mipsel-user.h b/exec/mipsel-user.h index 04f4a2a5089..14d8f6d0d5e 100644 --- a/exec/mipsel-user.h +++ b/exec/mipsel-user.h @@ -24,10 +24,6 @@ along with GNU Emacs. If not, see . */ #include -#ifndef ELF_NGREG -#define ELF_NGREG 45 -#endif /* ELF_NGREG */ - /* This file defines a structure containing user mode general purpose @@ -36,7 +32,15 @@ along with GNU Emacs. If not, see . */ struct mipsel_regs { /* General purpose registers. */ - uint64_t gregs[ELF_NGREG]; + uint64_t gregs[32]; + + /* Saved special registers. */ + uint64_t lo; + uint64_t hi; + uint64_t cp0_epc; + uint64_t cp0_badvaddr; + uint64_t cp0_status; + uint64_t cp0_cause; }; #endif /* _MIPSEL_USER_H_ */ diff --git a/exec/trace.c b/exec/trace.c index 05d862f5b9f..7cf95ed5733 100644 --- a/exec/trace.c +++ b/exec/trace.c @@ -49,11 +49,21 @@ along with GNU Emacs. If not, see . */ #ifndef SYS_SECCOMP #define SYS_SECCOMP 1 -#endif /* SYS_SECCOMP */ +#endif /* !defined SYS_SECCOMP */ #ifndef PTRACE_GETEVENTMSG #define PTRACE_GETEVENTMSG 0x4201 -#endif /* PTRACE_GETEVENTMSG */ +#endif /* !defined PTRACE_GETEVENTMSG */ + +#ifdef HAVE_SECCOMP +#include +#include + +#include +#include + +#include +#endif /* !defined HAVE_SECCOMP */ @@ -70,6 +80,15 @@ along with GNU Emacs. If not, see . */ /* Number of tracees children are allowed to create. */ #define MAX_TRACEES 4096 +#ifdef HAVE_SECCOMP + +/* Whether to enable seccomp acceleration. */ +static bool use_seccomp_p; + +#else /* !HAVE_SECCOMP */ +#define use_seccomp_p (false) +#endif /* HAVE_SECCOMP */ + #ifdef __aarch64__ /* Place PID's registers into *REGS. Return 1 upon failure, else @@ -105,8 +124,7 @@ aarch64_set_regs (pid_t pid, USER_REGS_STRUCT *regs, iov.iov_base = regs; iov.iov_len = sizeof *regs; - rc = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS, - &iov); + rc = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov); if (rc < 0) return 1; @@ -367,14 +385,17 @@ remove_tracee (struct exec_tracee *tracee) /* Link the tracee onto the list of free tracees. */ tracee->next = free_tracees; -#ifndef REENTRANT /* Free the exec file, if any. */ free (tracee->exec_file); tracee->exec_file = NULL; -#endif /* REENTRANT */ - free_tracees = tracee; + /* Likewise with any loader instructions that might be + present. */ + free (tracee->exec_data); + tracee->exec_data = NULL; + /* Return this tracee to the list of free ones. */ + free_tracees = tracee; return; } else @@ -419,7 +440,6 @@ find_tracee (pid_t process) static void handle_clone_prepare (struct exec_tracee *parent) { -#ifndef REENTRANT long rc; unsigned long pid; struct exec_tracee *tracee; @@ -440,7 +460,8 @@ handle_clone_prepare (struct exec_tracee *parent) assert (tracee->new_child); tracee->new_child = false; tracee->exec_file = NULL; - ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, 0); if (parent->exec_file) tracee->exec_file = strdup (parent->exec_file); @@ -457,12 +478,9 @@ handle_clone_prepare (struct exec_tracee *parent) tracee = &static_tracees[tracees]; tracees++; } -#ifndef REENTRANT - /* Try to allocate a tracee using `malloc' if this library is - not being built to run inside a signal handler. */ + /* Try to allocate a tracee using `malloc'. */ else if ((tracee = malloc (sizeof *tracee))) ; -#endif /* REENTRANT */ else return; @@ -477,7 +495,6 @@ handle_clone_prepare (struct exec_tracee *parent) if (parent->exec_file) tracee->exec_file = strdup (parent->exec_file); -#endif /* REENTRANT */ } /* Handle the completion of a `clone' or `clone3' system call, @@ -513,21 +530,18 @@ handle_clone (struct exec_tracee *tracee, pid_t pid) tracee = &static_tracees[tracees]; tracees++; } -#ifndef REENTRANT - /* Try to allocate a tracee using `malloc' if this library is - not being built to run inside a signal handler. */ + /* Try to allocate a tracee using `malloc'. */ else if ((tracee = malloc (sizeof *tracee))) ; -#endif /* REENTRANT */ else return 1; tracee->pid = pid; tracee->next = tracing_processes; tracee->waiting_for_syscall = false; -#ifndef REENTRANT tracee->exec_file = NULL; -#endif /* REENTRANT */ + tracee->exec_data = NULL; + tracee->data_size = 0; tracing_processes = tracee; tracee->new_child = true; @@ -549,6 +563,11 @@ handle_clone (struct exec_tracee *tracee, pid_t pid) flags |= PTRACE_O_TRACESYSGOOD; flags |= PTRACE_O_TRACEEXIT; +#ifdef HAVE_SECCOMP + if (use_seccomp_p) + flags |= PTRACE_O_TRACESECCOMP; +#endif /* HAVE_SECCOMP */ + rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags); if (rc) @@ -559,7 +578,8 @@ handle_clone (struct exec_tracee *tracee, pid_t pid) /* The new tracee is currently stopped. Continue it until the next system call. */ - rc = ptrace (PTRACE_SYSCALL, pid, 0, 0); + rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, 0); if (rc) goto bail; @@ -618,9 +638,11 @@ check_signal (struct exec_tracee *tracee, int status) { if (siginfo.si_code < 0) /* SIGTRAP delivered from userspace. Pass it on. */ - ptrace (PTRACE_SYSCALL, tracee->pid, 0, SIGTRAP); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, SIGTRAP); else - ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, 0); return 1; } @@ -639,26 +661,28 @@ check_signal (struct exec_tracee *tracee, int status) it. */ #ifdef HAVE_SIGINFO_T_SI_SYSCALL #ifndef __arm__ - ptrace (PTRACE_SYSCALL, tracee->pid, + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid, 0, ((siginfo.si_code == SYS_SECCOMP && siginfo.si_syscall == -1) ? 0 : status)); #else /* __arm__ */ - ptrace (PTRACE_SYSCALL, tracee->pid, + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid, 0, ((siginfo.si_code == SYS_SECCOMP && siginfo.si_syscall == 222) ? 0 : status)); #endif /* !__arm__ */ #else /* !HAVE_SIGINFO_T_SI_SYSCALL */ /* Drop this signal, since what caused it is unknown. */ - ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid, + 0, 0); #endif /* HAVE_SIGINFO_T_SI_SYSCALL */ return 1; #endif /* SIGSYS */ default: /* Continue the process until the next syscall. */ - ptrace (PTRACE_SYSCALL, tracee->pid, 0, status); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, status); return 1; } @@ -667,17 +691,16 @@ check_signal (struct exec_tracee *tracee, int status) -/* Handle an `exec' system call from the given TRACEE. REGS are the - tracee's current user-mode registers. +/* Handle the first stage of an `exec' system call from the given + TRACEE. REGS are the tracee's current user-mode registers. Rewrite the system call arguments to use the loader binary. Then, - continue the system call until the loader is loaded. Write the - information necessary to load the original executable into the - loader's stack. + resume the process till the loader is loaded and about to begin + execution. Save instructions to load the original executable into + TRACEE->exec_data. Value is 0 upon success, 1 upon a generic failure before the loader - is loaded, 2 if the process has stopped, and 3 if something failed, - but it is too late to handle it. + is loaded. Set errno appropriately upon returning a generic failure. */ @@ -687,16 +710,10 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) char buffer[PATH_MAX + 80], *area; USER_REGS_STRUCT original; size_t size, loader_size; - USER_WORD loader, size1, sp; - int rc, wstatus; - siginfo_t siginfo; - - /* Save the old stack pointer. */ - sp = regs->STACK_POINTER; + USER_WORD loader; /* Read the file name. */ - read_memory (tracee, buffer, PATH_MAX, - regs->SYSCALL_ARG_REG); + read_memory (tracee, buffer, PATH_MAX, regs->SYSCALL_ARG_REG); /* Make sure BUFFER is NULL terminated. */ @@ -722,8 +739,18 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) return 1; } - /* Rewrite the first argument to point to the loader. */ + /* Save this area in the tracee. */ + assert (!tracee->exec_data); + tracee->exec_data = malloc (size); + if (!tracee->exec_data) + { + errno = ENOMEM; + return 1; + } + memcpy (tracee->exec_data, area, size); + tracee->data_size = size; + /* Rewrite the first argument to point to the loader. */ loader_size = strlen (loader_name) + 1; loader = user_alloca (tracee, &original, regs, loader_size); @@ -731,14 +758,14 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) if (!loader) { errno = ENOMEM; - return 1; + goto free_data_error; } if (user_copy (tracee, (unsigned char *) loader_name, loader, loader_size)) { errno = EIO; - return 1; + goto free_data_error; } regs->SYSCALL_ARG_REG = loader; @@ -748,151 +775,113 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) if (aarch64_set_regs (tracee->pid, regs, false)) { errno = EIO; - return 1; + goto free_data_error; } #else /* !__aarch64__ */ - if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, - regs)) + if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs)) { errno = EIO; - return 1; + goto free_data_error; } #endif /* __aarch64__ */ - /* Continue the system call until loader starts. */ + /* Resume the process till the loader is executed. */ if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL)) { errno = EIO; - return 1; + goto free_data_error; } -#ifndef REENTRANT - /* Now that the loader has started, record the value to use for - /proc/self/exe. Don't give up just because strdup fails. + /* Now that the loader has been executed, record the value to + substitute for /proc/self/exe. Don't give up just because strdup + fails. Note that exec_0 copies the absolute file name into buffer. */ if (tracee->exec_file) free (tracee->exec_file); tracee->exec_file = strdup (buffer); -#endif /* REENTRANT */ - - again: - rc = waitpid (tracee->pid, &wstatus, __WALL); - if (rc == -1 && errno == EINTR) - goto again; - - if (rc < 0) - return 1; - - if (!WIFSTOPPED (wstatus)) - /* The process has been killed in response to a signal. - In this case, simply return 2. */ - return 2; - else - { - /* Then, check if STATUS is not a syscall-stop, and try again if - it isn't. */ - rc = check_signal (tracee, wstatus); - - if (rc == -1) - return 2; - else if (rc) - goto again; - - /* Retrieve the signal information and determine whether or not - the system call has completed. */ - - if (ptrace (PTRACE_GETSIGINFO, tracee->pid, 0, - &siginfo)) - return 3; - - if (!syscall_trap_p (&siginfo)) - { - /* Continue. */ - if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0)) - return 3; - - goto again; - } - } - -#ifdef __aarch64__ - - if (aarch64_get_regs (tracee->pid, &original)) - return 3; + return 0; -#else /* !__aarch64__ */ + free_data_error: + free (tracee->exec_data); + tracee->exec_data = NULL; + return 1; +} - /* The system call has now completed. Get the registers again. */ +/* Complete an `exec' system call issued by TRACEE. Write the + instructions stored in TRACEE->exec_data to an appropriate location + in TRACEE's stack, and resume TRACEE, releasing TRACEE->exec_data. + REGS should be the TRACEE's user registers. If the reissued system + call did not succeed in starting the executable loader, restore + TRACEE->sp (recorded by process_system_call or seccomp_system_call), + and resume execution, so that the failure may be reported. */ - if (ptrace (PTRACE_GETREGS, tracee->pid, NULL, - &original)) - return 3; +static void +finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) +{ + USER_WORD size1, loader; + USER_REGS_STRUCT original; -#endif /* __aarch64__ */ + size1 = tracee->data_size; - *regs = original; + /* Record the registers' values as they originally were. */ + memcpy (&original, regs, sizeof *regs); - /* Upon failure, wait for the next system call and return - success. */ + /* Any non-zero value of `original.SYSCALL_RET_REG' indicates that the + reissued `exec' call was unsuccessful, and the loader is not + executing. Restore the previous stack pointer and permit the + tracee to run to completion. */ if (original.SYSCALL_RET_REG) { - /* Restore the original stack pointer. */ - regs->STACK_POINTER = sp; - + regs->STACK_POINTER = tracee->sp; #ifdef __aarch64__ aarch64_set_regs (tracee->pid, regs, false); #else /* !__aarch64__ */ ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs); #endif /* __aarch64__ */ - - goto exec_failure; + return; } /* Write the loader area to the stack, followed by its size and the original stack pointer. */ loader = user_alloca (tracee, &original, regs, - size + sizeof loader * 2); + size1 + sizeof loader * 2); if (!loader) - return 3; - - size1 = size; + goto error; #ifndef STACK_GROWS_DOWNWARDS - - NOT_IMPLEMENTED; - + not implemented, you lose. #else /* STACK_GROWS_DOWNWARDS */ - if (user_copy (tracee, (unsigned char *) area, - loader + sizeof size1 * 2, size) + if (user_copy (tracee, (unsigned char *) tracee->exec_data, + loader + sizeof size1 * 2, size1) || user_copy (tracee, (unsigned char *) &size1, loader + sizeof size1, sizeof size1)) - return 3; + goto error; size1 = original.STACK_POINTER; if (user_copy (tracee, (unsigned char *) &size1, loader, sizeof size1)) - return 3; + goto error; #endif /* STACK_GROWS_DOWNWARDS */ /* Continue. */ - if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0)) - return 3; - - return 0; + if (ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, 0, 0)) + goto error; - exec_failure: - return 3; + error: + free (tracee->exec_data); + tracee->exec_data = NULL; } @@ -1007,13 +996,6 @@ static int handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs, struct exec_tracee *tracee, USER_WORD *result) { -#ifdef REENTRANT - /* readlinkat cannot be handled specially when the library is built - to be reentrant, as the file name information cannot be - recorded. */ - return 0; -#else /* !REENTRANT */ - char buffer[PATH_MAX + 1]; USER_WORD address, return_buffer, size; size_t length; @@ -1086,7 +1068,6 @@ handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs, *result = length; return 2; -#endif /* REENTRANT */ } /* Handle an `open' or `openat' system call. @@ -1104,12 +1085,6 @@ static int handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs, struct exec_tracee *tracee, USER_WORD *result) { -#ifdef REENTRANT - /* readlinkat cannot be handled specially when the library is built - to be reentrant, as the file name information cannot be - recorded. */ - return 0; -#else /* !REENTRANT */ char buffer[PATH_MAX + 1]; USER_WORD address; size_t length; @@ -1199,7 +1174,6 @@ handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs, fail: errno = EIO; return 1; -#endif /* REENTRANT */ } /* Process the system call at which TRACEE is stopped. If the system @@ -1229,30 +1203,43 @@ process_system_call (struct exec_tracee *tracee) /* Save the stack pointer. */ sp = regs.STACK_POINTER; - /* Now dispatch based on the system call. */ - callno = regs.SYSCALL_NUM_REG; + /* Now dispatch based on the system call. If TRACEE->exec_data is + set, this must be exec, whatever the value of SYSCALL_NUM_REG, + which is erased when exec loads another image. */ + + callno = (!tracee->exec_data ? regs.SYSCALL_NUM_REG : EXEC_SYSCALL); switch (callno) { case EXEC_SYSCALL: - /* exec system calls should be handled synchronously. */ - assert (!tracee->waiting_for_syscall); - rc = handle_exec (tracee, ®s); - - switch (rc) + if (!tracee->waiting_for_syscall) { - case 3: - /* It's too late to do anything about this error,. */ - break; + /* The outstanding syscall flag must not be inconsistent with + the presence of instructions for the loader. */ + assert (!tracee->exec_data); + rc = handle_exec (tracee, ®s); - case 2: - /* The process has gone away. */ - remove_tracee (tracee); - break; + if (rc) + /* An error has occurred; errno is set to the error. */ + goto report_syscall_error; + + /* The process has been resumed. Assert that the instructions + for loading this executable have been generated and + recorded, and set waiting_for_syscall. */ + tracee->waiting_for_syscall = true; + assert (tracee->exec_data); - case 1: - /* An error has occurred; errno is set to the error. */ - goto report_syscall_error; + /* Record the initial stack pointer also. */ + tracee->sp = sp; + } + else + { + assert (tracee->exec_data); + finish_exec (tracee, ®s); + + /* The process has been resumed and has become capable of + executing independently. */ + tracee->waiting_for_syscall = false; } break; @@ -1311,7 +1298,7 @@ process_system_call (struct exec_tracee *tracee) regs.STACK_POINTER = tracee->sp; #ifdef __aarch64__ - if (aarch64_set_regs (tracee->pid, ®s, true)) + if (aarch64_set_regs (tracee->pid, ®s, false)) return; #else /* !__aarch64__ */ if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s)) @@ -1327,11 +1314,35 @@ process_system_call (struct exec_tracee *tracee) will DTRT upon the next call to PTRACE_SYSCALL after the syscall-trap signal is delivered. */ - rc = ptrace (PTRACE_SYSCALL, tracee->pid, + rc = ptrace (((use_seccomp_p + /* open and openat are not processed synchronously, + nor can they afford to dispense with + post-syscall finalization. */ + + && ((callno != OPENAT_SYSCALL +#ifdef OPEN_SYSCALL + && callno != OPEN_SYSCALL +#endif /* OPEN_SYSCALL */ + ) + /* Since syscall initialization should be + reserved for seccomp_system_call, resume the + process if this system call is already + complete. */ + || !tracee->waiting_for_syscall)) + ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid, NULL, NULL); if (rc < 0) return; +#ifdef HAVE_SECCOMP + if (!(use_seccomp_p + && ((callno != OPENAT_SYSCALL +#ifdef OPEN_SYSCALL + && callno != OPEN_SYSCALL +#endif /* OPEN_SYSCALL */ + ) + || !tracee->waiting_for_syscall))) +#endif /* !HAVE_SECCOMP */ tracee->waiting_for_syscall = !tracee->waiting_for_syscall; } @@ -1345,9 +1356,10 @@ process_system_call (struct exec_tracee *tracee) reporting_error = false; common: - /* Reporting an error or emulating a system call works by setting - the system call number to -1, letting it continue, and then - substituting errno for ENOSYS in the case of an error. + /* Reporting an error or emulating a system call works by replacing + the system call number with -1 or another nonexistent syscall, + letting it continue, and then substituting errno for ENOSYS in the + case of an error. Make sure that the stack pointer is restored to its original position upon exit, or bad things can happen. */ @@ -1426,13 +1438,13 @@ process_system_call (struct exec_tracee *tracee) #endif /* __aarch64__ */ /* Now wait for the next system call to happen. */ - ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, NULL, NULL); } else { /* No error is being reported. Return the result in the appropriate registers. */ - #ifdef __mips__ /* MIPS systems place errno in v0 and set a3 to 1. */ regs.gregs[2] = result; @@ -1449,14 +1461,367 @@ process_system_call (struct exec_tracee *tracee) #endif /* __aarch64__ */ /* Now wait for the next system call to happen. */ - ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + tracee->pid, NULL, NULL); } } +#ifdef HAVE_SECCOMP + +/* Seccomp acceleration. + + Seccomp enables selectively filtering signals so that the tracing + process is only notified of such system calls as it is interested in + intercepting, i.e., exec and open*. This improves performance + enormously over the traditional approach of pausing the tracee before + each system call. */ + +/* Whether the kernel's version is 4.7.x or earlier. */ +static bool kernel_4_7_or_earlier; + +/* Array of system calls this module is interested in intercepting. */ +static int interesting_syscalls[] = + { + EXEC_SYSCALL, +#ifdef OPEN_SYSCALL + OPEN_SYSCALL, +#endif /* OPEN_SYSCALL */ + OPENAT_SYSCALL, +#ifdef READLINK_SYSCALL + READLINK_SYSCALL, +#endif /* READLINK_SYSCALL */ + READLINKAT_SYSCALL, + }; + +/* Number of elements in an array. */ +#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0]) + +/* Install a secure computing filter that will notify attached tracers + when a system call of interest to this module is received. Value is + 0 if successful, 1 otherwise. */ + +static int +establish_seccomp_filter (void) +{ + struct sock_filter statements[1 + ARRAYELTS (interesting_syscalls) + 2]; + struct sock_fprog program; + int index, rc; + + index = 0; + + /* As the exec wrapper will reject executables for an inappropriate + architecture, verifying the same here would only be redundant. + Proceed to load the current system call number. */ + + statements[index++] = ((struct sock_filter) + BPF_STMT (BPF_LD + BPF_W + BPF_ABS, + offsetof (struct seccomp_data, nr))); + + /* Search for system calls of interest. */ + + statements[index] + = ((struct sock_filter) + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, EXEC_SYSCALL, + ARRAYELTS (interesting_syscalls), 0)); index++; +#ifdef OPEN_SYSCALL + statements[index] + = ((struct sock_filter) + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, OPEN_SYSCALL, + ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++; +#endif /* OPEN_SYSCALL */ + statements[index] + = ((struct sock_filter) + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, OPENAT_SYSCALL, + ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++; +#ifdef READLINK_SYSCALL + statements[index] + = ((struct sock_filter) + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, READLINK_SYSCALL, + ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++; +#endif /* READLINK_SYSCALL */ + statements[index] + = ((struct sock_filter) + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, READLINKAT_SYSCALL, + ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++; + + /* If not intercepted above, permit this system call to execute as + normal. */ + statements[index++] + = (struct sock_filter) BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_ALLOW); + statements[index++] + = (struct sock_filter) BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_TRACE); + + rc = prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + if (rc) + return 1; + + program.len = ARRAYELTS (statements); + program.filter = statements; + rc = prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &program); + if (rc) + return 1; + + return 0; +} + +/* Intercept or resume and dismiss the system call at which TRACEE is + paused, similarly to process_system_call. */ + +static void +seccomp_system_call (struct exec_tracee *tracee) +{ + USER_REGS_STRUCT regs; + int rc, wstatus, save_errno; + USER_WORD callno, sp; + USER_WORD result; + bool reporting_error; + + if (kernel_4_7_or_earlier) + { + /* On kernel 4.7 and earlier, following a PTRACE_EVENT_SECCOMP by + a PTRACE_SYSCALL will give rise to a syscall-entry stop event, + and seccomp filters will be suppressed till the system call + runs its course. */ + ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0); + return; + } + +#ifdef __aarch64__ + rc = aarch64_get_regs (tracee->pid, ®s); +#else /* !__aarch64__ */ + rc = ptrace (PTRACE_GETREGS, tracee->pid, NULL, + ®s); +#endif /* __aarch64__ */ + + /* TODO: what to do if this fails? */ + if (rc < 0) + return; + + /* On kernel 4.8, processes resumed after being paused so as to + produce a PTRACE_EVENT_SECCOMP will execute till the system call + completes, or indefinitely if resumed with PTRACE_CONT. + + In this context processes are resumed with PTRACE_CONT unless it is + an `open' syscall that is being intercepted, which, if successfully + intercepted, must receive adjustments to their stack pointer upon + completion of said system call. */ + assert (!tracee->waiting_for_syscall); + + /* Save the stack pointer. */ + sp = regs.STACK_POINTER; + + /* Now dispatch based on the system call. */ + callno = regs.SYSCALL_NUM_REG; + switch (callno) + { + case EXEC_SYSCALL: + assert (!tracee->exec_data); + rc = handle_exec (tracee, ®s); + + if (rc) + /* An error has occurred; errno is set to the error. */ + goto report_syscall_error; + + /* The process has been resumed. Assert that the instructions for + loading this executable have been generated and recorded, and + set waiting_for_syscall. */ + tracee->waiting_for_syscall = true; + assert (tracee->exec_data); + + /* Record the initial stack pointer also. */ + tracee->sp = sp; + break; + +#ifdef READLINK_SYSCALL + case READLINK_SYSCALL: +#endif /* READLINK_SYSCALL */ + case READLINKAT_SYSCALL: + /* Handle this readlinkat system call. */ + rc = handle_readlinkat (callno, ®s, tracee, + &result); + + /* rc means the same as in `handle_exec'. */ + + if (rc == 1) + goto report_syscall_error; + else if (rc == 2) + goto emulate_syscall; + + goto continue_syscall; + +#ifdef OPEN_SYSCALL + case OPEN_SYSCALL: +#endif /* OPEN_SYSCALL */ + case OPENAT_SYSCALL: + /* Handle this open system call. */ + rc = handle_openat (callno, ®s, tracee, &result); + + /* rc means the same as in `handle_exec', except that `open' + is never emulated. */ + + if (rc == 1) + goto report_syscall_error; + + /* The stack pointer must be restored after it was modified + by `user_alloca'; record sp in TRACEE, which will be + restored after this system call completes. */ + tracee->sp = sp; + + /* As such, arrange to enter `process_system_call' on its + completion. */ + rc = ptrace (PTRACE_SYSCALL, tracee->pid, + NULL, NULL); + if (rc < 0) + return; + + tracee->waiting_for_syscall = !tracee->waiting_for_syscall; + break; + + default: + continue_syscall: + rc = ptrace (PTRACE_CONT, tracee->pid, NULL, NULL); + if (rc < 0) + return; + } + + return; + + report_syscall_error: + reporting_error = true; + goto common; + + emulate_syscall: + reporting_error = false; + common: + + /* Reporting an error or emulating a system call works by replacing + the system call number with -1 or another nonexistent syscall, + letting it continue, and then substituting errno for ENOSYS in the + case of an error. + + Make sure that the stack pointer is restored to its original + position upon exit, or bad things can happen. */ + + /* First, save errno; system calls below will clobber it. */ + save_errno = errno; + + regs.SYSCALL_NUM_REG = -1; + regs.STACK_POINTER = sp; + +#ifdef __aarch64__ + if (aarch64_set_regs (tracee->pid, ®s, true)) + return; +#else /* !__aarch64__ */ + +#ifdef __arm__ + /* On ARM systems, a special request is used to update the system + call number as known to the kernel. In addition, the system call + number must be valid, so use `tuxcall'. Hopefully, nobody will + run this on a kernel with Tux. */ + + if (ptrace (PTRACE_SET_SYSCALL, tracee->pid, NULL, 222)) + return; +#endif /* __arm__ */ + + if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s)) + return; +#endif /* __aarch64__ */ + + /* Do this invalid system call. */ + if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL)) + return; + + again1: + rc = waitpid (tracee->pid, &wstatus, __WALL); + if (rc == -1 && errno == EINTR) + goto again1; + + /* Return if waitpid fails. */ + + if (rc == -1) + return; + + /* If the process received a signal, see if the signal is SIGSYS + and/or from seccomp. If so, discard it. */ + + if (WIFSTOPPED (wstatus)) + { + rc = check_signal (tracee, wstatus); + + if (rc == -1) + return; + else if (rc) + goto again1; + } + + if (!WIFSTOPPED (wstatus)) + /* The process has been killed in response to a signal. In this + case, simply unlink the tracee and return. */ + remove_tracee (tracee); + else if (reporting_error) + { +#ifdef __mips__ + /* MIPS systems place errno in v0 and set a3 to 1. */ + regs.gregs[2] = save_errno; + regs.gregs[7] = 1; +#else /* !__mips__ */ + regs.SYSCALL_RET_REG = -save_errno; +#endif /* __mips__ */ + + /* Report errno. */ +#ifdef __aarch64__ + aarch64_set_regs (tracee->pid, ®s, false); +#else /* !__aarch64__ */ + ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s); +#endif /* __aarch64__ */ + + /* Resume the process till the next interception by its filter. */ + ptrace (PTRACE_CONT, tracee->pid, NULL, NULL); + } + else + { + /* No error is being reported. Return the result in the + appropriate registers. */ + +#ifdef __mips__ + /* MIPS systems place errno in v0 and set a3 to 1. */ + regs.gregs[2] = result; + regs.gregs[7] = 0; +#else /* !__mips__ */ + regs.SYSCALL_RET_REG = result; +#endif /* __mips__ */ + + /* Report errno. */ +#ifdef __aarch64__ + aarch64_set_regs (tracee->pid, ®s, false); +#else /* !__aarch64__ */ + ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s); +#endif /* __aarch64__ */ + + /* Resume the process till the next interception by its filter. */ + ptrace (PTRACE_CONT, tracee->pid, NULL, NULL); + } +} + +#ifndef PTRACE_EVENT_SECCOMP +#define PTRACE_EVENT_SECCOMP 7 +#endif /* !PTRACE_EVENT_SECCOMP */ + +#ifndef PTRACE_O_TRACESECCOMP +#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP) +#endif /* !PTRACE_O_TRACESECCOMP */ + +#ifndef SIGSYS +#define SIGSYS 31 +#endif /* !SIGSYS */ +#endif /* HAVE_SECCOMP */ + + + /* Like `execve', but asks the parent to begin tracing this thread. - Fail if tracing is unsuccessful. */ + Fail by returning a non-zero value if tracing is unsuccessful. */ int tracing_execve (const char *file, char *const *argv, @@ -1471,6 +1836,13 @@ tracing_execve (const char *file, char *const *argv, /* Notify the parent to enter signal-delivery-stop. */ raise (SIGSTOP); + +#ifdef HAVE_SECCOMP + /* Install the seccomp filter. */ + if (use_seccomp_p && establish_seccomp_filter ()) + return 1; +#endif /* HAVE_SECCOMP */ + return execve (file, argv, envp); } @@ -1510,6 +1882,10 @@ after_fork (pid_t pid) flags |= PTRACE_O_TRACEFORK; flags |= PTRACE_O_TRACESYSGOOD; flags |= PTRACE_O_TRACEEXIT; +#ifdef HAVE_SECCOMP + if (use_seccomp_p) + flags |= PTRACE_O_TRACESECCOMP; +#endif /* HAVE_SECCOMP */ rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags); @@ -1521,8 +1897,10 @@ after_fork (pid_t pid) return 1; } - /* Request that the child stop upon the next system call. */ - rc = ptrace (PTRACE_SYSCALL, pid, 0, 0); + /* Request that the child stop upon the next system call, or the next + filter event. */ + rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, 0); if (rc) return 1; @@ -1543,9 +1921,9 @@ after_fork (pid_t pid) tracee->next = tracing_processes; tracee->waiting_for_syscall = false; tracee->new_child = false; -#ifndef REENTRANT tracee->exec_file = NULL; -#endif /* REENTRANT */ + tracee->exec_data = NULL; + tracee->data_size = 0; tracing_processes = tracee; return 0; } @@ -1604,9 +1982,11 @@ exec_waitpid (pid_t pid, int *wstatus, int options) { if (siginfo.si_code < 0) /* SIGTRAP delivered from userspace. Pass it on. */ - ptrace (PTRACE_SYSCALL, pid, 0, SIGTRAP); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, SIGTRAP); else - ptrace (PTRACE_SYSCALL, pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, 0); return -1; } @@ -1644,8 +2024,16 @@ exec_waitpid (pid_t pid, int *wstatus, int options) /* These events are handled by tracing SIGSTOP signals sent to unknown tracees. Make sure not to pass through status, as there's no signal really being delivered. */ - ptrace (PTRACE_SYSCALL, pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), pid, 0, 0); + return -1; + +#ifdef HAVE_SECCOMP + case SIGTRAP | (PTRACE_EVENT_SECCOMP << 8): + /* Intercept and process this system call if the event was + produced by our filter. */ + seccomp_system_call (tracee); return -1; +#endif /* HAVE_SECCOMP */ #ifdef SIGSYS case SIGSYS: @@ -1657,17 +2045,20 @@ exec_waitpid (pid_t pid, int *wstatus, int options) it. */ #ifdef HAVE_SIGINFO_T_SI_SYSCALL #ifndef __arm__ - ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP - && siginfo.si_syscall == -1) - ? 0 : status)); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, ((siginfo.si_code == SYS_SECCOMP + && siginfo.si_syscall == -1) + ? 0 : status)); #else /* __arm__ */ - ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP - && siginfo.si_syscall == 222) - ? 0 : status)); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), + pid, 0, ((siginfo.si_code == SYS_SECCOMP + && siginfo.si_syscall == 222) + ? 0 : status)); #endif /* !__arm__ */ #else /* !HAVE_SIGINFO_T_SI_SYSCALL */ /* Drop this signal, since what caused it is unknown. */ - ptrace (PTRACE_SYSCALL, pid, 0, 0); + ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), pid, + 0, 0); #endif /* HAVE_SIGINFO_T_SI_SYSCALL */ return -1; #endif /* SIGSYS */ @@ -1698,5 +2089,49 @@ exec_waitpid (pid_t pid, int *wstatus, int options) void exec_init (const char *loader) { +#ifdef HAVE_SECCOMP + struct utsname u; + int major, minor; +#endif /* HAVE_SECCOMP */ + loader_name = loader; +#ifdef HAVE_SECCOMP + errno = 0; + prctl (PR_GET_SECCOMP); + + /* PR_GET_SECCOMP should not set errno if the kernel was configured + with support for seccomp. */ + if (!errno) + use_seccomp_p = true; + else + return; + + /* Establish whether the kernel is 4.7.x or older. */ + uname (&u); + if ((sscanf (u.release, "%d.%d", &major, &minor) == 2)) + { + /* Certain required ptrace features were introduced in kernel + 3.5. */ + if (major < 3 || (major == 3 && minor < 5)) + use_seccomp_p = false; + else + { + if (major < 4 || (major == 4 && minor <= 7)) + { +#ifndef __ANDROID__ + kernel_4_7_or_earlier = true; +#else /* __ANDROID __ */ + /* Certain Android kernels have received backports of + those new PTRACE_EVENT_SECCOMP semantics which were + introduced in kernel version 4.8, so that it is + necessary to actively establish which variant is in + place. This being much too involved for code I cannot + test, simply disable seccomp on kernel releases subject + to these uncertainties. */ + use_seccomp_p = false; +#endif /* !__ANDROID__ */ + } + } + } +#endif /* HAVE_SECCOMP */ } commit 1647494c04a57586c9616603b3ae803c6dd48d30 Author: Mattias Engdegård Date: Mon Jul 1 10:43:12 2024 +0200 ; * etc/NEWS: Clarify. diff --git a/etc/NEWS b/etc/NEWS index d0534ad7538..6428ef651aa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2726,8 +2726,8 @@ some obvious cases. Examples: (aset "abc" 1 ?d) Such code may have unpredictable behavior because the constants are part -of the program, not of the data structures generated afresh during -execution, and the compiler does not expect them to change. +of the program and are not data structures generated afresh during +execution; the compiler does not expect them to change. To avoid the warning, operate on an object created by the program (maybe a copy of the constant), or use a non-destructive operation commit b2c966f83963f1b4497896b81d3c51479f791e67 Author: Yuan Fu Date: Sun Jun 30 22:36:11 2024 -0700 ; * src/treesit.c (Ftreesit_query_capture): Fix typo. diff --git a/src/treesit.c b/src/treesit.c index f0c786e921d..a0e41add475 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -2942,7 +2942,7 @@ the query. */) /* As of right now, the node returned by treesit_resolve_node always passes treesit_check_node; but it might not be true in the future, so adding the line below just to be safe. */ - treesit_check_node (node); + treesit_check_node (lisp_node); /* Extract C values from Lisp objects. */ TSNode treesit_node = XTS_NODE (lisp_node)->node; commit ae3857942069d9d9a17976387eee383d10c1ce31 Author: Po Lu Date: Mon Jul 1 09:31:34 2024 +0800 * java/res/mipmap-v26/emacs_icon.xml: Define monospace icon. diff --git a/java/res/mipmap-v26/emacs_icon.xml b/java/res/mipmap-v26/emacs_icon.xml index f0a8df92846..5b720e8210f 100644 --- a/java/res/mipmap-v26/emacs_icon.xml +++ b/java/res/mipmap-v26/emacs_icon.xml @@ -20,4 +20,5 @@ + commit b2d99c0d0aaab4d0c7026a26393e22d66246a349 Author: Stefan Kangas Date: Mon Jul 1 02:33:05 2024 +0200 Improve `sentence-end-double-space` docstring * lisp/textmodes/paragraphs.el (sentence-end-double-space): Improve and expand docstring. diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index af99a96e045..be741e6517b 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -118,8 +118,28 @@ text indented by a margin setting." (defcustom sentence-end-double-space t "Non-nil means a single space does not end a sentence. -This is relevant for filling. See also `sentence-end-without-period' -and `colon-double-space'. +This user option affects fill commands and sentence commands. + +If this variable is non-nil, Emacs considers a period followed by two +spaces or by a newline as the end of a sentence. This means that: + + 1. The fill commands will not break a line after a period followed + by just one space. + + 2. The sentence commands stop only for double spaces. + +If this variable is nil, Emacs considers a period followed by one space +or by a newline as the end of a sentence. This means that: + + 1. The fill commands will break a line after a period followed by + one space, and put just one space after each period. + + 2. The sentence commands stop for single spaces. + +For more details, see Info node `(emacs) Fill Commands' and Info +node `(emacs) Sentences'. + +See also `sentence-end-without-period' and `colon-double-space'. This value is used by the function `sentence-end' to construct the regexp describing the end of a sentence, when the value of the variable commit 9d62dbc1f798f65d480c6b8e6255a33e124995d0 Author: Stefan Kangas Date: Mon Jul 1 01:44:38 2024 +0200 Backport file backup FAQ item to Emacs <28 * doc/misc/efaq.texi (Not writing files to the current directory): Backport recommendation to Emacs 27 or older. Problem reported by David Hedlund . diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index 7ab9731ff8f..93b3d48f6f1 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -2932,8 +2932,9 @@ For instance, to write all these things to @file{~/.emacs.d/aux/}: @lisp -(setq lock-file-name-transforms - '(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t))) +(when (>= emacs-major-version 28) + (setq lock-file-name-transforms + '(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t)))) (setq auto-save-file-name-transforms '(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t))) (setq backup-directory-alist commit 2f71460d52fb8ec36766edc297de559b318ee5e1 Author: Eli Zaretskii Date: Sun Jun 30 22:25:31 2024 +0300 More updates of documentation for Emacs 30 * etc/NEWS: Improve wording and move/mark entries. * doc/lispref/positions.texi (List Motion): Document 'forward-sentence-function'. * doc/lispref/functions.texi (What Is a Function): Document 'primitive-function-p' and 'cl-functionp'. * doc/emacs/misc.texi (Saving Emacs Sessions): Improve wording and indexing. * doc/lispref/tips.texi (Documentation Tips): Adapt to the new value of 'emacs-lisp-docstring-fill-column'. * doc/emacs/fixit.texi (Spelling): Document 'flyspell-check-changes'. diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi index f3c876cf3f7..af9ca5fcdf6 100644 --- a/doc/emacs/fixit.texi +++ b/doc/emacs/fixit.texi @@ -473,6 +473,13 @@ it will slow down cursor motion and scrolling commands. It also doesn't automatically check the text you didn't type or move across; use @code{flyspell-region} or @code{flyspell-buffer} for that. +@vindex flyspell-check-changes + Normally, Flyspell mode highlights misspelled words that you typed or +modified, but also words you move across without changing them. But if +you customize the variable @code{flyspell-check-changes} to a +non-@code{nil} value, Flyspell mode will check only the words you typed +or edited in some way. + @findex flyspell-correct-word @findex flyspell-auto-correct-word @findex flyspell-correct-word-before-point diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 13d86a32e79..d1e8217f579 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2849,13 +2849,14 @@ frame parameters you don't want to be restored; they will then be set according to your customizations in the init file. @vindex desktop-files-not-to-save -@vindex remote-file-name-access-timeout +@vindex remote-file-name-access-timeout@r{, and desktop restoring} Information about buffers visiting remote files is not saved by default. Customize the variable @code{desktop-files-not-to-save} to change this. In this case, you might also consider customizing @code{remote-file-name-access-timeout}, which is the number of seconds after which buffer restoration of a remote file is -stopped. This prevents Emacs being blocked. +stopped. This prevents Emacs from being blocked when restoring sessions +that visited remote files. @vindex desktop-restore-eager By default, all the buffers in the desktop are restored in one go. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index dcce4043064..695e1c3efb5 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -186,8 +186,8 @@ their code. @end defun @noindent -Unlike @code{functionp}, the next three functions do @emph{not} treat -a symbol as its function definition. +Unlike @code{functionp}, the next functions do @emph{not} treat a symbol +as its function definition. @defun subrp object This function returns @code{t} if @var{object} is a built-in function @@ -243,6 +243,20 @@ without symbol indirection. It signals an error for non-built-in functions. We recommend to use @code{func-arity} instead. @end defun +@defun cl-functionp object +This function is like @code{functionp}, except it returns @code{nil} for +lists and symbols. +@end defun + +@findex subr-primitive-p +@defun primitive-function-p object +This function returns @code{t} if @var{object} is a built-in primitive +written in C (@pxref{Primitive Function Type}). Note that special forms +are explicitly excluded, as they are not functions. Use +@code{subr-primitive-p} if you need to recognize special forms as well. +@end defun + + @node Lambda Expressions @section Lambda Expressions @cindex lambda expression diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 9193c1063d1..ead7833af61 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -875,14 +875,21 @@ nested defuns. @findex treesit-forward-sentence @findex forward-sentence @findex backward-sentence -If Emacs is compiled with tree-sitter, it can use the tree-sitter -parser information to move across syntax constructs. Since what -exactly is considered a sentence varies between languages, a major -mode should set @code{treesit-thing-settings} to determine that. -Then the mode can get navigation-by-sentence functionality for free, -by using @code{forward-sentence} and -@code{backward-sentence}(@pxref{Moving by Sentences,,, emacs, The -extensible self-documenting text editor}). +@vindex forward-sentence-function +@cindex sentence, in program source files +The function that is the value of the variable +@code{forward-sentence-function} determines how to move across syntax +constructs known as @dfn{sentences}. Major modes can assign their own +functions to this variable to customize the behavior of +@code{forward-sentence} command. If Emacs is compiled with tree-sitter, +it can use the tree-sitter parser information to move across syntax +constructs. Since what exactly is considered a sentence varies between +languages, a major mode should set @code{treesit-thing-settings} to +determine that. Then @code{forward-sentence-function} will be set to +@code{treesit-forward-sentence}, and the mode will get +navigation-by-sentence functionality for free, by using +@code{forward-sentence} and @code{backward-sentence}(@pxref{Moving by +Sentences,,, emacs, The extensible self-documenting text editor}). @findex treesit-forward-sexp @findex forward-sexp@r{, and tree-sitter} diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index 1e35b82e413..802fa0febed 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -611,7 +611,7 @@ little space in a running Emacs. @item Format the documentation string so that it fits in an Emacs window on an 80-column screen. It is a good idea for most lines to be no wider than -60 characters. The first line should not be wider than 67 characters +60 characters. The first line should not be wider than 74 characters, or it will look bad in the output of @code{apropos}. @vindex emacs-lisp-docstring-fill-column diff --git a/etc/NEWS b/etc/NEWS index 28bfe38b84b..d0534ad7538 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -744,6 +744,8 @@ bind 'M-TAB' to 'ispell-complete-word' as it did in previous Emacs versions, or disable Ispell word completion in Text mode altogether, by customizing the new user option 'text-mode-ispell-word-completion'. +** Internationalization + --- ** Mode-line mnemonics for some coding-systems have changed. The mode-line mnemonic for 'utf-7' is now the lowercase 'u', to be @@ -760,7 +762,14 @@ previous behavior of showing 'U' in the mode line for 'koi8-u': (coding-system-put 'koi8-u :mnemonic ?U) -** Internationalization +--- +** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'. +VSCII-1 and TCVN-5712 are different names for the same character +encoding. Therefore, the duplicate coding system definition has been +dropped in favor of an alias. + +The mode-line mnemonic for 'vietnamese-vscii' and its aliases is the +lowercase letter 'v'. --- *** Users in CJK locales can control width of some non-CJK characters. @@ -1593,10 +1602,12 @@ mouse to consult an error message. ** Flyspell ++++ *** New user option 'flyspell-check-changes'. When non-nil, Flyspell mode spell-checks only words that you edited; it does not check unedited words just because you move point across them. +--- ** JS mode. The binding 'M-.' has been removed from the major mode keymaps in 'js-mode' and 'js-ts-mode', having it default to the global binding @@ -1604,6 +1615,7 @@ which calls 'xref-find-definitions'. If the previous one worked better for you, use 'define-key' in your init script to bind 'js-find-symbol' to that combination again. +--- ** Json mode. 'js-json-mode' does not derive from 'js-mode' any more so as not to confuse tools like Eglot or YASnippet into thinking that those @@ -1627,19 +1639,16 @@ instead of: and another_expression): do_something() +--- *** New user option 'python-interpreter-args'. This allows the user to specify command line arguments to the non interactive Python interpreter specified by 'python-interpreter'. +--- *** New function 'python-shell-send-block'. It sends the python block delimited by 'python-nav-beginning-of-block' and 'python-nav-end-of-block' to the inferior Python process. -*** 'eldoc' no longer truncates to a single line by default. -Previously, the entire docstring was not available to eldoc, which made -'eldoc-echo-area-use-multiline-p' ineffective. The old behavior may be -kept by customizing 'eldoc-echo-area-use-multiline-p'. - ** Inferior Python mode --- @@ -1648,6 +1657,15 @@ Support for Python's ExceptionGroup has been added, so in the Python shell, the line indicating the source of error in the error messages from ExceptionGroup will be recognized as well. +** Eldoc + +--- +*** 'eldoc' no longer truncates to a single line by default. +Previously, the entire docstring was not available to eldoc, which made +'eldoc-echo-area-use-multiline-p' ineffective. The old behavior may be +kept by customizing 'eldoc-echo-area-use-multiline-p'. + +--- ** Scheme mode Scheme mode now handles regular expression literal '#/regexp/' that is available in some Scheme implementations. @@ -1711,7 +1729,7 @@ provide dictionary-based minibuffer completion for word selection. *** New user option 'dictionary-read-word-prompt'. This allows the user to customize the prompt that is used by 'dictionary-search' when asking for a word to search in the -dictionary. +dictionaries. --- *** New user option 'dictionary-display-definition-function'. @@ -1750,13 +1768,19 @@ the mode was turned on. ** Pp ++++ *** New 'pp-default-function' user option replaces 'pp-use-max-width'. +Its default value is 'pp-fill', a new default pretty-printing function, +which tries to obey 'fill-column'. -*** New default pretty printing function, which tries to obey 'fill-column'. - +--- *** 'pp-to-string' takes an additional PP-FUNCTION argument. This argument specifies the prettifying algorithm to use. +--- +*** 'pp' and 'pp-to-string' now always include a terminating newline. +In the past they included a terminating newline in most cases but not all. + ** Emacs Lisp mode --- @@ -1765,7 +1789,7 @@ Previously, the '@' character, which normally has 'symbol' syntax, would combine with a following Lisp symbol and interfere with symbol searching. ---- ++++ *** 'emacs-lisp-docstring-fill-column' now defaults to 72. It was previously 65. The new default formats documentation strings to fit on fewer lines without negatively impacting readability. @@ -1777,10 +1801,12 @@ fit on fewer lines without negatively impacting readability. CPerl mode fontifies subroutine signatures like variable declarations which makes them visually distinct from subroutine prototypes. +--- *** Syntax of Perl up to version 5.40 is supported. CPerl mode supports the new keywords for exception handling and the object oriented syntax which were added in Perl 5.36, 5.38 and 5.40. +--- *** New user option 'cperl-fontify-trailer'. This user option takes the values 'perl-code' or 'comment' and treats text after an "__END__" or "__DATA__" token accordingly. The default @@ -1788,21 +1814,25 @@ value of 'perl-code' is useful for trailing POD and for AutoSplit modules, the value 'comment' makes CPerl mode treat trailers as comment, like Perl mode does. +--- *** New command 'cperl-file-style'. This command sets the indentation style for the current buffer. To change the default style, either use the user option with the same name or use the command 'cperl-set-style'. -*** New minor mode cperl-extra-paired-delimiters-mode +--- +*** New minor mode 'cperl-extra-paired-delimiters-mode'. Perl 5.36 and newer allows using more than 200 non-ASCII paired delimiters for quote-like constructs, eg. "q«text»". Use this minor mode in buffers where this feature is activated. -*** Commands using the Perl info page are obsolete. -The Perl documentation in info format is no longer distributed with +--- +*** Commands using the Perl Info manual are obsolete. +The Perl documentation in Info format is no longer distributed with Perl or on CPAN since more than 10 years. Perl documentation can be read with 'cperl-perldoc' instead. +--- *** Highlighting trailing whitespace has been removed. The user option 'cperl-invalid-face' is now obsolete, and does nothing. See the user option 'show-trailing-whitespace' instead. @@ -1828,8 +1858,9 @@ of the accessibility of remote files can now time out if ** Image Dired ++++ *** New user option 'image-dired-thumb-naming'. -You can now configure how a thumbnail is named using this option. +You can now configure how thumbnails are named using this option. ** ERT @@ -1874,10 +1905,10 @@ macros with many lines, such as from 'kmacro-edit-lossage'. Fractions of the form "123⁄456" are handled as if written "123:456". Note in particular the difference in behavior from U+2215 DIVISION SLASH and U+002F SOLIDUS, which result in division rather than a rational -fraction. You may also be interested to know that precomposed fraction -characters, such as ½ (U+00BD VULGAR FRACTION ONE HALF), are also -recognized as rational fractions. They have been since 2004, but it -looks like it was never mentioned in the NEWS, or even the manual. +fraction. In addition, precomposed fraction characters, such as ½ +(U+00BD VULGAR FRACTION ONE HALF), are also recognized as rational +fractions. (They have been recognized since 2004, but it looks like it +was never mentioned in the NEWS, or even the Calc manual.) ** IELM @@ -1904,12 +1935,14 @@ labels of unselected active radio-button or checkbox widgets from the labels of unselected inactive widgets (the default value inherits from the 'widget-inactive' face). ++++ *** New user option 'widget-skip-inactive'. If non-nil, moving point forward or backward between widgets by typing 'TAB' or 'S-TAB' skips over inactive widgets. The default value is nil. ** Ruby mode +--- *** New user option 'ruby-rubocop-use-bundler'. By default it retains the previous behavior: read the contents of Gemfile and act accordingly. But you can also set it to t or nil to @@ -1927,8 +1960,8 @@ of 'bounds-of-thing-at-point' and 'forward-thing', respectively. *** New helper functions for text property-based thingatpt providers. The new helper functions 'thing-at-point-for-char-property', 'bounds-of-thing-at-point-for-char-property', and -'forward-thing-for-char-property' can help to help implement custom -thingatpt providers for "things" that are defined by a text property. +'forward-thing-for-char-property' can help to implement custom thingatpt +providers for "things" that are defined by text properties. --- *** 'bug-reference-mode' now supports 'thing-at-point'. @@ -1957,7 +1990,7 @@ in Buffer Menu mode. --- *** 'ffap-lax-url' now defaults to nil. -Previously, it was set to t but this broke remote file name detection. +Previously, it was set to t, but this broke remote file name detection. --- *** More control on automatic update of Proced buffers. @@ -1976,6 +2009,7 @@ The following new XML schemas are now supported: - Nuget package specification file - Nuget packages config file +--- *** color.el now supports the Oklab color representation. +++ @@ -1989,9 +2023,9 @@ This allows disabling JavaScript in xwidget Webkit sessions. options of GNU 'ls'. --- -*** 'M-x ping' can now give "ping" additional flags. +*** 'M-x ping' can now give additional flags to the 'ping' program. Typing 'C-u M-x ping' prompts first for the host, and then for the flags -to give to "ping". +to give to the 'ping' command. --- *** Webjump now assumes URIs are HTTPS instead of HTTP. @@ -2004,11 +2038,13 @@ URIs are now prefixed with "https://" instead. Most of the variables and functions in the file have been renamed to make sure they all use a 'tit-' namespace prefix. +--- *** 'xref-revert-buffer' is now an alias of 'revert-buffer'. The Xref buffer now sets up 'revert-buffer-function' such that 'revert-buffer' behaves like 'xref-revert-buffer' did in previous Emacs versions, and the latter is now an alias of the former. +--- *** The Makefile browser is now obsolete. The command 'makefile-switch-to-browser' command is now obsolete, together with related commands used in the "*Macros and Targets*" @@ -2040,6 +2076,7 @@ A major mode based on the tree-sitter library for editing Lua files. *** New major mode 'php-ts-mode'. A major mode based on the tree-sitter library for editing PHP files. ++++ ** New package EditorConfig. This package provides support for the EditorConfig standard, an editor-neutral way to provide directory local (project-wide) settings. @@ -2080,7 +2117,7 @@ global minor mode 'global-window-tool-bar-mode' enables this minor mode in all buffers. +++ -** New package Track-Changes. +** New library Track-Changes. This library is a layer of abstraction above 'before-change-functions' and 'after-change-functions' which provides a superset of the functionality of 'after-change-functions': @@ -2095,7 +2132,7 @@ the functionality of 'after-change-functions': ** New global minor mode 'minibuffer-regexp-mode'. This is a minor mode for editing regular expressions in the minibuffer, for example in 'query-replace-regexp'. It correctly highlights parens -via ‘show-paren-mode’ and ‘blink-matching-paren’ in a user-friendly way, +via 'show-paren-mode' and 'blink-matching-paren' in a user-friendly way, avoids reporting alleged paren mismatches and makes sexp navigation more intuitive. @@ -2112,13 +2149,14 @@ The Info manual "(modus-themes) Top" describes the details and showcases all their customization options. +++ -** New package PEG. +** New library PEG. Emacs now includes a library for writing Parsing Expression Grammars (PEG), an approach to text parsing that provides more structure than regular expressions, but less complexity than context-free grammars. The Info manual "(elisp) Parsing Expression Grammars" has documentation and examples. +--- ** New major mode 'shell-command-mode'. This mode is used by default for the output of asynchronous 'shell-command'. To revert to the previous behavior, set the (also new) variable @@ -2170,9 +2208,7 @@ whose major modes fail to use 'run-mode-hooks'. Major modes defined with 'define-derived-mode' are not affected. 'run-mode-hooks' has been the recommended way to run major mode hooks since Emacs 22. -** 'pp' and 'pp-to-string' now always include a terminating newline. -In the past they included a terminating newline in most cases but not all. - ++++ ** 'buffer-match-p' and 'match-buffers' take '&rest args'. They used to take a single '&optional arg' and were documented to use an unreliable hack to try and support condition predicates that @@ -2180,10 +2216,11 @@ don't accept this optional arg. The new semantics makes no such accommodation, but the code still supports it (with a warning) for backward compatibility. +--- ** 'post-gc-hook' runs after updating 'gcs-done' and 'gcs-elapsed'. --- -** Connection-local variables are applied in buffers visiting a remote file. +** Connection-local variables are applied in buffers visiting remote files. This overrides possible directory-local or file-local variables with the same name. @@ -2198,15 +2235,6 @@ assertion only (which is useless). For historical compatibility, an operator character following '^' or '\`' becomes literal, but we advise against relying on this. ---- -** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'. -VSCII-1 and TCVN-5712 are different names for the same character -encoding. Therefore, the duplicate coding system definition has been -dropped in favor of an alias. - -The mode-line mnemonic for 'vietnamese-vscii' and its aliases is the -lowercase letter 'v'. - +++ ** Infinities and NaNs no longer act as symbols on non-IEEE platforms. On old platforms like the VAX that do not support IEEE floating-point, @@ -2246,6 +2274,7 @@ The compatibility aliases 'x-defined-colors', 'x-color-defined-p', ** 'easy-mmode-define-{minor,global}-mode' aliases are now obsolete. Use 'define-minor-mode' and 'define-globalized-minor-mode' instead. ++++ ** The 'millisec' argument of 'sleep-for' is now obsolete. Use a float value for the first argument instead. @@ -2264,9 +2293,19 @@ values. This user option has been obsoleted in Emacs 27, use 'remote-file-name-inhibit-cache' instead. ++++ ** The obsolete calling convention of 'sit-for' has been removed. That convention was: '(sit-for SECONDS MILLISEC &optional NODISP)'. +--- +** 'defadvice' is marked as obsolete. +See the "(elisp) Porting Old Advice" Info node for help converting +them to use 'advice-add' or 'define-advice' instead. + +--- +** 'cl-old-struct-compat-mode' is marked as obsolete. +You may need to recompile your code if it was compiled with Emacs < 24.3. + --- ** Old derived.el functions removed. The following functions have been deleted because they were only used @@ -2287,6 +2326,7 @@ to specify the 'mouse-4/5/6/7' events that might still happen to be generated by some old packages (or if 'mouse-wheel-buttons' has been set to nil). +--- ** Xterm Mouse mode now emits 'wheel-up/down/right/left' events. This is instead of 'mouse-4/5/6/7' events for the mouse wheel. It uses the new variable 'mouse-wheel-buttons' to decide which button maps to @@ -2312,6 +2352,7 @@ compilation, by customizing this user option. It is also possible to control this at function granularity by using the new 'safety' parameter in the function's 'declare' form. ++++ ** New types 'closure' and 'interpreted-function'. 'interpreted-function' is the new type used for interpreted functions, and 'closure' is the common parent type of 'interpreted-function' @@ -2321,6 +2362,7 @@ Those new types come with the associated new predicates 'closurep' and 'interpreted-function-p' as well as a new constructor 'make-interpreted-closure'. +--- ** New function 'help-fns-function-name'. For named functions, it just returns the name and otherwise it returns a short "unique" string that identifies the function. @@ -2332,22 +2374,26 @@ further details. This is a convenience function to return the Unicode name of a char (if it has one). ++++ ** New function 'cl-type-of'. This function is like 'type-of' except that it sometimes returns a more precise type. For example, for nil and t it returns 'null' and 'boolean' respectively, instead of just 'symbol'. ++++ ** New functions 'primitive-function-p' and 'cl-functionp'. 'primitive-function-p' is like 'subr-primitive-p' except that it returns t only if the argument is a function rather than a special-form, and 'cl-functionp' is like 'functionp' except it returns nil for lists and symbols. +--- ** Built-in types now have corresponding classes. At the Lisp level, this means that things like '(cl-find-class 'integer)' will now return a class object, and at the UI level it means that things like 'C-h o integer RET' will show some information about that type. +--- ** New variable 'major-mode-remap-defaults' and function 'major-mode-remap'. The first is like Emacs-29's 'major-mode-remap-alist' but to be set by packages (instead of users). The second looks up those two variables. @@ -2392,6 +2438,7 @@ more details. This has the same effect as the variable of the same name and takes precedence over the variable when present. +--- ** New function 'merge-ordered-lists'. Mostly used internally to do a kind of topological sort of inheritance hierarchies. @@ -2469,6 +2516,7 @@ without specifying a file, like this: (notifications-notify :title "I am playing music" :app-icon 'multimedia-player) +--- ** New function 're-disassemble' to see the innards of a regexp. If you built Emacs with '--enable-checking', you can use this to help debug either your regexp performance problems or the regexp engine. @@ -2480,13 +2528,6 @@ characters in length, provided that the LONG_XLFDs argument is true. Other features in Emacs which employ XLFDs have been modified to produce and understand XLFDs larger than 255 characters. -** 'defadvice' is marked as obsolete. -See the "(elisp) Porting Old Advice" Info node for help converting -them to use 'advice-add' or 'define-advice' instead. - -** 'cl-old-struct-compat-mode' is marked as obsolete. -You may need to recompile code if it was compiled with Emacs < 24.3. - +++ ** New macro 'static-if' for conditional evaluation of code. This macro hides a form from the evaluator or byte-compiler based on a @@ -2536,98 +2577,24 @@ as a single word. This is useful for programming languages and styles where only the first letter of a symbol's name is ever capitalized. The default value of this variable is nil. -** Touch Screen support - -+++ -*** 'x-popup-menu' now understands touch screen events. -When a 'touchscreen-begin' or 'touchscreen-end' event is passed as the -POSITION argument, it will behave as if that event was a mouse event. - -+++ -*** New functions for handling touch screen events. -The new functions 'touch-screen-track-tap' and -'touch-screen-track-drag' handle tracking common touch screen gestures -from within a command. - -+++ -*** New parameter to 'touchscreen-end' events. -CANCEL non-nil establishes that the touch sequence has been -intercepted by programs such as window managers and should be ignored -with Emacs. - -** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill. - -+++ -** New variable 'secondary-tool-bar-map'. -If non-nil, this variable contains a keymap of menu items that are -displayed along tool bar items inside 'tool-bar-map'. - -** New variable 'completion-lazy-hilit'. -Lisp programs that present completion candidates may bind this -variable non-nil around calls to functions such as -'completion-all-completions'. This tells the underlying completion -styles to skip eager fontification of completion candidates, which -improves performance. Such a Lisp program can then use the -'completion-lazy-hilit' function to fontify candidates just in time. - -** New primitive 'buffer-last-name'. -It returns the name of a buffer before the last time it was renamed or -killed. - -** New primitive 'marker-last-position'. -It returns the last position of a marker in its buffer even if that -buffer has been killed. ('marker-position' would return nil in that -case.) - -** Functions and variables to transpose sexps - -+++ -*** New helper variable 'transpose-sexps-function'. -Emacs now can set this variable to customize the behavior of the -'transpose-sexps' function. - -+++ -*** New function 'transpose-sexps-default-function'. -The previous implementation is moved into its own function, to be -bound by 'transpose-sexps-function'. - -*** New function 'treesit-transpose-sexps'. -Tree-sitter now unconditionally sets 'transpose-sexps-function' for all -tree-sitter enabled modes. This functionality utilizes the new -'transpose-sexps-function'. - -** Functions and variables to move by program statements - -*** New variable 'forward-sentence-function'. -Major modes can now set this variable to customize the behavior of the -'forward-sentence' command. - -*** New function 'forward-sentence-default-function'. -The previous implementation of 'forward-sentence' is moved into its -own function, to be bound by 'forward-sentence-function'. - -*** New function 'treesit-forward-sentence'. -All tree-sitter enabled modes that define 'sentence' in -'treesit-thing-settings' now set 'forward-sentence-function' to call -'treesit-forward-sentence'. - -** Functions and variables to move by program sexps - -*** New function 'treesit-forward-sexp'. -Tree-sitter conditionally sets 'forward-sexp-function' for major modes -that have defined 'sexp' in 'treesit-thing-settings' to enable -sexp-related motion commands. +--- +** Bytecode is now always loaded eagerly. +Bytecode compiled with older Emacs versions for lazy loading using +'byte-compile-dynamic' is now loaded all at once. +As a consequence, 'fetch-bytecode' has no use, does nothing, and is +now obsolete. The variable 'byte-compile-dynamic' has no effect any +more; compilation will always yield bytecode for eager loading. +++ -** Returned strings are never docstrings. +** Returned strings from functions and macros are never docstrings. Functions and macros whose bodies consist of a single string literal now -only return that string; it is not used as a docstring. Example: +only return that string, and will not use it as a docstring. Example: (defun sing-a-song () "Sing a song.") -The above function returns the string '"Sing a song."' but has no -docstring. Previously, that string was used as both a docstring and +The above function returns the string '"Sing a song."' and has no doc +string. Previously, that string was used as both the doc string and return value, which was never what the programmer wanted. If you want the string to be a docstring, add an explicit return value. @@ -2743,8 +2710,8 @@ default (unconditional) clause. Example: (t (say "some")) (say "goodbye")) -Such a clause will never be executed but is likely to be a mistake, -perhaps due to misplaced brackets. +Such a clause will never be executed, and is likely to be a mistake, +perhaps due to misplaced parens. This warning can be suppressed using 'with-suppressed-warnings' with the warning name 'suspicious'. @@ -2758,8 +2725,8 @@ some obvious cases. Examples: (aset [3 4] 0 8) (aset "abc" 1 ?d) -Such code may have unpredictable behavior because the constants are -part of the program, not data structures generated afresh during +Such code may have unpredictable behavior because the constants are part +of the program, not of the data structures generated afresh during execution, and the compiler does not expect them to change. To avoid the warning, operate on an object created by the program @@ -2806,6 +2773,112 @@ The warning name is 'docstrings-control-chars'. *** The warning about wide docstrings can now be disabled separately. Its warning name is 'docstrings-wide'. ++++ +** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases. +Previously, 'fset', 'defalias' and 'defvaralias' could be made to +build circular function and variable indirection chains as in + + (defalias 'able 'baker) + (defalias 'baker 'able) + +but trying to use them would sometimes make Emacs hang. Now, an attempt +to create such a loop results in an error. + +Since circular alias chains now cannot occur, 'function-alias-p', +'indirect-function' and 'indirect-variable' will never signal an error. +Their 'noerror' arguments have no effect and are therefore obsolete. + +** Touch Screen support + ++++ +*** 'x-popup-menu' now understands touch screen events. +When a 'touchscreen-begin' or 'touchscreen-end' event is passed as the +POSITION argument, it will behave as if that event was a mouse event. + ++++ +*** New functions for handling touch screen events. +The new functions 'touch-screen-track-tap' and 'touch-screen-track-drag' +handle tracking common touch screen gestures from within a command. + ++++ +*** New parameter to 'touchscreen-end' events. +CANCEL non-nil establishes that the touch sequence has been intercepted +by programs such as window managers and should be ignored with Emacs. + +--- +** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill. + ++++ +** New variable 'secondary-tool-bar-map'. +If non-nil, this variable contains a keymap of menu items that are +displayed along tool bar items defined by 'tool-bar-map'. These items +are displayed below the tool bar if the value of 'tool-bar-position' is +'top', and above it if the value is 'bottom'. This is used by +'modifier-bar-mode'. + +--- +** New variable 'completion-lazy-hilit'. +Lisp programs that present completion candidates may bind this +variable non-nil around calls to functions such as +'completion-all-completions'. This tells the underlying completion +styles to skip eager fontification of completion candidates, which +improves performance. Such a Lisp program can then use the +'completion-lazy-hilit' function to fontify candidates just in time. + ++++ +** New primitive 'buffer-last-name'. +It returns the name of a buffer before the last time it was renamed or +killed. + ++++ +** New primitive 'marker-last-position'. +It returns the last position of a marker in its buffer even if that +buffer has been killed. ('marker-position' would return nil in that +case.) + +** Functions and variables to transpose sexps + +--- +*** New helper variable 'transpose-sexps-function'. +Lisp programs can now set this variable to customize the behavior of the +'transpose-sexps' command. + +--- +*** New function 'transpose-sexps-default-function'. +The previous implementation of 'transpose-sexps' was moved into its own +function, to be used in 'transpose-sexps-function'. + +--- +*** New function 'treesit-transpose-sexps'. +Tree-sitter now unconditionally sets 'transpose-sexps-function' for all +tree-sitter enabled modes to this function. + +** Functions and variables to move by program statements + ++++ +*** New variable 'forward-sentence-function'. +Major modes can now set this variable to customize the behavior of the +'forward-sentence' command. + +--- +*** New function 'forward-sentence-default-function'. +The previous implementation of 'forward-sentence' is moved into its +own function, to be bound by 'forward-sentence-function'. + ++++ +*** New function 'treesit-forward-sentence'. +All tree-sitter enabled modes that define 'sentence' in +'treesit-thing-settings' now set 'forward-sentence-function' to call +'treesit-forward-sentence'. + +** Functions and variables to move by program sexps + ++++ +*** New function 'treesit-forward-sexp'. +Tree-sitter conditionally sets 'forward-sexp-function' for major modes +that have defined 'sexp' in 'treesit-thing-settings' to enable +sexp-related motion commands. + --- ** New user option 'native-comp-async-warnings-errors-kind'. It allows control of what kinds of warnings and errors from asynchronous @@ -2839,34 +2912,12 @@ The declaration '(important-return-value t)' sets the 'important-return-value' property which indicates that the function return value should probably not be thrown away implicitly. -** Bytecode is now always loaded eagerly. -Bytecode compiled with older Emacs versions for lazy loading using -'byte-compile-dynamic' is now loaded all at once. -As a consequence, 'fetch-bytecode' has no use, does nothing, and is -now obsolete. The variable 'byte-compile-dynamic' has no effect any -more; compilation will always yield bytecode for eager loading. - +++ ** New functions 'file-user-uid' and 'file-group-gid'. These functions are like 'user-uid' and 'group-gid', respectively, but are aware of file name handlers, so they will return the remote UID or GID for remote files (or -1 if the connection has no associated user). -+++ -** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases. -Previously, 'fset', 'defalias' and 'defvaralias' could be made to -build circular function and variable indirection chains as in - - (defalias 'able 'baker) - (defalias 'baker 'able) - -but trying to use them would sometimes make Emacs hang. Now, an attempt -to create such a loop results in an error. - -Since circular alias chains now cannot occur, 'function-alias-p', -'indirect-function' and 'indirect-variable' will never signal an error. -Their 'noerror' arguments have no effect and are therefore obsolete. - +++ ** 'treesit-font-lock-rules' now accepts additional global keywords. When supplied with ':default-language LANGUAGE', rules after it will commit a9df581c40392170af79258d9fd8f1cec4f479da Author: Mattias Engdegård Date: Sun Jun 30 17:11:55 2024 +0200 ; * etc/NEWS: Copy-edit. diff --git a/etc/NEWS b/etc/NEWS index 7cc1949af2d..28bfe38b84b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2343,7 +2343,7 @@ t only if the argument is a function rather than a special-form, and 'cl-functionp' is like 'functionp' except it returns nil for lists and symbols. -** Built-in types have now corresponding classes. +** Built-in types now have corresponding classes. At the Lisp level, this means that things like '(cl-find-class 'integer)' will now return a class object, and at the UI level it means that things like 'C-h o integer RET' will show some information about that type. @@ -2485,7 +2485,7 @@ See the "(elisp) Porting Old Advice" Info node for help converting them to use 'advice-add' or 'define-advice' instead. ** 'cl-old-struct-compat-mode' is marked as obsolete. -You may need to recompile our code if it was compiled with Emacs < 24.3. +You may need to recompile code if it was compiled with Emacs < 24.3. +++ ** New macro 'static-if' for conditional evaluation of code. @@ -2982,7 +2982,7 @@ this was not possible.) In addition, LOCATION can be an integer, a (BEFORE is ignored in this case). +++ -**** New function 'sqlite-execute-batch'. +** New function 'sqlite-execute-batch'. This function lets the user execute multiple SQL statements in one go. It is useful, for example, when a Lisp program needs to evaluate an entire SQL file. commit dfbdd38f701cbf70769b024ee3fc59f677b328da Author: Mattias Engdegård Date: Sun Jun 30 17:06:30 2024 +0200 Revert "; * etc/NEWS: Move items to "Incompatible Lisp Changes"." This reverts commit 000ef8876ae9e2098cf98e1b1c468c09be3acd43. Most of the moved items weren't actually incompatible changes. diff --git a/etc/NEWS b/etc/NEWS index a6eda6afddd..7cc1949af2d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2135,13 +2135,6 @@ preventing the installation of Compat if unnecessary. * Incompatible Lisp Changes in Emacs 30.1 -** Bytecode is now always loaded eagerly. -Bytecode compiled with older Emacs versions for lazy loading using -'byte-compile-dynamic' is now loaded all at once. -As a consequence, 'fetch-bytecode' has no use, does nothing, and is -now obsolete. The variable 'byte-compile-dynamic' has no effect any -more; compilation will always yield bytecode for eager loading. - +++ ** Evaluating a 'lambda' returns an object of type 'interpreted-function'. Instead of representing interpreted functions as lists that start with @@ -2159,209 +2152,6 @@ no longer work and will need to use 'aref' instead to extract its various subparts (when 'interactive-form', 'documentation', and 'help-function-arglist' aren't adequate). -+++ -** Returned strings from functions and macros are never docstrings. -Functions and macros whose bodies consist of a single string literal now -only return that string; it is not used as a docstring. Example: - - (defun sing-a-song () - "Sing a song.") - -The above function returns the string '"Sing a song."' but has no -docstring. Previously, that string was used as both a docstring and -return value, which was never what the programmer wanted. If you want -the string to be a docstring, add an explicit return value. - -This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda' -forms; other defining forms such as 'cl-defun' already worked this way. - -** New or changed byte-compilation warnings - ---- -*** Warn about missing 'lexical-binding' directive. -The compiler now warns if an Elisp file lacks the standard -'-*- lexical-binding: ... -*-' cookie on the first line. -This line typically looks something like - - ;;; My little pony mode -*- lexical-binding: t -*- - -It is needed to inform the compiler about which dialect of ELisp -your code is using: the modern dialect with lexical binding or -the old dialect with only dynamic binding. - -Lexical binding avoids some name conflicts and allows the compiler to -detect more mistakes and generate more efficient code, so it is -recommended. For how to adapt your code to lexical binding, see the -manual section "(elisp) Converting to Lexical Binding". - -If your code cannot be converted to lexical binding, you can insert -the line - - ;;; -*- lexical-binding: nil -*- - -first in the file to declare that it uses the old dialect. - ---- -*** Warn about empty bodies for more special forms and macros. -The compiler now warns about an empty body argument to 'when', -'unless', 'ignore-error' and 'with-suppressed-warnings' in addition to -the existing warnings for 'let' and 'let*'. Example: - - (when (> x 2)) - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'empty-body'. - ---- -*** Warn about quoted error names in 'condition-case' and 'ignore-error'. -The compiler now warns about quoted condition (error) names -in 'condition-case' and 'ignore-error'. Example: - - (condition-case nil - (/ x y) - ('arith-error "division by zero")) - -Quoting them adds the error name 'quote' to those handled or ignored -respectively, which was probably not intended. - ---- -*** Warn about comparison with literal constants without defined identity. -The compiler now warns about comparisons by identity with a literal -string, cons, vector, record, function, large integer or float as this -may not match any value at all. Example: - - (eq x "hello") - -Only literals for symbols and small integers (fixnums), including -characters, are guaranteed to have a consistent (unique) identity. -This warning applies to 'eq', 'eql', 'memq', 'memql', 'assq', 'rassq', -'remq' and 'delq'. - -To compare by (structural) value, use 'equal', 'member', 'assoc', -'rassoc', 'remove' or 'delete' instead. Floats and bignums can also -be compared using 'eql', '=' and 'memql'. Function literals cannot be -compared reliably at all. - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'suspicious'. - ---- -*** Warn about 'condition-case' without handlers. -The compiler now warns when the 'condition-case' form is used without -any actual handlers, as in - - (condition-case nil (read buffer)) - -because it has no effect other than the execution of the body form. -In particular, no errors are caught or suppressed. If the intention -was to catch all errors, add an explicit handler for 'error', or use -'ignore-error' or 'ignore-errors'. - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'suspicious'. - ---- -*** Warn about 'unwind-protect' without unwind forms. -The compiler now warns when the 'unwind-protect' form is used without -any unwind forms, as in - - (unwind-protect (read buffer)) - -because the behavior is identical to that of the argument; there is -no protection of any kind. Perhaps the intended unwind forms have -been misplaced or forgotten, or the use of 'unwind-protect' could be -simplified away. - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'suspicious'. - ---- -*** Warn about useless trailing 'cond' clauses. -The compiler now warns when a 'cond' form contains clauses following a -default (unconditional) clause. Example: - - (cond ((= x 0) (say "none")) - (t (say "some")) - (say "goodbye")) - -Such a clause will never be executed but is likely to be a mistake, -perhaps due to misplaced brackets. - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'suspicious'. - ---- -*** Warn about mutation of constant values. -The compiler now warns about code that modifies program constants in -some obvious cases. Examples: - - (setcar '(1 2) 7) - (aset [3 4] 0 8) - (aset "abc" 1 ?d) - -Such code may have unpredictable behavior because the constants are -part of the program, not data structures generated afresh during -execution, and the compiler does not expect them to change. - -To avoid the warning, operate on an object created by the program -(maybe a copy of the constant), or use a non-destructive operation -instead. - -This warning can be suppressed using 'with-suppressed-warnings' with -the warning name 'mutate-constant'. - ---- -*** Warn about more ignored function return values. -The compiler now warns when the return value from certain functions is -implicitly ignored. Example: - - (progn (nreverse my-list) my-list) - -will elicit a warning because it is usually pointless to call -'nreverse' on a list without using the returned value. - -To silence the warning, make use of the value in some way, such as -assigning it to a variable. You can also wrap the function call in -'(ignore ...)', or use 'with-suppressed-warnings' with the warning -name 'ignored-return-value'. - -The warning will only be issued for calls to functions declared -'important-return-value' or 'side-effect-free' (but not 'error-free'). - ---- -*** Warn about docstrings that contain control characters. -The compiler now warns about docstrings with control characters other -than newline and tab. This is often a result of improper escaping. -Example: - - (defun my-fun () - "Uses c:\remote\dir\files and the key \C-x." - ...) - -where the docstring contains the four control characters 'CR', 'DEL', -'FF' and 'C-x'. - -The warning name is 'docstrings-control-chars'. - ---- -*** The warning about wide docstrings can now be disabled separately. -Its warning name is 'docstrings-wide'. - -+++ -** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases. -Previously, 'fset', 'defalias' and 'defvaralias' could be made to -build circular function and variable indirection chains as in - - (defalias 'able 'baker) - (defalias 'baker 'able) - -but trying to use them would sometimes make Emacs hang. Now, an attempt -to create such a loop results in an error. - -Since circular alias chains now cannot occur, 'function-alias-p', -'indirect-function' and 'indirect-variable' will never signal an error. -Their 'noerror' arguments have no effect and are therefore obsolete. - --- ** The escape sequence '\x' not followed by hex digits is now an error. Previously, '\x' without at least one hex digit denoted character code @@ -2447,13 +2237,6 @@ When it has a non-nil value, then completion functions like 'completing-read' don't discard text properties from the returned completion candidate. -** 'defadvice' is marked as obsolete. -See the "(elisp) Porting Old Advice" Info node for help converting -them to use 'advice-add' or 'define-advice' instead. - -** 'cl-old-struct-compat-mode' is marked as obsolete. -You may need to recompile our code if it was compiled with Emacs < 24.3. - +++ ** X color support compatibility aliases are now obsolete. The compatibility aliases 'x-defined-colors', 'x-color-defined-p', @@ -2560,7 +2343,7 @@ t only if the argument is a function rather than a special-form, and 'cl-functionp' is like 'functionp' except it returns nil for lists and symbols. -** Built-in types now have corresponding classes. +** Built-in types have now corresponding classes. At the Lisp level, this means that things like '(cl-find-class 'integer)' will now return a class object, and at the UI level it means that things like 'C-h o integer RET' will show some information about that type. @@ -2697,6 +2480,13 @@ characters in length, provided that the LONG_XLFDs argument is true. Other features in Emacs which employ XLFDs have been modified to produce and understand XLFDs larger than 255 characters. +** 'defadvice' is marked as obsolete. +See the "(elisp) Porting Old Advice" Info node for help converting +them to use 'advice-add' or 'define-advice' instead. + +** 'cl-old-struct-compat-mode' is marked as obsolete. +You may need to recompile our code if it was compiled with Emacs < 24.3. + +++ ** New macro 'static-if' for conditional evaluation of code. This macro hides a form from the evaluator or byte-compiler based on a @@ -2828,6 +2618,194 @@ Tree-sitter conditionally sets 'forward-sexp-function' for major modes that have defined 'sexp' in 'treesit-thing-settings' to enable sexp-related motion commands. ++++ +** Returned strings are never docstrings. +Functions and macros whose bodies consist of a single string literal now +only return that string; it is not used as a docstring. Example: + + (defun sing-a-song () + "Sing a song.") + +The above function returns the string '"Sing a song."' but has no +docstring. Previously, that string was used as both a docstring and +return value, which was never what the programmer wanted. If you want +the string to be a docstring, add an explicit return value. + +This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda' +forms; other defining forms such as 'cl-defun' already worked this way. + +** New or changed byte-compilation warnings + +--- +*** Warn about missing 'lexical-binding' directive. +The compiler now warns if an Elisp file lacks the standard +'-*- lexical-binding: ... -*-' cookie on the first line. +This line typically looks something like + + ;;; My little pony mode -*- lexical-binding: t -*- + +It is needed to inform the compiler about which dialect of ELisp +your code is using: the modern dialect with lexical binding or +the old dialect with only dynamic binding. + +Lexical binding avoids some name conflicts and allows the compiler to +detect more mistakes and generate more efficient code, so it is +recommended. For how to adapt your code to lexical binding, see the +manual section "(elisp) Converting to Lexical Binding". + +If your code cannot be converted to lexical binding, you can insert +the line + + ;;; -*- lexical-binding: nil -*- + +first in the file to declare that it uses the old dialect. + +--- +*** Warn about empty bodies for more special forms and macros. +The compiler now warns about an empty body argument to 'when', +'unless', 'ignore-error' and 'with-suppressed-warnings' in addition to +the existing warnings for 'let' and 'let*'. Example: + + (when (> x 2)) + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'empty-body'. + +--- +*** Warn about quoted error names in 'condition-case' and 'ignore-error'. +The compiler now warns about quoted condition (error) names +in 'condition-case' and 'ignore-error'. Example: + + (condition-case nil + (/ x y) + ('arith-error "division by zero")) + +Quoting them adds the error name 'quote' to those handled or ignored +respectively, which was probably not intended. + +--- +*** Warn about comparison with literal constants without defined identity. +The compiler now warns about comparisons by identity with a literal +string, cons, vector, record, function, large integer or float as this +may not match any value at all. Example: + + (eq x "hello") + +Only literals for symbols and small integers (fixnums), including +characters, are guaranteed to have a consistent (unique) identity. +This warning applies to 'eq', 'eql', 'memq', 'memql', 'assq', 'rassq', +'remq' and 'delq'. + +To compare by (structural) value, use 'equal', 'member', 'assoc', +'rassoc', 'remove' or 'delete' instead. Floats and bignums can also +be compared using 'eql', '=' and 'memql'. Function literals cannot be +compared reliably at all. + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'suspicious'. + +--- +*** Warn about 'condition-case' without handlers. +The compiler now warns when the 'condition-case' form is used without +any actual handlers, as in + + (condition-case nil (read buffer)) + +because it has no effect other than the execution of the body form. +In particular, no errors are caught or suppressed. If the intention +was to catch all errors, add an explicit handler for 'error', or use +'ignore-error' or 'ignore-errors'. + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'suspicious'. + +--- +*** Warn about 'unwind-protect' without unwind forms. +The compiler now warns when the 'unwind-protect' form is used without +any unwind forms, as in + + (unwind-protect (read buffer)) + +because the behavior is identical to that of the argument; there is +no protection of any kind. Perhaps the intended unwind forms have +been misplaced or forgotten, or the use of 'unwind-protect' could be +simplified away. + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'suspicious'. + +--- +*** Warn about useless trailing 'cond' clauses. +The compiler now warns when a 'cond' form contains clauses following a +default (unconditional) clause. Example: + + (cond ((= x 0) (say "none")) + (t (say "some")) + (say "goodbye")) + +Such a clause will never be executed but is likely to be a mistake, +perhaps due to misplaced brackets. + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'suspicious'. + +--- +*** Warn about mutation of constant values. +The compiler now warns about code that modifies program constants in +some obvious cases. Examples: + + (setcar '(1 2) 7) + (aset [3 4] 0 8) + (aset "abc" 1 ?d) + +Such code may have unpredictable behavior because the constants are +part of the program, not data structures generated afresh during +execution, and the compiler does not expect them to change. + +To avoid the warning, operate on an object created by the program +(maybe a copy of the constant), or use a non-destructive operation +instead. + +This warning can be suppressed using 'with-suppressed-warnings' with +the warning name 'mutate-constant'. + +--- +*** Warn about more ignored function return values. +The compiler now warns when the return value from certain functions is +implicitly ignored. Example: + + (progn (nreverse my-list) my-list) + +will elicit a warning because it is usually pointless to call +'nreverse' on a list without using the returned value. + +To silence the warning, make use of the value in some way, such as +assigning it to a variable. You can also wrap the function call in +'(ignore ...)', or use 'with-suppressed-warnings' with the warning +name 'ignored-return-value'. + +The warning will only be issued for calls to functions declared +'important-return-value' or 'side-effect-free' (but not 'error-free'). + +--- +*** Warn about docstrings that contain control characters. +The compiler now warns about docstrings with control characters other +than newline and tab. This is often a result of improper escaping. +Example: + + (defun my-fun () + "Uses c:\remote\dir\files and the key \C-x." + ...) + +where the docstring contains the four control characters 'CR', 'DEL', +'FF' and 'C-x'. + +The warning name is 'docstrings-control-chars'. + +--- +*** The warning about wide docstrings can now be disabled separately. +Its warning name is 'docstrings-wide'. + --- ** New user option 'native-comp-async-warnings-errors-kind'. It allows control of what kinds of warnings and errors from asynchronous @@ -2861,12 +2839,34 @@ The declaration '(important-return-value t)' sets the 'important-return-value' property which indicates that the function return value should probably not be thrown away implicitly. +** Bytecode is now always loaded eagerly. +Bytecode compiled with older Emacs versions for lazy loading using +'byte-compile-dynamic' is now loaded all at once. +As a consequence, 'fetch-bytecode' has no use, does nothing, and is +now obsolete. The variable 'byte-compile-dynamic' has no effect any +more; compilation will always yield bytecode for eager loading. + +++ ** New functions 'file-user-uid' and 'file-group-gid'. These functions are like 'user-uid' and 'group-gid', respectively, but are aware of file name handlers, so they will return the remote UID or GID for remote files (or -1 if the connection has no associated user). ++++ +** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases. +Previously, 'fset', 'defalias' and 'defvaralias' could be made to +build circular function and variable indirection chains as in + + (defalias 'able 'baker) + (defalias 'baker 'able) + +but trying to use them would sometimes make Emacs hang. Now, an attempt +to create such a loop results in an error. + +Since circular alias chains now cannot occur, 'function-alias-p', +'indirect-function' and 'indirect-variable' will never signal an error. +Their 'noerror' arguments have no effect and are therefore obsolete. + +++ ** 'treesit-font-lock-rules' now accepts additional global keywords. When supplied with ':default-language LANGUAGE', rules after it will @@ -2982,7 +2982,7 @@ this was not possible.) In addition, LOCATION can be an integer, a (BEFORE is ignored in this case). +++ -** New function 'sqlite-execute-batch'. +**** New function 'sqlite-execute-batch'. This function lets the user execute multiple SQL statements in one go. It is useful, for example, when a Lisp program needs to evaluate an entire SQL file. commit 7c8d4e96ba6db19bdca20a87bafed024a84eb517 Merge: 7f89fe8a342 64851d101a8 Author: Po Lu Date: Sun Jun 30 23:12:09 2024 +0800 Merge from savannah/emacs-30 64851d101a8 Improve Android "adaptive icon" 9b294059d71 Fix documentation for Emacs 30 f50167ab95e ; Update NEWS and corresponding manuals 4e22ef870c4 Add D-Bus test f784d946d44 ; Repair corruption in etc/DEBUG c750fbb539e ; * etc/DEBUG: Advice for debugging Emacs on OpenBSD (bug... 38179f85f8f Merge remote-tracking branch 'savannah/scratch/windows-98... 72cf9964f3c Inaccuracy in efaq.texi fc48e9e8ed5 ; Fix typos in DOS Makefile scripts 9b8d754579f ; * etc/NEWS: Explain Nextstep. 8819e5a45d5 Fix treesit crash (bug#71681) eaf2dc96c1f ; Fix SHR test on MS-Windows 57880f597c5 Delete redundant mention of `with-eval-after-load' ea8ce984342 * doc/misc/efaq.texi (New in Emacs 30): Fix typos. 45a20d781a9 ; Fix typos in symbols d95f039af43 Document security fixes in FAQ d063af203c8 Add "New in Emacs 30" to FAQ ca6b484162b ; * etc/NEWS: Move "Minibuffer and Completions" 35c46663e49 ; * etc/NEWS: Move item to "Lisp Changes". 0515b38d289 ; * etc/NEWS: Move keyboard macro items closer together. 22af3a71039 ; * etc/NEWS: More copy-edits. 000ef8876ae ; * etc/NEWS: Move items to "Incompatible Lisp Changes". 4088dc8e4ce ; * etc/NEWS: Rearrange "Incompatible Lisp Changes". 179800f36bb ; * lisp/epg.el (epg--start): Add commentary about encoding. 73898f0214c Fix non-ASCII filename operatiion on EasyPG (bug#71500) a65b6aac6b5 Silence warning with global minor mode :predicate f5f7343ac41 ; * etc/NEWS: Move an item to "Startup Changes" c95066bf188 ; * etc/NEWS: Move some Lisp items to better place. bf7db88ce1f ; * etc/NEWS: Rearrange "Editing Changes in Emacs 30.1" 000424eb9eb ; * etc/NEWS: Make touch screen support more prominent. 5b5671587fb ; * etc/NEWS: Rearrange "Changes in Emacs 30.1". 31124abdefe ; * lisp/thingatpt.el (sexp-at-point): Doc fix (bug#71777). 44f269d6e60 Fix: make 'xwidget-webkit-scroll-backward' scroll backwards 358085997c6 Merge branch 'emacs-30' of git.savannah.gnu.org:/srv/git/... 736b7cad406 Add jsdoc support to php-ts-mode in