commit ec20ebf2413ca1042cd41e3a278d18f1fc1debf6 (HEAD, refs/remotes/origin/master) Author: Steven Allen Date: Tue Jan 14 23:56:08 2025 -0800 Take the tab-line into account when computing the window edges window-body-height correctly subtracts the tab-line's height but window-edges did not add this same height to the y-offset. See https://github.com/emacs-exwm/exwm/pull/114 * lisp/window.el (window-edges): Add the tab-line-height to the y-offet of the window body. (Bug#75576) diff --git a/lisp/window.el b/lisp/window.el index 886128c7daa..b91c45226a1 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -3828,7 +3828,8 @@ ABSOLUTE is non-nil, PIXELWISE is implicitly non-nil too." (top-body (when body (+ (window-pixel-top window) border-width - (window-header-line-height window)))) + (window-header-line-height window) + (window-tab-line-height window)))) (right (+ left (if pixelwise (window-pixel-width window) (window-total-width window)))) commit 74dc2bd28007e68532d9813a57d3ec7da0c390e3 Author: Paul Eggert Date: Wed Jan 15 19:31:07 2025 -0800 Update from Gnulib by running admin/merge-gnulib diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index 5f06c4fe10f..ac61c0865a4 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -369,8 +369,12 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " # define O_RSYNC 0 #endif +#if defined O_SEARCH && defined O_PATH && O_SEARCH == O_PATH +# undef O_SEARCH /* musl mistakenly #defines O_SEARCH to O_PATH. */ +#endif + #ifndef O_SEARCH -# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */ +# define O_SEARCH O_RDONLY /* Often close enough in non-POSIX systems. */ #endif #ifndef O_SYNC diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 35dcc19f169..e8413f8f85f 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -99,6 +99,36 @@ enum { ACE4_IDENTIFIER_GROUP = 0x00000040 }; +/* AI indicates XATTR may be present but wasn't accessible. + This is the case when [l]listxattr failed with E2BIG, + or failed with EACCES which in Linux kernel 6.12 NFS can mean merely + that we lack read access. +*/ + +static bool +aclinfo_may_indicate_xattr (struct aclinfo const *ai) +{ + return ai->size < 0 && (ai->u.err == EACCES || ai->u.err == E2BIG); +} + +/* Does NAME have XATTR? */ + +static bool +has_xattr (char const *xattr, struct aclinfo const *ai, + MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) +{ + if (ai && aclinfo_has_xattr (ai, xattr)) + return true; + else if (!ai || aclinfo_may_indicate_xattr (ai)) + { + int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) + (name, xattr, NULL, 0)); + if (0 <= ret || (errno == ERANGE || errno == E2BIG)) + return true; + } + return false; +} + /* Does AI's xattr set contain XATTR? */ bool @@ -176,11 +206,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) } } - if (0 < ai->size && flags & ACL_GET_SCONTEXT) + /* A security context can exist only if extended attributes do. */ + if (flags & ACL_GET_SCONTEXT + && (0 < ai->size || aclinfo_may_indicate_xattr (ai))) { if (is_smack_enabled ()) { - if (aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) { ssize_t r = smack_new_label_from_path (name, "security.SMACK64", flags & ACL_SYMLINK_FOLLOW, @@ -191,7 +223,7 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) else { # if USE_SELINUX_SELINUX_H - if (aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) { ssize_t r = ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) @@ -352,7 +384,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, int initial_errno = errno; get_aclinfo (name, ai, flags); - if (ai->size <= 0) + if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) { errno = ai->size < 0 ? ai->u.err : initial_errno; return ai->size; @@ -363,11 +395,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, In earlier Fedora the two types of ACLs were mutually exclusive. Attempt to work correctly on both kinds of systems. */ - if (!aclinfo_has_xattr (ai, XATTR_NAME_NFSV4_ACL)) + if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) return - (aclinfo_has_xattr (ai, XATTR_NAME_POSIX_ACL_ACCESS) + (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) || ((d_type == DT_DIR || d_type == DT_UNKNOWN) - && aclinfo_has_xattr (ai, XATTR_NAME_POSIX_ACL_DEFAULT))); + && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); /* A buffer large enough to hold any trivial NFSv4 ACL. The max length of a trivial NFSv4 ACL is 6 words for owner, diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index a42e77e99b8..b1f0053e582 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -489,6 +489,8 @@ GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@ GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@ GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@ GL_GNULIB_MBSTOWCS = @GL_GNULIB_MBSTOWCS@ +GL_GNULIB_MBS_ENDSWITH = @GL_GNULIB_MBS_ENDSWITH@ +GL_GNULIB_MBS_STARTSWITH = @GL_GNULIB_MBS_STARTSWITH@ GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@ GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@ GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@ @@ -642,6 +644,8 @@ GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@ GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@ GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@ GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@ +GL_GNULIB_STR_ENDSWITH = @GL_GNULIB_STR_ENDSWITH@ +GL_GNULIB_STR_STARTSWITH = @GL_GNULIB_STR_STARTSWITH@ GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@ GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@ GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@ @@ -3655,6 +3659,8 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \ -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \ -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \ + -e 's/@''GNULIB_MBS_ENDSWITH''@/$(GL_GNULIB_MBS_ENDSWITH)/g' \ + -e 's/@''GNULIB_MBS_STARTSWITH''@/$(GL_GNULIB_MBS_STARTSWITH)/g' \ -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \ -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \ -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \ @@ -3673,6 +3679,8 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \ -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \ -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \ + -e 's/@''GNULIB_STR_ENDSWITH''@/$(GL_GNULIB_STR_ENDSWITH)/g' \ + -e 's/@''GNULIB_STR_STARTSWITH''@/$(GL_GNULIB_STR_STARTSWITH)/g' \ -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \ diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h index 1da98b43732..215be914c2f 100644 --- a/lib/mktime-internal.h +++ b/lib/mktime-internal.h @@ -19,6 +19,9 @@ #ifndef _LIBC # include +# define __libc_lock_lock(lock) ((void) 0) +# define __libc_lock_unlock(lock) ((void) 0) +# define __tzset_unlocked() tzset () #endif /* mktime_offset_t is a signed type wide enough to hold a UTC offset @@ -73,6 +76,8 @@ typedef int mktime_offset_t; /* Subroutine of mktime. Return the time_t representation of TP and normalize TP, given that a struct tm * maps to a time_t. If LOCAL, the mapping is performed by localtime_r, otherwise by gmtime_r. - Record next guess for localtime-gmtime offset in *OFFSET. */ + Record next guess for localtime-gmtime offset in *OFFSET. + + If _LIBC, the caller must lock __tzset_lock. */ extern __time64_t __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) attribute_hidden; diff --git a/lib/mktime.c b/lib/mktime.c index 74403e4530e..4218fca69b1 100644 --- a/lib/mktime.c +++ b/lib/mktime.c @@ -62,6 +62,9 @@ # define NEED_MKTIME_WORKING 0 #endif +#ifdef _LIBC +# include +#endif #include "mktime-internal.h" #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) @@ -98,8 +101,8 @@ my_tzset (void) tzset (); # endif } -# undef __tzset -# define __tzset() my_tzset () +# undef tzset +# define tzset() my_tzset () #endif #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL @@ -250,6 +253,7 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec, tp->tm_hour, tp->tm_min, tp->tm_sec); } +#ifndef _LIBC /* Convert T to a struct tm value in *TM. Use localtime64_r if LOCAL, otherwise gmtime64_r. T must be in range for __time64_t. Return TM if successful, NULL (setting errno) on failure. */ @@ -262,8 +266,8 @@ convert_time (long_int t, bool local, struct tm *tm) else return __gmtime64_r (&x, tm); } -/* Call it __tzconvert to sync with other parts of glibc. */ -#define __tz_convert convert_time +# define __tz_convert convert_time +#endif /* Convert *T to a broken down time in *TP (as if by localtime if LOCAL, otherwise as if by gmtime). If *T is out of range for @@ -320,7 +324,9 @@ ranged_convert (bool local, long_int *t, struct tm *tp) If *OFFSET's guess is correct, only one reverse mapping call is needed. If successful, set *TP to the canonicalized struct tm; otherwise leave *TP alone, return ((time_t) -1) and set errno. - This function is external because it is used also by timegm.c. */ + This function is external because it is used also by timegm.c. + + If _LIBC, the caller must lock __tzset_lock. */ __time64_t __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) { @@ -349,12 +355,10 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) int mday = tp->tm_mday; int mon = tp->tm_mon; int year_requested = tp->tm_year; + int isdst = tp->tm_isdst; - /* Ignore any tm_isdst request for timegm. */ - int isdst = local ? tp->tm_isdst : 0; - - /* 1 if the previous probe was DST. */ - int dst2 = 0; + /* True if the previous probe was DST. */ + bool dst2 = false; /* Ensure that mon is in range, and set year accordingly. */ int mon_remainder = mon % 12; @@ -443,13 +447,10 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) Heuristic: probe the adjacent timestamps in both directions, looking for the desired isdst. If none is found within a - reasonable duration bound, assume a one-hour DST difference. + reasonable duration bound, ignore the disagreement. This should work for all real time zone histories in the tz database. */ - /* +1 if we wanted standard time but got DST, -1 if the reverse. */ - int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); - /* Distance between probes when looking for a DST boundary. In tzdata2003a, the shortest period of DST is 601200 seconds (e.g., America/Recife starting 2000-10-08 01:00), and the @@ -459,21 +460,17 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) periods when probing. */ int stride = 601200; - /* In TZDB 2021e, the longest period of DST (or of non-DST), in - which the DST (or adjacent DST) difference is not one hour, - is 457243209 seconds: e.g., America/Cambridge_Bay with leap - seconds, starting 1965-10-31 00:00 in a switch from - double-daylight time (-05) to standard time (-07), and - continuing to 1980-04-27 02:00 in a switch from standard time - (-07) to daylight time (-06). */ - int duration_max = 457243209; - - /* Search in both directions, so the maximum distance is half - the duration; add the stride to avoid off-by-1 problems. */ - int delta_bound = duration_max / 2 + stride; + /* Do not probe too far away from the requested time, + by striding until at least a year has passed, but then giving up. + This helps avoid unexpected results in (for example) Asia/Kolkata, + for which today's users expect to see no DST even though it + did observe DST long ago. */ + int year_seconds_bound = 366 * 24 * 60 * 60 + 1; + int delta_bound = year_seconds_bound + stride; int delta, direction; + /* Search in both directions, closest first. */ for (delta = stride; delta < delta_bound; delta += stride) for (direction = -1; direction <= 1; direction += 2) { @@ -503,13 +500,8 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) } } - /* No unusual DST offset was found nearby. Assume one-hour DST. */ - t += 60 * 60 * dst_difference; - if (mktime_min <= t && t <= mktime_max && __tz_convert (t, local, &tm)) - goto offset_found; - - __set_errno (EOVERFLOW); - return -1; + /* No probe with the requested tm_isdst was found nearby. + Ignore the requested tm_isdst. */ } offset_found: @@ -548,17 +540,19 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) __time64_t __mktime64 (struct tm *tp) { - /* POSIX.1 requires mktime to set external variables like 'tzname' - as though tzset had been called. */ - __tzset (); + __libc_lock_lock (__tzset_lock); + __tzset_unlocked (); # if defined _LIBC || NEED_MKTIME_WORKING static mktime_offset_t localtime_offset; - return __mktime_internal (tp, true, &localtime_offset); + __time64_t result = __mktime_internal (tp, true, &localtime_offset); # else # undef mktime - return mktime (tp); + __time64_t result = mktime (tp); # endif + + __libc_lock_unlock (__tzset_lock); + return result; } #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index f8e2a6ce344..bd82086ff37 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -62,8 +62,9 @@ /* NetBSD 5.0 mis-defines NULL. */ #include -/* MirBSD 10 defines WEXITSTATUS in , not in . */ -#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS +/* MirBSD 10 defines WEXITSTATUS in , not in . + glibc 2.40 defines WCOREDUMP in , not in . */ +#if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) # include #endif diff --git a/lib/string.in.h b/lib/string.in.h index 1bae32ad465..ce488299006 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -1077,6 +1077,22 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " /* The following functions are not specified by POSIX. They are gnulib extensions. */ +#if @GNULIB_STR_STARTSWITH@ +/* Returns true if STRING starts with PREFIX. + Returns false otherwise. */ +_GL_EXTERN_C bool str_startswith (const char *string, const char *prefix) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_STR_ENDSWITH@ +/* Returns true if STRING ends with SUFFIX. + Returns false otherwise. */ +_GL_EXTERN_C bool str_endswith (const char *string, const char *prefix) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + #if @GNULIB_MBSLEN@ /* Return the number of multibyte characters in the character string STRING. This considers multibyte characters, unlike strlen, which counts bytes. */ @@ -1301,6 +1317,26 @@ _GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim, _GL_ARG_NONNULL ((2, 3)); #endif +#if @GNULIB_MBS_STARTSWITH@ +/* Returns true if STRING starts with PREFIX. + Returns false otherwise. */ +_GL_EXTERN_C bool mbs_startswith (const char *string, const char *prefix) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +/* No extra code is needed for multibyte locales for this function. */ +# define mbs_startswith str_startswith +#endif + +#if @GNULIB_MBS_ENDSWITH@ +/* Returns true if STRING ends with SUFFIX. + Returns false otherwise. + Unlike str_endswith(), this function works correctly in multibyte locales. + */ +_GL_EXTERN_C bool mbs_endswith (const char *string, const char *suffix) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + /* Map any int, typically from errno, into an error message. */ #if @GNULIB_STRERROR@ # if @REPLACE_STRERROR@ diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h index fd3e28fd8e0..a06725020d2 100644 --- a/lib/sys_select.in.h +++ b/lib/sys_select.in.h @@ -165,12 +165,18 @@ #if @HAVE_WINSOCK2_H@ +/* Define type 'suseconds_t'. */ +# if !GNULIB_defined_suseconds_t +typedef int suseconds_t; +# define GNULIB_defined_suseconds_t 1 +# endif + # if !GNULIB_defined_rpl_fd_isset /* Re-define FD_ISSET to avoid a WSA call while we are not using network sockets. */ static int -rpl_fd_isset (SOCKET fd, fd_set * set) +rpl_fd_isset (SOCKET fd, const fd_set * set) { u_int i; if (set == NULL) diff --git a/m4/assert_h.m4 b/m4/assert_h.m4 index 91f446e7f6d..e77524caff9 100644 --- a/m4/assert_h.m4 +++ b/m4/assert_h.m4 @@ -1,5 +1,5 @@ # assert_h.m4 -# serial 4 +# serial 5 dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -64,11 +64,13 @@ AC_DEFUN([gl_ASSERT_H], [#if (!(defined __clang__ \ ? (defined __cplusplus \ ? __cplusplus >= 201703L \ - : __STDC_VERSION__ >= 202000L && __clang_major__ >= 16) \ + : __STDC_VERSION__ >= 202000L && __clang_major__ >= 16 \ + && !defined __sun) \ : (defined __GNUC__ \ ? (defined __cplusplus \ ? __cplusplus >= 201103L && __GNUG__ >= 6 \ - : __STDC_VERSION__ >= 202000L && __GNUC__ >= 13) \ + : __STDC_VERSION__ >= 202000L && __GNUC__ >= 13 \ + && !defined __sun) \ : defined HAVE_C_STATIC_ASSERT)) \ && !defined assert \ && (!defined __cplusplus \ diff --git a/m4/string_h.m4 b/m4/string_h.m4 index a07738479d4..d0a67608114 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -1,5 +1,5 @@ # string_h.m4 -# serial 39 +# serial 43 dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -70,6 +70,8 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) @@ -84,6 +86,8 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBS_STARTSWITH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBS_ENDSWITH]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP]) diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 index 75e97485724..fb69209b4dc 100644 --- a/m4/sys_socket_h.m4 +++ b/m4/sys_socket_h.m4 @@ -1,5 +1,5 @@ # sys_socket_h.m4 -# serial 29 +# serial 31 dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -53,24 +53,10 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H], fi # We need to check for ws2tcpip.h now. gl_PREREQ_SYS_H_SOCKET - AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ - /* sys/types.h is not needed according to POSIX, but the - sys/socket.h in i386-unknown-freebsd4.10 and - powerpc-apple-darwin5.5 required it. */ -#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WS2TCPIP_H -#include -#endif -]) + gl_PREREQ_SYS_SA_FAMILY if test $ac_cv_type_struct_sockaddr_storage = no; then HAVE_STRUCT_SOCKADDR_STORAGE=0 fi - if test $ac_cv_type_sa_family_t = no; then - HAVE_SA_FAMILY_T=0 - fi if test $ac_cv_type_struct_sockaddr_storage != no; then AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], [], @@ -159,6 +145,32 @@ AC_DEFUN([gl_PREREQ_SYS_H_WS2TCPIP], AC_SUBST([HAVE_WS2TCPIP_H]) ]) +# Common prerequisites of the replacement and of the +# replacement. +# Sets and substitutes HAVE_SA_FAMILY_T. +AC_DEFUN([gl_PREREQ_SYS_SA_FAMILY], +[ + AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) + AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ + /* sys/types.h is not needed according to POSIX, but the + sys/socket.h in i386-unknown-freebsd4.10 and + powerpc-apple-darwin5.5 required it. */ +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WS2TCPIP_H +#include +#endif +]) + if test $ac_cv_type_sa_family_t = yes; then + HAVE_SA_FAMILY_T=1 + else + HAVE_SA_FAMILY_T=0 + fi + AC_SUBST([HAVE_SA_FAMILY_T]) +]) + # gl_SYS_SOCKET_MODULE_INDICATOR([modulename]) # sets the shell variable that indicates the presence of the given module # to a C preprocessor expression that will evaluate to 1. @@ -203,6 +215,5 @@ AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) - HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) ]) commit 4f946a652278cc72a777fe56999bc4525f53e03a Author: Stefan Kangas Date: Wed Jan 15 23:11:16 2025 +0100 Fix clear-string crash with text properties * src/fns.c (Fclear_string): Fix crash by clearing all text properties. (Bug#75581) * doc/lispref/strings.texi (Modifying Strings): Document the above behavior change. Fix proposed by Andreas Schwab . diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index da0c1abd348..93025574893 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -478,8 +478,9 @@ a raw byte. @code{clear-string}: @defun clear-string string -This makes @var{string} a unibyte string and clears its contents to -null characters. It may also change @var{string}'s length. +This makes @var{string} a unibyte string, clears its contents to null +characters, and removes all text properties. It may also change +@var{string}'s length. @end defun @need 2000 diff --git a/src/fns.c b/src/fns.c index 191154c651a..07df2a5e90e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -3307,14 +3307,16 @@ ARRAY is a vector, string, char-table, or bool-vector. */) return array; } -DEFUN ("clear-string", Fclear_string, Sclear_string, - 1, 1, 0, +DEFUN ("clear-string", Fclear_string, Sclear_string, 1, 1, 0, doc: /* Clear the contents of STRING. -This makes STRING unibyte and may change its length. */) +This makes STRING unibyte, clears its contents to null characters, and +removes all text properties. This may change its length. */) (Lisp_Object string) { CHECK_STRING (string); ptrdiff_t len = SBYTES (string); + Fset_text_properties (make_fixnum (0), make_fixnum (SCHARS (string)), + Qnil, string); if (len != 0 || STRING_MULTIBYTE (string)) { CHECK_IMPURE (string, XSTRING (string)); commit 86916c136b3129fac2e805b380fe501a50459abd Author: Stefan Kangas Date: Wed Jan 15 23:11:45 2025 +0100 Add clear-string to symbol-releases.eld * etc/symbol-releases.eld (clear-string): Add function. diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index de1eaad6bd1..0609dd1467f 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -14,6 +14,7 @@ ("26.1" fun and-let*) ("26.1" fun if-let*) ("24.4" fun set-transient-map) + ("22.1" fun clear-string) ("22.1" fun version=) ("22.1" fun version<) ("22.1" fun version<=) commit e092aabf714717dd135e5767a49b78c428e49878 Author: Stefan Kangas Date: Wed Jan 15 20:09:32 2025 +0100 Prefer 'ARRAYELTS (x)' to 'sizeof x / sizeof *x' * src/comp.c (emit_limple_insn): * src/msdos.c (dos_set_keyboard, dos_rawgetc): * src/sysdep.c (convert_speed, list_system_processes): * src/w32fns.c (deliver_wm_chars, Fx_file_dialog): * src/w32term.c (record_event, w32_read_socket): Prefer 'ARRAYELTS (x)' to 'sizeof x / sizeof *x'. * admin/coccinelle/arrayelts.cocci: New file. diff --git a/admin/coccinelle/arrayelts.cocci b/admin/coccinelle/arrayelts.cocci new file mode 100644 index 00000000000..5376a94bd85 --- /dev/null +++ b/admin/coccinelle/arrayelts.cocci @@ -0,0 +1,21 @@ +// Use the ARRAYELTS macro where possible. +@@ +type T; +T[] E; +@@ +- (sizeof (E) / sizeof (E[...])) ++ ARRAYELTS (E) + +@@ +type T; +T[] E; +@@ +- (sizeof (E) / sizeof (T)) ++ ARRAYELTS (E) + +@@ +type T; +T[] E; +@@ +- (sizeof (E) / sizeof (*E)) ++ ARRAYELTS (E) diff --git a/src/comp.c b/src/comp.c index 97c7ea2efac..2603a2f4334 100644 --- a/src/comp.c +++ b/src/comp.c @@ -2279,7 +2279,7 @@ emit_limple_insn (Lisp_Object insn) ptrdiff_t i = 0; FOR_EACH_TAIL (p) { - if (i == sizeof (arg) / sizeof (Lisp_Object)) + if (i == ARRAYELTS (arg)) break; arg[i++] = XCAR (p); } diff --git a/src/msdos.c b/src/msdos.c index 6ee35b9e853..63a5400bc7d 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -2069,7 +2069,7 @@ dos_set_keyboard (int code, int always) keyboard_map_all = always; dos_keyboard_layout = 1; - for (i = 0; i < (sizeof (keyboard_layout_list)/sizeof (struct keyboard_layout_list)); i++) + for (i = 0; i < ARRAYELTS (keyboard_layout_list); i++) if (code == keyboard_layout_list[i].country_code) { keyboard = keyboard_layout_list[i].keyboard_map; @@ -2512,7 +2512,7 @@ dos_rawgetc (void) one. */ if (code == -1) { - if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short))) + if (sc >= ARRAYELTS (ibmpc_translate_map)) continue; if ((code = ibmpc_translate_map[sc]) == Ignore) continue; diff --git a/src/sysdep.c b/src/sysdep.c index 188b3c3958a..3d9c49d9280 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -3160,7 +3160,7 @@ static const struct speed_struct speeds[] = static speed_t convert_speed (speed_t speed) { - for (size_t i = 0; i < sizeof speeds / sizeof speeds[0]; i++) + for (size_t i = 0; i < ARRAYELTS (speeds); i++) { if (speed == speeds[i].internal) return speed; @@ -3380,7 +3380,7 @@ list_system_processes (void) int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC}; #endif size_t len; - size_t mibsize = sizeof mib / sizeof mib[0]; + size_t mibsize = ARRAYELTS (mib); struct kinfo_proc *procs; size_t i; diff --git a/src/w32fns.c b/src/w32fns.c index c7963d2c616..452740f46ca 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -4154,7 +4154,7 @@ deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam, windows_msg.time = GetMessageTime (); TranslateMessage (&windows_msg); } - count = get_wm_chars (hwnd, buf, sizeof (buf)/sizeof (*buf), 1, + count = get_wm_chars (hwnd, buf, ARRAYELTS (buf), 1, /* The message may have been synthesized by who knows what; be conservative. */ modifier_set (VK_LCONTROL) @@ -8379,8 +8379,7 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, file_details_w->lStructSize = sizeof (*file_details_w); /* Set up the inout parameter for the selected file name. */ file_details_w->lpstrFile = filename_buf_w; - file_details_w->nMaxFile = - sizeof (filename_buf_w) / sizeof (*filename_buf_w); + file_details_w->nMaxFile = ARRAYELTS (filename_buf_w); file_details_w->hwndOwner = FRAME_W32_WINDOW (f); /* Undocumented Bug in Common File Dialog: If a filter is not specified, shell links are not resolved. */ @@ -8413,8 +8412,7 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, else file_details_a->lStructSize = sizeof (*file_details_a); file_details_a->lpstrFile = filename_buf_a; - file_details_a->nMaxFile = - sizeof (filename_buf_a) / sizeof (*filename_buf_a); + file_details_a->nMaxFile = ARRAYELTS (filename_buf_a); file_details_a->hwndOwner = FRAME_W32_WINDOW (f); file_details_a->lpstrFilter = filter_a; file_details_a->lpstrInitialDir = dir_a; diff --git a/src/w32term.c b/src/w32term.c index c81779b8517..cb7bc7e4540 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -276,7 +276,7 @@ int event_record_index; record_event (char *locus, int type) { - if (event_record_index == sizeof (event_record) / sizeof (struct record)) + if (event_record_index == ARRAYELTS (event_record)) event_record_index = 0; event_record[event_record_index].locus = locus; @@ -5259,7 +5259,7 @@ w32_read_socket (struct terminal *terminal, hlinfo->mouse_face_hidden = true; } - if (temp_index == sizeof temp_buffer / sizeof (short)) + if (temp_index == ARRAYELTS (temp_buffer)) temp_index = 0; temp_buffer[temp_index++] = msg.msg.wParam; inev.kind = NON_ASCII_KEYSTROKE_EVENT; @@ -5285,7 +5285,7 @@ w32_read_socket (struct terminal *terminal, hlinfo->mouse_face_hidden = true; } - if (temp_index == sizeof temp_buffer / sizeof (short)) + if (temp_index == ARRAYELTS (temp_buffer)) temp_index = 0; temp_buffer[temp_index++] = msg.msg.wParam; @@ -5400,7 +5400,7 @@ w32_read_socket (struct terminal *terminal, hlinfo->mouse_face_hidden = true; } - if (temp_index == sizeof temp_buffer / sizeof (short)) + if (temp_index == ARRAYELTS (temp_buffer)) temp_index = 0; temp_buffer[temp_index++] = msg.msg.wParam; inev.kind = MULTIMEDIA_KEY_EVENT;