* Re: boot-time: straighten code [not found] <4536176.VaOIPsP7d9@nimes> @ 2023-08-13 2:49 ` Paul Eggert 2023-08-13 3:26 ` Po Lu ` (2 more replies) 0 siblings, 3 replies; 24+ messages in thread From: Paul Eggert @ 2023-08-13 2:49 UTC (permalink / raw) To: Bruno Haible; +Cc: bug-gnulib, Emacs Development [-- Attachment #1: Type: text/plain, Size: 927 bytes --] On 2023-08-11 14:49, Bruno Haible wrote: > Paul: With this simplification, you may consider using the 'boot-time' module > in Emacs. I bet that it produces a better result than Emacs' src/filelock.c > on many platforms. (I haven't tested it, but I could test it if you give me > a manual testing recipe.) Thanks for doing all that. I installed the attached patch into Emacs master, which you should be able to test via: git clone https://git.savannah.gnu.org/git/emacs.git cd emacs ./autogen.sh ./configure make src/emacs Please give it a try, especially on any MS-Windows platform you happen to have. I have tested only on Ubuntu 23.04 so far. A simple way to test is to use Emacs to start editing a file (without saving) and then inspect the symbolic link .#* that Emacs uses as a lock file. The trailing digits of that link's contents should be the boot time. These symlinks are Emacs's only use of boot time. [-- Attachment #2: 0001-Improve-boot-time-gathering.patch --] [-- Type: text/x-patch, Size: 51156 bytes --] From 5e736ca6ccfa131736ab0b3a298de2cb319e7dfb Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sat, 12 Aug 2023 19:39:11 -0700 Subject: [PATCH] Improve boot-time gathering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify Emacs proper by using Gnulib’s boot-time module instead of doing it all by hand. This should port Emacs better to obscurish hosts, as Bruno Haible has merged the best of Emacs’s and Gnulib’s boot-time gathering. * lib/boot-time-aux.h, lib/boot-time.c, lib/boot-time.h: * lib/readutmp.h, m4/readutmp.m4: New files, copied from Gnulib. * admin/merge-gnulib (GNULIB_MODULES): Add boot-time. * configure.ac: Do not check for utmp.h; the boot-time module now does this. (BOOT_TIME_FILE): Remove; no longer used. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * src/filelock.c [__FreeBSD__]: Do not include <sys/sysctl.h>. [HAVE_UTMP_H]: Do not include utmp.h. Include boot-time instead: boot-time does the work now. (BOOT_TIME) [HAVE_ANDROID && !ANDROID_STUBIFY]: Don’t undef. (WTMP_FILE): Don’t define. (boot_time, boot_time_initialized, get_boot_time_1, get_boot_time): Remove. (get_boot_sec): New function that simply calls Gnulib get_boot_time. (lock_file_1, current_lock_owner): Use get_boot_sec instead of get_boot_time. --- admin/merge-gnulib | 2 +- configure.ac | 47 +------ lib/boot-time-aux.h | 315 ++++++++++++++++++++++++++++++++++++++++++ lib/boot-time.c | 285 ++++++++++++++++++++++++++++++++++++++ lib/boot-time.h | 44 ++++++ lib/gnulib.mk.in | 11 ++ lib/readutmp.h | 325 ++++++++++++++++++++++++++++++++++++++++++++ m4/gnulib-comp.m4 | 7 + m4/readutmp.m4 | 117 ++++++++++++++++ src/filelock.c | 172 ++--------------------- 10 files changed, 1116 insertions(+), 209 deletions(-) create mode 100644 lib/boot-time-aux.h create mode 100644 lib/boot-time.c create mode 100644 lib/boot-time.h create mode 100644 lib/readutmp.h create mode 100644 m4/readutmp.m4 diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 2a713beb01a..fe88d1106ae 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -26,7 +26,7 @@ GNULIB_URL=https://git.savannah.gnu.org/git/gnulib.git GNULIB_MODULES=' - alignasof alloca-opt binary-io byteswap c-ctype c-strcase + alignasof alloca-opt binary-io boot-time byteswap c-ctype c-strcase canonicalize-lgpl careadlinkat close-stream copy-file-range count-leading-zeros count-one-bits count-trailing-zeros diff --git a/configure.ac b/configure.ac index 35dfed247d0..0234a82b92f 100644 --- a/configure.ac +++ b/configure.ac @@ -2539,7 +2539,7 @@ AC_DEFUN sys/sysinfo.h coff.h pty.h sys/resource.h - sys/utsname.h pwd.h utmp.h util.h + sys/utsname.h pwd.h util.h sanitizer/lsan_interface.h sanitizer/asan_interface.h sanitizer/common_interface_defs.h]) @@ -2635,51 +2635,6 @@ AC_DEFUN fi AC_SUBST([AUTO_DEPEND]) -BOOT_TIME_FILE= -AC_CACHE_CHECK([for old but post-boot file], - [emacs_cv_boot_time_file], - [AS_CASE([$opsys], - [gnu-linux], - [emacs_cv_boot_time_file=unknown - AS_IF([test $cross_compiling = no], - [# systemd puts it in /var/lib/systemd. - # initscripts puts it in /var/lib/urandom (previously /var/lib). - # Linux drivers/char/random.c before 2022-02-21 suggests /var/run. - for file in \ - /var/lib/systemd/random-seed \ - /var/lib/urandom/random-seed \ - /var/lib/random-seed \ - /var/run/random-seed - do - test -f $file && { emacs_cv_boot_time_file=$file; break; } - done])], - # This isn't perfect, as some systems might have the page file in - # another place. Also, I suspect that the time stamp of that - # file might also change when Windows enlarges the file due to - # insufficient VM. Still, this seems to be the most reliable - # way; the alternative (of using GetSystemTimes) won't work on - # laptops that hibernate, because the system clock is stopped - # then. Other possibility would be to run "net statistics - # workstation" and parse the output, but that's gross. So this - # should do; if the file is not there, the boot time will be - # returned as zero, and filelock.c already handles that. - [mingw32], [emacs_cv_boot_time_file=C:/pagefile.sys], - [*], [emacs_cv_boot_time_file=not-needed])]) - -AS_CASE([$emacs_cv_boot_time_file], - [/*|*:*], [BOOT_TIME_FILE=\"$emacs_cv_boot_time_file\"], - [not-needed], [BOOT_TIME_FILE=], - [# Guess systemd if unknown. - # If guess is wrong, Emacs falls back on something else. - BOOT_TIME_FILE=\"/var/lib/systemd/random-seed\"]) - -AS_IF([test -n "$BOOT_TIME_FILE"], - [AC_DEFINE_UNQUOTED([BOOT_TIME_FILE], [$BOOT_TIME_FILE], - [Name of file that, if it exists, postdates boot and predates - the first Emacs invocation; or a null pointer if no such file is known. - This file is used only on GNU/Linux and other systems - that lack the FreeBSD-style sysctl with KERN_BOOTTIME.])]) - #### Choose a window system. ## We leave window_system equal to none if diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h new file mode 100644 index 00000000000..348611fc85c --- /dev/null +++ b/lib/boot-time-aux.h @@ -0,0 +1,315 @@ +/* Auxiliary functions for determining the time when the machine last booted. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#define SIZEOF(a) (sizeof(a)/sizeof(a[0])) + +#if defined __linux__ || defined __ANDROID__ + +/* Store the uptime counter, as managed by the Linux kernel, in *P_UPTIME. + Return 0 upon success, -1 upon failure. */ +_GL_ATTRIBUTE_MAYBE_UNUSED +static int +get_linux_uptime (struct timespec *p_uptime) +{ + /* The clock_gettime facility returns the uptime with a resolution of 1 µsec. + It is available with glibc >= 2.14, Android, or musl libc. + In glibc < 2.17 it required linking with librt. */ +# if !defined __GLIBC__ || 2 < __GLIBC__ + (17 <= __GLIBC_MINOR__) + if (clock_gettime (CLOCK_BOOTTIME, p_uptime) >= 0) + return 0; +# endif + + /* /proc/uptime contains the uptime with a resolution of 0.01 sec. + But it does not have read permissions on Android. */ +# if !defined __ANDROID__ + FILE *fp = fopen ("/proc/uptime", "re"); + if (fp != NULL) + { + char buf[32 + 1]; + size_t n = fread (buf, 1, sizeof (buf) - 1, fp); + fclose (fp); + if (n > 0) + { + buf[n] = '\0'; + /* buf now contains two values: the uptime and the idle time. */ + time_t s = 0; + char *p; + for (p = buf; '0' <= *p && *p <= '9'; p++) + s = 10 * s + (*p - '0'); + if (buf < p) + { + long ns = 0; + if (*p++ == '.') + for (int i = 0; i < 9; i++) + ns = 10 * ns + ('0' <= *p && *p <= '9' ? *p++ - '0' : 0); + p_uptime->tv_sec = s; + p_uptime->tv_nsec = ns; + return 0; + } + } + } +# endif + + /* The sysinfo call returns the uptime with a resolution of 1 sec only. */ + struct sysinfo info; + if (sysinfo (&info) >= 0) + { + p_uptime->tv_sec = info.uptime; + p_uptime->tv_nsec = 0; + return 0; + } + + return -1; +} + +#endif + +#if defined __linux__ && !defined __ANDROID__ + +static int +get_linux_boot_time_fallback (struct timespec *p_boot_time) +{ + /* On Alpine Linux, UTMP_FILE is not filled. It is always empty. + So, get the time stamp of a file that gets touched only during the + boot process. */ + + const char * const boot_touched_files[] = + { + "/var/lib/systemd/random-seed", /* seen on distros with systemd */ + "/var/run/utmp", /* seen on distros with OpenRC */ + "/var/lib/random-seed" /* seen on older distros */ + }; + for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++) + { + const char *filename = boot_touched_files[i]; + struct stat statbuf; + if (stat (filename, &statbuf) >= 0) + { + *p_boot_time = get_stat_mtime (&statbuf); + return 0; + } + } + return -1; +} + +/* The following approach is only usable as a fallback, because it is of + the form + boot_time = (time now) - (kernel's ktime_get_boottime[_ts64] ()) + and therefore produces wrong values after the date has been bumped in the + running system, which happens frequently if the system is running in a + virtual machine and this VM has been put into "saved" or "sleep" state + and then resumed. */ +static int +get_linux_boot_time_final_fallback (struct timespec *p_boot_time) +{ + struct timespec uptime; + if (get_linux_uptime (&uptime) >= 0) + { + struct timespec result; +# if !defined __GLIBC__ || 2 < __GLIBC__ + (16 <= __GLIBC_MINOR__) + /* Better than: + if (0 <= clock_gettime (CLOCK_REALTIME, &result)) + because timespec_get does not need -lrt in glibc 2.16. + */ + if (! timespec_get (&result, TIME_UTC)) + return -1; +# else + /* Fall back on lower-res approach that does not need -lrt. + This is good enough; on these hosts UPTIME is even lower-res. */ + struct timeval tv; + int r = gettimeofday (&tv, NULL); + if (r < 0) + return r; + result.tv_sec = tv.tv_sec; + result.tv_nsec = tv.tv_usec * 1000; +# endif + + if (result.tv_nsec < uptime.tv_nsec) + { + result.tv_nsec += 1000000000; + result.tv_sec -= 1; + } + result.tv_sec -= uptime.tv_sec; + result.tv_nsec -= uptime.tv_nsec; + *p_boot_time = result; + return 0; + } + return -1; +} + +#endif + +#if defined __ANDROID__ + +static int +get_android_boot_time (struct timespec *p_boot_time) +{ + /* On Android, there is no /var, and normal processes don't have access + to system files. Therefore use the kernel's uptime counter, although + it produces wrong values after the date has been bumped in the running + system. */ + struct timespec uptime; + if (get_linux_uptime (&uptime) >= 0) + { + struct timespec result; + if (clock_gettime (CLOCK_REALTIME, &result) >= 0) + { + if (result.tv_nsec < uptime.tv_nsec) + { + result.tv_nsec += 1000000000; + result.tv_sec -= 1; + } + result.tv_sec -= uptime.tv_sec; + result.tv_nsec -= uptime.tv_nsec; + *p_boot_time = result; + return 0; + } + } + return -1; +} + +#endif + +#if defined __OpenBSD__ + +static int +get_openbsd_boot_time (struct timespec *p_boot_time) +{ + /* On OpenBSD, UTMP_FILE is not filled. It contains only dummy entries. + So, get the time stamp of a file that gets touched only during the + boot process. */ + const char * const boot_touched_files[] = + { + "/var/db/host.random", + "/var/run/utmp" + }; + for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++) + { + const char *filename = boot_touched_files[i]; + struct stat statbuf; + if (stat (filename, &statbuf) >= 0) + { + *p_boot_time = get_stat_mtime (&statbuf); + return 0; + } + } + return -1; +} + +#endif + +#if HAVE_SYS_SYSCTL_H && HAVE_SYSCTL \ + && defined CTL_KERN && defined KERN_BOOTTIME \ + && !defined __minix +/* macOS, FreeBSD, GNU/kFreeBSD, NetBSD, OpenBSD */ +/* On Minix 3.3 this sysctl produces garbage results. Therefore avoid it. */ + +/* The following approach is only usable as a fallback, because it produces + wrong values after the date has been bumped in the running system, which + happens frequently if the system is running in a virtual machine and this + VM has been put into "saved" or "sleep" state and then resumed. */ +static int +get_bsd_boot_time_final_fallback (struct timespec *p_boot_time) +{ + static int request[2] = { CTL_KERN, KERN_BOOTTIME }; + struct timeval result; + size_t result_len = sizeof result; + + if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0) + { + p_boot_time->tv_sec = result.tv_sec; + p_boot_time->tv_nsec = result.tv_usec * 1000; + return 0; + } + return -1; +} + +#endif + +#if defined __HAIKU__ + +static int +get_haiku_boot_time (struct timespec *p_boot_time) +{ + /* On Haiku, /etc/utmp does not exist. During boot, + 1. the current time is restored, but possibly with a wrong time zone, + that is, with an offset of a few hours, + 2. some symlinks and files get created, + 3. the various devices are brought up, in particular the network device, + 4. the correct date and time is set, + 5. some more device nodes get created. + The boot time can be retrieved by looking at a directory created during + phase 5, such as /dev/input. */ + const char * const boot_touched_file = "/dev/input"; + struct stat statbuf; + if (stat (boot_touched_file, &statbuf) >= 0) + { + *p_boot_time = get_stat_mtime (&statbuf); + return 0; + } + return -1; +} + +#endif + +#if HAVE_OS_H /* BeOS, Haiku */ + +/* The following approach is only usable as a fallback, because it produces + wrong values after the date has been bumped in the running system, which + happens frequently if the system is running in a virtual machine and this + VM has been put into "saved" or "sleep" state and then resumed. */ +static int +get_haiku_boot_time_final_fallback (struct timespec *p_boot_time) +{ + system_info si; + + get_system_info (&si); + p_boot_time->tv_sec = si.boot_time / 1000000; + p_boot_time->tv_nsec = (si.boot_time % 1000000) * 1000; + return 0; +} + +#endif + +#if defined __CYGWIN__ || defined _WIN32 + +static int +get_windows_boot_time (struct timespec *p_boot_time) +{ + /* On Cygwin, /var/run/utmp is empty. + On native Windows, <utmpx.h> and <utmp.h> don't exist. + Instead, on Windows, the boot time can be retrieved by looking at the + time stamp of a file that (normally) gets touched only during the boot + process, namely C:\pagefile.sys. */ + const char * const boot_touched_file = + #if defined __CYGWIN__ && !defined _WIN32 + "/cygdrive/c/pagefile.sys" + #else + "C:\\pagefile.sys" + #endif + ; + struct stat statbuf; + if (stat (boot_touched_file, &statbuf) >= 0) + { + *p_boot_time = get_stat_mtime (&statbuf); + return 0; + } + return -1; +} + +#endif diff --git a/lib/boot-time.c b/lib/boot-time.c new file mode 100644 index 00000000000..d813bfa5825 --- /dev/null +++ b/lib/boot-time.c @@ -0,0 +1,285 @@ +/* Determine the time when the machine last booted. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#include <config.h> + +/* Specification. */ +#include "boot-time.h" + +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +#if defined __linux__ || defined __ANDROID__ +# include <sys/sysinfo.h> +# include <time.h> +#endif + +#if HAVE_SYS_SYSCTL_H && !defined __minix +# if HAVE_SYS_PARAM_H +# include <sys/param.h> +# endif +# include <sys/sysctl.h> +#endif + +#if HAVE_OS_H +# include <OS.h> +#endif + +#include "idx.h" +#include "readutmp.h" +#include "stat-time.h" + +/* Each of the FILE streams in this file is only used in a single thread. */ +#include "unlocked-io.h" + +/* Some helper functions. */ +#include "boot-time-aux.h" + +/* The following macros describe the 'struct UTMP_STRUCT_NAME', + *not* 'struct gl_utmp'. */ +#undef UT_USER + +/* Accessor macro for the member named ut_user or ut_name. */ +#if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_NAME \ + : HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_NAME) +# define UT_USER(UT) ((UT)->ut_name) +#else +# define UT_USER(UT) ((UT)->ut_user) +#endif + +#if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION && !HAVE_DECL_GETUTENT +struct utmp *getutent (void); +#endif + +#if defined __linux__ || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || defined _WIN32 + +static int +get_boot_time_uncached (struct timespec *p_boot_time) +{ + struct timespec found_boot_time = {0}; + +# if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) + + /* Try to find the boot time in the /var/run/utmp file. */ + +# if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, IRIX, Solaris, Cygwin, Android */ + + /* Ignore the return value for now. + Solaris' utmpname returns 1 upon success -- which is contrary + to what the GNU libc version does. In addition, older GNU libc + versions are actually void. */ + UTMP_NAME_FUNCTION ((char *) UTMP_FILE); + + SET_UTMP_ENT (); + +# if (defined __linux__ && !defined __ANDROID__) || defined __minix + /* Timestamp of the "runlevel" entry, if any. */ + struct timespec runlevel_ts = {0}; +# endif + + void const *entry; + + while ((entry = GET_UTMP_ENT ()) != NULL) + { + struct UTMP_STRUCT_NAME const *ut = (struct UTMP_STRUCT_NAME const *) entry; + + struct timespec ts = + #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV) + { .tv_sec = ut->ut_tv.tv_sec, .tv_nsec = ut->ut_tv.tv_usec * 1000 }; + #else + { .tv_sec = ut->ut_time, .tv_nsec = 0 }; + #endif + + if (ut->ut_type == BOOT_TIME) + found_boot_time = ts; + +# if defined __linux__ && !defined __ANDROID__ + if (memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0 + && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0) + runlevel_ts = ts; +# endif +# if defined __minix + if (UT_USER (ut)[0] == '\0' + && memcmp (ut->ut_line, "run-level ", strlen ("run-level ")) == 0) + runlevel_ts = ts; +# endif + } + + END_UTMP_ENT (); + +# if defined __linux__ && !defined __ANDROID__ + /* On Raspbian, which runs on hardware without a real-time clock, during boot, + 1. the clock gets set to 1970-01-01 00:00:00, + 2. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME, + ut_user = "reboot", ut_line = "~", time = 1970-01-01 00:00:05 or so, + 3. the clock gets set to a correct value through NTP, + 4. an entry gets written into /var/run/utmp, with + ut_user = "runlevel", ut_line = "~", time = correct value. + In this case, get the time from the "runlevel" entry. */ + + /* Workaround for Raspbian: */ + if (found_boot_time.tv_sec <= 60 && runlevel_ts.tv_sec != 0) + found_boot_time = runlevel_ts; + if (found_boot_time.tv_sec == 0) + { + /* Workaround for Alpine Linux: */ + get_linux_boot_time_fallback (&found_boot_time); + } +# endif + +# if defined __ANDROID__ + if (found_boot_time.tv_sec == 0) + { + /* Workaround for Android: */ + get_android_boot_time (&found_boot_time); + } +# endif + +# if defined __minix + /* On Minix, during boot, + 1. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME, + ut_user = "", ut_line = "system boot", time = 1970-01-01 00:00:00, + 2. an entry gets written into /var/run/utmp, with + ut_user = "", ut_line = "run-level m", time = correct value. + In this case, copy the time from the "run-level m" entry to the + "system boot" entry. */ + if (found_boot_time.tv_sec <= 60 && runlevel_ts.tv_sec != 0) + found_boot_time = runlevel_ts; +# endif + +# else /* HP-UX, Haiku */ + + FILE *f = fopen (UTMP_FILE, "re"); + + if (f != NULL) + { + for (;;) + { + struct UTMP_STRUCT_NAME ut; + + if (fread (&ut, sizeof ut, 1, f) == 0) + break; + + struct timespec ts = + #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV) + { .tv_sec = ut.ut_tv.tv_sec, .tv_nsec = ut.ut_tv.tv_usec * 1000 }; + #else + { .tv_sec = ut.ut_time, .tv_nsec = 0 }; + #endif + + if (ut.ut_type == BOOT_TIME) + found_boot_time = ts; + } + + fclose (f); + } + +# endif + +# if defined __linux__ && !defined __ANDROID__ + if (found_boot_time.tv_sec == 0) + { + get_linux_boot_time_final_fallback (&found_boot_time); + } +# endif + +# else /* old FreeBSD, OpenBSD, native Windows */ + +# if defined __OpenBSD__ + /* Workaround for OpenBSD: */ + get_openbsd_boot_time (&found_boot_time); +# endif + +# endif + +# if HAVE_SYS_SYSCTL_H && HAVE_SYSCTL \ + && defined CTL_KERN && defined KERN_BOOTTIME \ + && !defined __minix + if (found_boot_time.tv_sec == 0) + { + get_bsd_boot_time_final_fallback (&found_boot_time); + } +# endif + +# if defined __HAIKU__ + if (found_boot_time.tv_sec == 0) + { + get_haiku_boot_time (&found_boot_time); + } +# endif + +# if HAVE_OS_H + if (found_boot_time.tv_sec == 0) + { + get_haiku_boot_time_final_fallback (&found_boot_time); + } +# endif + +# if defined __CYGWIN__ || defined _WIN32 + if (found_boot_time.tv_sec == 0) + { + /* Workaround for Windows: */ + get_windows_boot_time (&found_boot_time); + } +# endif + + if (found_boot_time.tv_sec != 0) + { + *p_boot_time = found_boot_time; + return 0; + } + else + return -1; +} + +int +get_boot_time (struct timespec *p_boot_time) +{ + /* Cache the result from get_boot_time_uncached. */ + static int volatile cached_result = -1; + static struct timespec volatile cached_boot_time; + + if (cached_result < 0) + { + struct timespec boot_time; + int result = get_boot_time_uncached (&boot_time); + cached_boot_time = boot_time; + cached_result = result; + } + + if (cached_result == 0) + { + *p_boot_time = cached_boot_time; + return 0; + } + else + return -1; +} + +#else + +int +get_boot_time (struct timespec *p_boot_time) +{ + return -1; +} + +#endif diff --git a/lib/boot-time.h b/lib/boot-time.h new file mode 100644 index 00000000000..401e854adbb --- /dev/null +++ b/lib/boot-time.h @@ -0,0 +1,44 @@ +/* Determine the time when the machine last booted. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>. */ + +#ifndef _BOOT_TIME_H +#define _BOOT_TIME_H + +#include <time.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Store the approximate time when the machine last booted in *P_BOOT_TIME, + and return 0. If it cannot be determined, return -1. + + This function is not multithread-safe, since on many platforms it + invokes the functions setutxent, getutxent, endutxent. These + functions are needed because they may lock FILE (so that we don't + read garbage when a concurrent process writes to FILE), but their + drawback is that they have a common global state. */ +extern int get_boot_time (struct timespec *p_boot_time); + + +#ifdef __cplusplus +} +#endif + +#endif /* _BOOT_TIME_H */ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 785bdc70c5c..3b33f39f73b 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -76,6 +76,7 @@ # alignasof \ # alloca-opt \ # binary-io \ +# boot-time \ # byteswap \ # c-ctype \ # c-strcase \ @@ -1601,6 +1602,16 @@ libgnu_a_SOURCES += binary-io.h binary-io.c endif ## end gnulib module binary-io +## begin gnulib module boot-time +ifeq (,$(OMIT_GNULIB_MODULE_boot-time)) + +libgnu_a_SOURCES += boot-time.c + +EXTRA_DIST += boot-time-aux.h boot-time.h readutmp.h + +endif +## end gnulib module boot-time + ## begin gnulib module byteswap ifeq (,$(OMIT_GNULIB_MODULE_byteswap)) diff --git a/lib/readutmp.h b/lib/readutmp.h new file mode 100644 index 00000000000..1cf588d265b --- /dev/null +++ b/lib/readutmp.h @@ -0,0 +1,325 @@ +/* Declarations for GNU's read utmp module. + + Copyright (C) 1992-2007, 2009-2023 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by jla; revised by djm */ + +#ifndef __READUTMP_H__ +#define __READUTMP_H__ + +/* This file uses _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_RETURNS_NONNULL, + HAVE_UTMP_H, HAVE_UTMPX_H, HAVE_STRUCT_UTMP_*, HAVE_STRUCT_UTMPX_*, + HAVE_UTMPNAME, HAVE_UTMPXNAME. */ +#if !_GL_CONFIG_H_INCLUDED +# error "Please include config.h first." +#endif + +#include "idx.h" + +#include <stdlib.h> +#include <sys/types.h> +#include <time.h> + +/* AIX 4.3.3 has both utmp.h and utmpx.h, but only struct utmp + has the ut_exit member. */ +#if (HAVE_UTMPX_H && HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_EXIT \ + && ! HAVE_STRUCT_UTMPX_UT_EXIT) +# undef HAVE_UTMPX_H +#endif + +/* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE. */ +#if HAVE_UTMP_H +# include <utmp.h> +#endif + +/* Needed for BOOT_TIME and USER_PROCESS. */ +#if HAVE_UTMPX_H +# if defined _THREAD_SAFE && defined UTMP_DATA_INIT + /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE + defined, work around the duplicate struct utmp_data declaration. */ +# define utmp_data gl_aix_4_3_workaround_utmp_data +# endif +# include <utmpx.h> +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Type of entries returned by read_utmp on all platforms. */ +struct gl_utmp +{ + /* All 'char *' here are of arbitrary length and point to storage + with lifetime equal to that of this struct. */ + char *ut_user; /* User name */ + char *ut_id; /* Session ID */ + char *ut_line; /* seat / device */ + char *ut_host; /* for remote sessions: user@host or host, + for local sessions: the X11 display :N */ + struct timespec ut_ts; /* time */ + pid_t ut_pid; /* process ID of ? */ + pid_t ut_session; /* process ID of session leader */ + short ut_type; /* BOOT_TIME, USER_PROCESS, or other */ + struct { int e_termination; int e_exit; } ut_exit; +}; + +/* The following types, macros, and constants describe the 'struct gl_utmp'. */ +#define UT_USER(UT) ((UT)->ut_user) +#define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec) +#define UT_PID(UT) ((UT)->ut_pid) +#define UT_TYPE_EQ(UT, V) ((UT)->ut_type == (V)) +#define UT_TYPE_NOT_DEFINED 0 +#define UT_EXIT_E_TERMINATION(UT) ((UT)->ut_exit.e_termination) +#define UT_EXIT_E_EXIT(UT) ((UT)->ut_exit.e_exit) + +/* Type of entry returned by read_utmp(). */ +typedef struct gl_utmp STRUCT_UTMP; + +/* Size of the UT_USER (ut) member, or -1 if unbounded. */ +enum { UT_USER_SIZE = -1 }; + +/* Size of the ut->ut_id member, or -1 if unbounded. */ +enum { UT_ID_SIZE = -1 }; + +/* Size of the ut->ut_line member, or -1 if unbounded. */ +enum { UT_LINE_SIZE = -1 }; + +/* Size of the ut->ut_host member, or -1 if unbounded. */ +enum { UT_HOST_SIZE = -1 }; + + +/* When read_utmp accesses a file (as opposed to fetching the information + from systemd), it uses the following low-level types and macros. + Keep them here, rather than moving them into readutmp.c, for backward + compatibility. */ + +#if HAVE_UTMPX_H + +/* <utmpx.h> defines 'struct utmpx' with the following fields: + + Field Type Platforms + ---------- ------ --------- + ⎡ ut_user char[] glibc, musl, macOS, FreeBSD, AIX, HP-UX, IRIX, Solaris, Cygwin + ⎣ ut_name char[] NetBSD, Minix + ut_id char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ut_line char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ut_pid pid_t glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ut_type short glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ⎡ ut_tv struct glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ⎢ { tv_sec; tv_usec; } + ⎣ ut_time time_t Cygwin + ut_host char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ut_exit struct glibc, musl, NetBSD, Minix, HP-UX, IRIX, Solaris + { e_termination; e_exit; } + ut_session [long] int glibc, musl, NetBSD, Minix, IRIX, Solaris + ⎡ ut_addr [long] int HP-UX, Cygwin + ⎢ ut_addr_v6 [u]int[4] glibc, musl + ⎣ ut_ss struct sockaddr_storage NetBSD, Minix + */ + +# if __GLIBC__ && _TIME_BITS == 64 +/* This is a near-copy of glibc's struct utmpx, which stops working + after the year 2038. Unlike the glibc version, struct utmpx32 + describes the file format even if time_t is 64 bits. */ +struct utmpx32 +{ + short int ut_type; /* Type of login. */ + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[__UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[__UT_USERSIZE]; /* Username. */ + char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ + struct __exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + /* The fields ut_session and ut_tv must be the same size when compiled + 32- and 64-bit. This allows files and shared memory to be shared + between 32- and 64-bit applications. */ + int ut_session; /* Session ID, used for windowing. */ + struct + { + /* Seconds. Unsigned not signed, as glibc did not exist before 1970, + and if the format is still in use after 2038 its timestamps + will surely have the sign bit on. This hack stops working + at 2106-02-07 06:28:16 UTC. */ + unsigned int tv_sec; + int tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ + int ut_addr_v6[4]; /* Internet address of remote host. */ + char ut_reserved[20]; /* Reserved for future use. */ +}; +# define UTMP_STRUCT_NAME utmpx32 +# else +# define UTMP_STRUCT_NAME utmpx +# endif +# define SET_UTMP_ENT setutxent +# define GET_UTMP_ENT getutxent +# define END_UTMP_ENT endutxent +# ifdef HAVE_UTMPXNAME /* glibc, musl, macOS, NetBSD, Minix, IRIX, Solaris, Cygwin */ +# define UTMP_NAME_FUNCTION utmpxname +# elif defined UTXDB_ACTIVE /* FreeBSD */ +# define UTMP_NAME_FUNCTION(x) setutxdb (UTXDB_ACTIVE, x) +# endif + +#elif HAVE_UTMP_H + +/* <utmp.h> defines 'struct utmp' with the following fields: + + Field Type Platforms + ---------- ------ --------- + ⎡ ut_user char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ⎣ ut_name char[] macOS, old FreeBSD, NetBSD, OpenBSD, Minix + ut_id char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ut_line char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ut_pid pid_t glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ut_type short glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ⎡ ut_tv struct glibc, musl, Android + ⎢ { tv_sec; tv_usec; } + ⎣ ut_time time_t macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ut_host char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Cygwin, Android + ut_exit struct glibc, musl, AIX, HP-UX, IRIX, Solaris, Android + { e_termination; e_exit; } + ut_session [long] int glibc, musl, Android + ⎡ ut_addr [long] int HP-UX, Cygwin + ⎣ ut_addr_v6 [u]int[4] glibc, musl, Android + */ + +# define UTMP_STRUCT_NAME utmp +# define SET_UTMP_ENT setutent +# define GET_UTMP_ENT getutent +# define END_UTMP_ENT endutent +# ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android */ +# define UTMP_NAME_FUNCTION utmpname +# endif + +#endif + +/* Evaluates to 1 if gl_utmp's ut_id field may ever have a non-zero value. */ +#define HAVE_STRUCT_XTMP_UT_ID \ + (READUTMP_USE_SYSTEMD \ + || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID)) + +/* Evaluates to 1 if gl_utmp's ut_pid field may ever have a non-zero value. */ +#define HAVE_STRUCT_XTMP_UT_PID \ + (READUTMP_USE_SYSTEMD \ + || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_PID : HAVE_STRUCT_UTMP_UT_PID)) + +/* Evaluates to 1 if gl_utmp's ut_host field may ever be non-empty. */ +#define HAVE_STRUCT_XTMP_UT_HOST \ + (READUTMP_USE_SYSTEMD \ + || (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_HOST : HAVE_STRUCT_UTMP_UT_HOST)) + +/* Definition of UTMP_FILE. + On glibc systems, UTMP_FILE is "/var/run/utmp". */ +#if !defined UTMP_FILE && defined _PATH_UTMP +# define UTMP_FILE _PATH_UTMP +#endif +#ifdef UTMPX_FILE /* Solaris, SysVr4 */ +# undef UTMP_FILE +# define UTMP_FILE UTMPX_FILE +#endif +#ifndef UTMP_FILE +# define UTMP_FILE "/etc/utmp" +#endif + +/* Definition of WTMP_FILE. + On glibc systems, UTMP_FILE is "/var/log/wtmp". */ +#if !defined WTMP_FILE && defined _PATH_WTMP +# define WTMP_FILE _PATH_WTMP +#endif +#ifdef WTMPX_FILE /* Solaris, SysVr4 */ +# undef WTMP_FILE +# define WTMP_FILE WTMPX_FILE +#endif +#ifndef WTMP_FILE +# define WTMP_FILE "/etc/wtmp" +#endif + +/* Some platforms, such as OpenBSD, don't have an ut_type field and don't have + the BOOT_TIME and USER_PROCESS macros. But we want to support them in + 'struct gl_utmp'. */ +#if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) +# define BOOT_TIME 2 +# define USER_PROCESS 0 +#endif + +/* Macros that test (UT)->ut_type. */ +#ifdef BOOT_TIME +# define UT_TYPE_BOOT_TIME(UT) UT_TYPE_EQ (UT, BOOT_TIME) +#else +# define UT_TYPE_BOOT_TIME(UT) 0 +#endif +#ifdef USER_PROCESS +# define UT_TYPE_USER_PROCESS(UT) UT_TYPE_EQ (UT, USER_PROCESS) +#else +# define UT_TYPE_USER_PROCESS(UT) 0 +#endif + +/* Determines whether an entry *UT corresponds to a user process. */ +#define IS_USER_PROCESS(UT) \ + (UT_USER (UT)[0] \ + && (UT_TYPE_USER_PROCESS (UT) \ + || (UT_TYPE_NOT_DEFINED && UT_TIME_MEMBER (UT) != 0))) + +/* Define if read_utmp is not just a dummy. */ +#if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || defined _WIN32 +# define READ_UTMP_SUPPORTED 1 +#endif + +/* Options for read_utmp. */ +enum + { + READ_UTMP_CHECK_PIDS = 1, + READ_UTMP_USER_PROCESS = 2, + READ_UTMP_BOOT_TIME = 4, + READ_UTMP_NO_BOOT_TIME = 8 + }; + +/* Return a copy of (UT)->ut_user, without trailing spaces, + as a freshly allocated string. */ +char *extract_trimmed_name (const STRUCT_UTMP *ut) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Read the utmp entries corresponding to file FILE into freshly- + malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to + the number of entries, and return zero. If there is any error, + return -1, setting errno, and don't modify the parameters. + A good candidate for FILE is UTMP_FILE. + If OPTIONS & READ_UTMP_CHECK_PIDS is nonzero, omit entries whose + process-IDs do not currently exist. + If OPTIONS & READ_UTMP_USER_PROCESS is nonzero, omit entries which + do not correspond to a user process. + If OPTIONS & READ_UTMP_BOOT_TIME is nonzero, omit all entries except + the one that contains the boot time. + If OPTIONS & READ_UTMP_NO_BOOT_TIME is nonzero, omit the boot time + entries. + + This function is not multithread-safe, since on many platforms it + invokes the functions setutxent, getutxent, endutxent. These + functions are needed because they may lock FILE (so that we don't + read garbage when a concurrent process writes to FILE), but their + drawback is that they have a common global state. */ +int read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, + int options); + + +#ifdef __cplusplus +} +#endif + +#endif /* __READUTMP_H__ */ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 3382e9bc241..14ff92040a4 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -51,6 +51,7 @@ AC_DEFUN # Code from module at-internal: # Code from module attribute: # Code from module binary-io: + # Code from module boot-time: # Code from module builtin-expect: # Code from module byteswap: # Code from module c-ctype: @@ -243,6 +244,7 @@ AC_DEFUN gl_ASSERT_H gl_CONDITIONAL_HEADER([assert.h]) AC_PROG_MKDIR_P + gl_PREREQ_READUTMP_H gl___BUILTIN_EXPECT gl_BYTESWAP gl_CONDITIONAL_HEADER([byteswap.h]) @@ -1252,6 +1254,9 @@ AC_DEFUN lib/attribute.h lib/binary-io.c lib/binary-io.h + lib/boot-time-aux.h + lib/boot-time.c + lib/boot-time.h lib/byteswap.in.h lib/c++defs.h lib/c-ctype.c @@ -1383,6 +1388,7 @@ AC_DEFUN lib/rawmemchr.valgrind lib/readlink.c lib/readlinkat.c + lib/readutmp.h lib/realloc.c lib/regcomp.c lib/regex.c @@ -1542,6 +1548,7 @@ AC_DEFUN m4/rawmemchr.m4 m4/readlink.m4 m4/readlinkat.m4 + m4/readutmp.m4 m4/realloc.m4 m4/regex.m4 m4/sha1.m4 diff --git a/m4/readutmp.m4 b/m4/readutmp.m4 new file mode 100644 index 00000000000..fff8d4eb7bf --- /dev/null +++ b/m4/readutmp.m4 @@ -0,0 +1,117 @@ +# readutmp.m4 serial 28 +dnl Copyright (C) 2002-2023 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_READUTMP], +[ + AC_REQUIRE([gl_SYSTEMD_CHOICE]) + + dnl Set READUTMP_LIB to '-lsystemd' or '', depending on whether use of + dnl systemd APIs is possible and desired (only the systemd login API, here). + dnl AC_LIB_LINKFLAGS_BODY would be overkill here, since few people install + dnl libsystemd in non-system directories. + READUTMP_LIB= + if test "$SYSTEMD_CHOICE" = yes; then + AC_CHECK_HEADER([systemd/sd-login.h]) + if test $ac_cv_header_systemd_sd_login_h = yes; then + AC_CACHE_CHECK([for libsystemd version >= 254], + [gl_cv_lib_readutmp_systemd], + [gl_save_LIBS="$LIBS" + LIBS="$LIBS -lsystemd" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include <stdint.h> + #include <systemd/sd-login.h> + ]], [[ + uint64_t st; + sd_session_get_start_time ("1", &st); + ]]) + ], + [gl_cv_lib_readutmp_systemd=yes], + [gl_cv_lib_readutmp_systemd=no]) + LIBS="$gl_save_LIBS" + ]) + if test $gl_cv_lib_readutmp_systemd = yes; then + AC_DEFINE([READUTMP_USE_SYSTEMD], [1], + [Define if the readutmp module should use the systemd login API.]) + READUTMP_LIB='-lsystemd' + fi + fi + fi + AC_SUBST([READUTMP_LIB]) + + gl_PREREQ_READUTMP_H +]) + +# Prerequisites of readutmp.h and boot-time-aux.h. +AC_DEFUN_ONCE([gl_PREREQ_READUTMP_H], +[ + dnl Persuade utmpx.h to declare utmpxname + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_HEADERS_ONCE([utmp.h utmpx.h]) + if test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes; then + dnl Prerequisites of lib/readutmp.h and lib/readutmp.c. + AC_CHECK_FUNCS_ONCE([utmpname utmpxname]) + AC_CHECK_DECLS([getutent],,,[[ +/* <sys/types.h> is a prerequisite of <utmp.h> on FreeBSD 8.0, OpenBSD 4.6. */ +#include <sys/types.h> +#ifdef HAVE_UTMP_H +# include <utmp.h> +#endif +]]) + utmp_includes="\ +AC_INCLUDES_DEFAULT +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +#ifdef HAVE_UTMP_H +# if defined _THREAD_SAFE && defined UTMP_DATA_INIT + /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE + defined, work around the duplicate struct utmp_data declaration. */ +# define utmp_data gl_aix_4_3_workaround_utmp_data +# endif +# include <utmp.h> +#endif +" + AC_CHECK_MEMBERS([struct utmpx.ut_user],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_user],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_name],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_name],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_type],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_type],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_pid],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_pid],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_tv],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_host],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_host],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_id],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_id],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_session],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_session],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_exit],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_exit],,,[$utmp_includes]) + + AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_exit],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_exit],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_exit.e_exit],,,[$utmp_includes]) + + AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_termination],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_termination],,,[$utmp_includes]) + AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination],,,[$utmp_includes]) + fi + + AC_CHECK_HEADERS_ONCE([sys/param.h]) + dnl <sys/sysctl.h> requires <sys/param.h> on OpenBSD 4.0. + AC_CHECK_HEADERS([sys/sysctl.h],,, + [AC_INCLUDES_DEFAULT + #if HAVE_SYS_PARAM_H + # include <sys/param.h> + #endif + ]) + AC_CHECK_FUNCS([sysctl]) + + AC_CHECK_HEADERS_ONCE([OS.h]) +]) diff --git a/src/filelock.c b/src/filelock.c index 3b1ff8ad566..d2161f1e58a 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -36,13 +36,9 @@ Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2023 Free Software #include <sys/file.h> #include <fcntl.h> #include <unistd.h> - -#ifdef __FreeBSD__ -#include <sys/sysctl.h> -#endif /* __FreeBSD__ */ - #include <errno.h> +#include <boot-time.h> #include <c-ctype.h> #include "lisp.h" @@ -55,20 +51,6 @@ Copyright (C) 1985-1987, 1993-1994, 1996, 1998-2023 Free Software #ifndef MSDOS -#ifdef HAVE_UTMP_H -#include <utmp.h> -#endif - -/* Boot time is not available on Android. */ - -#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY -#undef BOOT_TIME -#endif - -#if !defined WTMP_FILE && !defined WINDOWSNT && defined BOOT_TIME -#define WTMP_FILE "/var/log/wtmp" -#endif - #ifdef HAVE_ANDROID #include "android.h" /* For `android_is_special_directory'. */ #endif /* HAVE_ANDROID */ @@ -127,153 +109,19 @@ #define WTMP_FILE "/var/log/wtmp" \f /* Return the time of the last system boot. */ -static time_t boot_time; -static bool boot_time_initialized; - -#ifdef BOOT_TIME -static void get_boot_time_1 (const char *, bool); -#endif - static time_t -get_boot_time (void) +get_boot_sec (void) { - if (boot_time_initialized) - return boot_time; - boot_time_initialized = 1; - -#if defined (CTL_KERN) && defined (KERN_BOOTTIME) - { - int mib[2]; - size_t size; - struct timeval boottime_val; - - mib[0] = CTL_KERN; - mib[1] = KERN_BOOTTIME; - size = sizeof (boottime_val); - - if (sysctl (mib, 2, &boottime_val, &size, NULL, 0) >= 0 && size != 0) - { - boot_time = boottime_val.tv_sec; - return boot_time; - } - } -#endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */ - -#ifdef BOOT_TIME_FILE - { - struct stat st; - if (stat (BOOT_TIME_FILE, &st) == 0) - { - boot_time = st.st_mtime; - return boot_time; - } - } -#endif /* BOOT_TIME_FILE */ - -#if defined (BOOT_TIME) - /* The utmp routines maintain static state. Don't touch that state + /* get_boot_time maintains static state. Don't touch that state if we are going to dump, since it might not survive dumping. */ if (will_dump_p ()) - return boot_time; - - /* Try to get boot time from utmp before wtmp, - since utmp is typically much smaller than wtmp. - Passing a null pointer causes get_boot_time_1 - to inspect the default file, namely utmp. */ - get_boot_time_1 (0, 0); - if (boot_time) - return boot_time; - - /* Try to get boot time from the current wtmp file. */ - get_boot_time_1 (WTMP_FILE, 1); - - /* If we did not find a boot time in wtmp, look at wtmp.1, - wtmp.1.gz, wtmp.2, wtmp.2.gz, and so on. */ - for (int counter = 0; counter < 20 && ! boot_time; counter++) - { - Lisp_Object filename = Qnil; - bool delete_flag = false; - char cmd_string[sizeof WTMP_FILE ".19.gz"]; - AUTO_STRING_WITH_LEN (tempname, cmd_string, - sprintf (cmd_string, "%s.%d", WTMP_FILE, counter)); - if (! NILP (Ffile_exists_p (tempname))) - filename = tempname; - else - { - tempname = make_formatted_string (cmd_string, "%s.%d.gz", - WTMP_FILE, counter); - if (! NILP (Ffile_exists_p (tempname))) - { - /* The utmp functions on older systems accept only file - names up to 8 bytes long. Choose a 2 byte prefix, so - the 6-byte suffix does not make the name too long. */ - filename = Fmake_temp_file_internal (build_string ("wt"), Qnil, - empty_unibyte_string, Qnil); - CALLN (Fcall_process, build_string ("gzip"), Qnil, - list2 (QCfile, filename), Qnil, - build_string ("-cd"), tempname); - delete_flag = true; - } - } - - if (! NILP (filename)) - { - get_boot_time_1 (SSDATA (filename), 1); - if (delete_flag) - emacs_unlink (SSDATA (filename)); - } - } - - return boot_time; -#else - return 0; -#endif -} + return 0; -#ifdef BOOT_TIME -/* Try to get the boot time from wtmp file FILENAME. - This succeeds if that file contains a reboot record. - - If FILENAME is zero, use the same file as before; - if no FILENAME has ever been specified, this is the utmp file. - Use the newest reboot record if NEWEST, - the first reboot record otherwise. - Ignore all reboot records on or before BOOT_TIME. - Success is indicated by setting BOOT_TIME to a larger value. */ - -void -get_boot_time_1 (const char *filename, bool newest) -{ - struct utmp ut, *utp; - - if (filename) - utmpname (filename); - - setutent (); - - while (1) - { - /* Find the next reboot record. */ - ut.ut_type = BOOT_TIME; - utp = getutid (&ut); - if (! utp) - break; - /* Compare reboot times and use the newest one. */ - if (utp->ut_time > boot_time) - { - boot_time = utp->ut_time; - if (! newest) - break; - } - /* Advance on element in the file - so that getutid won't repeat the same one. */ - utp = getutent (); - if (! utp) - break; - } - endutent (); + struct timespec boot_time; + boot_time.tv_sec = 0; + get_boot_time (&boot_time); + return boot_time.tv_sec; } -#endif /* BOOT_TIME */ \f /* An arbitrary limit on lock contents length. 8 K should be plenty big enough in practice. */ @@ -418,7 +266,7 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) static int lock_file_1 (Lisp_Object lfname, bool force) { - intmax_t boot = get_boot_time (); + intmax_t boot = get_boot_sec (); Lisp_Object luser_name = Fuser_login_name (Qnil); Lisp_Object lhost_name = Fsystem_name (); @@ -604,7 +452,7 @@ current_lock_owner (lock_info_type *owner, Lisp_Object lfname) && (kill (pid, 0) >= 0 || errno == EPERM) && (boot_time == 0 || (boot_time <= TYPE_MAXIMUM (time_t) - && within_one_second (boot_time, get_boot_time ())))) + && within_one_second (boot_time, get_boot_sec ())))) return ANOTHER_OWNS_IT; /* The owner process is dead or has a strange pid, so try to zap the lockfile. */ -- 2.39.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 2:49 ` boot-time: straighten code Paul Eggert @ 2023-08-13 3:26 ` Po Lu 2023-08-13 6:35 ` Paul Eggert ` (3 more replies) 2023-08-14 8:02 ` boot-time: straighten code Andreas Schwab 2023-08-15 21:12 ` Bruno Haible 2 siblings, 4 replies; 24+ messages in thread From: Po Lu @ 2023-08-13 3:26 UTC (permalink / raw) To: Paul Eggert; +Cc: Bruno Haible, bug-gnulib, Emacs Development Paul Eggert <eggert@cs.ucla.edu> writes: > On 2023-08-11 14:49, Bruno Haible wrote: >> Paul: With this simplification, you may consider using the 'boot-time' module >> in Emacs. I bet that it produces a better result than Emacs' src/filelock.c >> on many platforms. (I haven't tested it, but I could test it if you give me >> a manual testing recipe.) > > Thanks for doing all that. I installed the attached patch into Emacs > master, which you should be able to test via: > > git clone https://git.savannah.gnu.org/git/emacs.git > cd emacs > ./autogen.sh > ./configure > make > src/emacs > > Please give it a try, especially on any MS-Windows platform you happen > to have. I have tested only on Ubuntu 23.04 so far. > > A simple way to test is to use Emacs to start editing a file (without > saving) and then inspect the symbolic link .#* that Emacs uses as a > lock file. The trailing digits of that link's contents should be the > boot time. These symlinks are Emacs's only use of boot time. During the automated build of the Android port, the following errors were encountered with the Android NDK r10b and __ANDROID_API__ set to 8 (which is the oldest configuration Emacs supports.) Bruno, would you please investigate this? In file included from boot-time.c:54:0: boot-time-aux.h: In function 'get_linux_uptime': boot-time-aux.h:70:3: error: implicit declaration of function 'sysinfo' [-Werror=implicit-function-declaration] if (sysinfo (&info) >= 0) ^ boot-time.c: In function 'get_boot_time_uncached': boot-time.c:111:26: error: 'BOOT_TIME' undeclared (first use in this function) if (ut->ut_type == BOOT_TIME) ^ boot-time.c:111:26: note: each undeclared identifier is reported only once for each function it appears in boot-time.c:126:3: error: implicit declaration of function 'endutent' [-Werror=implicit-function-declaration] END_UTMP_ENT (); ^ cc1: some warnings being treated as errors ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 3:26 ` Po Lu @ 2023-08-13 6:35 ` Paul Eggert 2023-08-13 13:45 ` Bruno Haible ` (2 subsequent siblings) 3 siblings, 0 replies; 24+ messages in thread From: Paul Eggert @ 2023-08-13 6:35 UTC (permalink / raw) To: Po Lu; +Cc: Bruno Haible, bug-gnulib, Emacs Development [-- Attachment #1: Type: text/plain, Size: 1224 bytes --] On 2023-08-12 20:26, Po Lu wrote: > In file included from boot-time.c:54:0: > boot-time-aux.h: In function 'get_linux_uptime': > boot-time-aux.h:70:3: error: implicit declaration of function 'sysinfo' [-Werror=implicit-function-declaration] > if (sysinfo (&info) >= 0) > ^ > boot-time.c: In function 'get_boot_time_uncached': > boot-time.c:111:26: error: 'BOOT_TIME' undeclared (first use in this function) > if (ut->ut_type == BOOT_TIME) > ^ > boot-time.c:111:26: note: each undeclared identifier is reported only once for each function it appears in > boot-time.c:126:3: error: implicit declaration of function 'endutent' [-Werror=implicit-function-declaration] > END_UTMP_ENT (); > ^ > cc1: some warnings being treated as errors Thanks for reporting that. As I understand it, the utmp/utmpx functions are a losing cause on Android since they never return anything. If so, it's simpler to bypass these functions on that platform. Also, Gnulib should bypass sysinfo unless it's available. Please try the attached patch, which I haven't installed onto Emacs master on Savannah. I've tested it only on Ubuntu 23.04. If this patch works we can propagate it to Gnulib. [-- Attachment #2: 0001-Temp-patch-for-Android.patch --] [-- Type: text/x-patch, Size: 6598 bytes --] From d2db6d8e92282de8ffb5293dd1445e3a2e549ed0 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sat, 12 Aug 2023 23:20:12 -0700 Subject: [PATCH] Temp patch for Android --- configure.ac | 19 ------------------- lib/boot-time-aux.h | 10 ++++++++++ lib/boot-time.c | 26 +++++++++----------------- src/conf_post.h | 34 ---------------------------------- src/filelock.c | 14 +++++--------- 5 files changed, 24 insertions(+), 79 deletions(-) diff --git a/configure.ac b/configure.ac index 46836073aa0..0234a82b92f 100644 --- a/configure.ac +++ b/configure.ac @@ -2710,25 +2710,6 @@ AC_DEFUN # Check for some functions not always present in the NDK. AC_CHECK_DECLS([android_get_device_api_level]) - AC_CHECK_DECLS([endutent, sysinfo], [], [], - [[ -#include <sys/sysinfo.h> -#include <utmp.h> -]]) - - # Establish if BOOT_TIME is defined in utmp.h. - AC_CACHE_CHECK([if utmp.h defines BOOT_TIME], - [emacs_cv_utmp_h_defines_boot_time], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include <utmp.h> -#ifndef BOOT_TIME -BOOT_TIME not defined -#endif /* BOOT_TIME */ -]], [[]])], [emacs_cv_utmp_h_defines_boot_time=yes], - [emacs_cv_utmp_h_defines_boot_time=no])]) - AS_IF([test x"$emacs_cv_utmp_h_defines_boot_time" = xyes], - [AC_DEFINE([UTMP_H_DEFINES_BOOT_TIME], [1], - [Define to 1 if building for Android and utmp.h declares BOOT_TIME])]) # Say this build is really for Android. REALLY_ANDROID=yes])]) diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h index 348611fc85c..e782ca6eac6 100644 --- a/lib/boot-time-aux.h +++ b/lib/boot-time-aux.h @@ -16,6 +16,14 @@ /* Written by Bruno Haible <bruno@clisp.org>. */ +#if defined __linux__ || 9 <= __ANDROID_API__ +# include <sys/sysinfo.h> +#endif +#if 9 <= __ANDROID_API__ +/* Absent from some NDK versions, but present in API level 9+. */ +extern int sysinfo (struct sysinfo *); +#endif + #define SIZEOF(a) (sizeof(a)/sizeof(a[0])) #if defined __linux__ || defined __ANDROID__ @@ -65,6 +73,7 @@ get_linux_uptime (struct timespec *p_uptime) } # endif +# if defined __linux__ || 9 <= __ANDROID_API__ /* The sysinfo call returns the uptime with a resolution of 1 sec only. */ struct sysinfo info; if (sysinfo (&info) >= 0) @@ -73,6 +82,7 @@ get_linux_uptime (struct timespec *p_uptime) p_uptime->tv_nsec = 0; return 0; } +# endif return -1; } diff --git a/lib/boot-time.c b/lib/boot-time.c index d813bfa5825..331711238bc 100644 --- a/lib/boot-time.c +++ b/lib/boot-time.c @@ -27,11 +27,6 @@ #include <sys/types.h> #include <sys/stat.h> -#if defined __linux__ || defined __ANDROID__ -# include <sys/sysinfo.h> -# include <time.h> -#endif - #if HAVE_SYS_SYSCTL_H && !defined __minix # if HAVE_SYS_PARAM_H # include <sys/param.h> @@ -76,7 +71,12 @@ get_boot_time_uncached (struct timespec *p_boot_time) { struct timespec found_boot_time = {0}; -# if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) +# ifdef __ANDROID__ + + /* Workaround for Android: */ + get_android_boot_time (&found_boot_time); + +# elif (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) /* Try to find the boot time in the /var/run/utmp file. */ @@ -90,7 +90,7 @@ get_boot_time_uncached (struct timespec *p_boot_time) SET_UTMP_ENT (); -# if (defined __linux__ && !defined __ANDROID__) || defined __minix +# if defined __linux__ || defined __minix /* Timestamp of the "runlevel" entry, if any. */ struct timespec runlevel_ts = {0}; # endif @@ -111,7 +111,7 @@ get_boot_time_uncached (struct timespec *p_boot_time) if (ut->ut_type == BOOT_TIME) found_boot_time = ts; -# if defined __linux__ && !defined __ANDROID__ +# ifdef __linux__ if (memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0 && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0) runlevel_ts = ts; @@ -125,7 +125,7 @@ get_boot_time_uncached (struct timespec *p_boot_time) END_UTMP_ENT (); -# if defined __linux__ && !defined __ANDROID__ +# ifdef __linux__ /* On Raspbian, which runs on hardware without a real-time clock, during boot, 1. the clock gets set to 1970-01-01 00:00:00, 2. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME, @@ -145,14 +145,6 @@ get_boot_time_uncached (struct timespec *p_boot_time) } # endif -# if defined __ANDROID__ - if (found_boot_time.tv_sec == 0) - { - /* Workaround for Android: */ - get_android_boot_time (&found_boot_time); - } -# endif - # if defined __minix /* On Minix, during boot, 1. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME, diff --git a/src/conf_post.h b/src/conf_post.h index 5f18e5ae4bb..f31e012dc6e 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -471,37 +471,3 @@ #define VFORK() vfork () #undef MB_CUR_MAX #define MB_CUR_MAX REPLACEMENT_MB_CUR_MAX #endif /* REPLACEMENT_MB_CUR_MAX */ - -#ifdef __ANDROID__ - -/* The Android NDK r10b omits the function `endutent' that is actually - defined in the C library and used by Gnulib. Define a prototype - for it here. */ - -#if !HAVE_DECL_ENDUTENT -extern void endutent (void); -#endif /* !HAVE_DECL_ENDUTENT */ - -/* Now define substitutes for BOOT_TIME if necessary. */ - -#ifndef UTMP_H_DEFINES_BOOT_TIME -#include <utmp.h> - -#define BOOT_TIME 2 -#endif /* !UTMP_H_DEFINES_BOOT_TIME */ - -/* sysinfo is also absent from some versions of the NDK, yet is - present on API level 9 and above. */ - -#if !HAVE_DECL_SYSINFO -#include <sys/sysinfo.h> - -#if __ANDROID_API__ >= 9 -extern int sysinfo (struct sysinfo *info); -#else /* __ANDROID_API__ < 8 */ -/* Gnulib uses this function unconditionally. */ -#define sysinfo(ignored) ((void) ignored, (errno = ENOSYS), -1) -#endif /* __ANDROID_API >= 9 */ -#endif /* !HAVE_DECL_SYSINFO */ - -#endif /* __ANDROID__ */ diff --git a/src/filelock.c b/src/filelock.c index f3075b93322..92be20ad8a0 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -118,16 +118,12 @@ get_boot_sec (void) if (will_dump_p ()) return 0; + struct timespec boot_time; + boot_time.tv_sec = 0; #ifndef MSDOS - { - struct timespec boot_time; - boot_time.tv_sec = 0; - get_boot_time (&boot_time); - return boot_time.tv_sec; - } -#else /* MSDOS */ - return 0; -#endif /* MSDOS */ + get_boot_time (&boot_time); +#endif + return boot_time.tv_sec; } \f /* An arbitrary limit on lock contents length. 8 K should be plenty -- 2.39.2 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 3:26 ` Po Lu 2023-08-13 6:35 ` Paul Eggert @ 2023-08-13 13:45 ` Bruno Haible 2023-08-13 14:16 ` Bruno Haible 2023-08-13 14:36 ` Bruno Haible 3 siblings, 0 replies; 24+ messages in thread From: Bruno Haible @ 2023-08-13 13:45 UTC (permalink / raw) To: Paul Eggert, Po Lu; +Cc: bug-gnulib, Emacs-devel Po Lu wrote: > During the automated build of the Android port, the following errors > were encountered with the Android NDK r10b and __ANDROID_API__ set to 8 > (which is the oldest configuration Emacs supports.) > ... > boot-time.c:111:26: note: each undeclared identifier is reported only once for each function it appears in > boot-time.c:126:3: error: implicit declaration of function 'endutent' [-Werror=implicit-function-declaration] > END_UTMP_ENT (); > ^ endutent() exists in Android, already in API 8. It's just that its declaration is missing from <utmp.h> until ca. 2015. Should be fixed through this patch. Also, it removes a declaration that was needed only for Ultrix 4.3. Gnulib dropped Ultrix support in 2018. Paul Eggert wrote: > As I understand it, the utmp/utmpx functions > are a losing cause on Android since they never return anything. If so, > it's simpler to bypass these functions on that platform. It's more future-proof to continue to use the API that they have. Who knows, they might add useful data into the UTMP_FILE at some point. (E.g. they had a broken localeconv() function for a long time; then they actually fixed it.) 2023-08-13 Bruno Haible <bruno@clisp.org> readutmp, boot-time: Fix compilation error on old Android. Reported by Po Lu in <https://lists.gnu.org/archive/html/bug-gnulib/2023-08/msg00108.html>. * lib/readutmp.c (endutent): New fallback declaration, for Android. (getutent): Remove Ultrix workaround from 2000-04-05. * lib/boot-time.c: Likewise. * m4/readutmp.m4 (gl_PREREQ_READUTMP_H): Test whether endutent is declared, not getutent. * doc/glibc-functions/endutent.texi: Mention the Android bug. diff --git a/doc/glibc-functions/endutent.texi b/doc/glibc-functions/endutent.texi index 5e12e23c44..b4f3dd397a 100644 --- a/doc/glibc-functions/endutent.texi +++ b/doc/glibc-functions/endutent.texi @@ -28,4 +28,7 @@ @item This function is missing on some platforms: macOS 11.1, FreeBSD 13.0, OpenBSD 6.7, Minix 3.1.8, mingw, MSVC 14. +@item +This function is not declared on some platforms: +Android before ca.@: 2015. @end itemize diff --git a/lib/boot-time.c b/lib/boot-time.c index d813bfa582..c359954f19 100644 --- a/lib/boot-time.c +++ b/lib/boot-time.c @@ -65,8 +65,10 @@ # define UT_USER(UT) ((UT)->ut_user) #endif -#if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION && !HAVE_DECL_GETUTENT -struct utmp *getutent (void); +#if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION +# if !HAVE_DECL_ENDUTENT /* Android */ +void endutent (void); +# endif #endif #if defined __linux__ || HAVE_UTMPX_H || HAVE_UTMP_H || defined __CYGWIN__ || defined _WIN32 diff --git a/lib/readutmp.c b/lib/readutmp.c index ef9f0aff43..0b7732b165 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -314,9 +314,11 @@ have_boot_time (struct utmp_alloc a) return false; } -# if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION && !HAVE_DECL_GETUTENT -struct utmp *getutent (void); +#if !HAVE_UTMPX_H && HAVE_UTMP_H && defined UTMP_NAME_FUNCTION +# if !HAVE_DECL_ENDUTENT /* Android */ +void endutent (void); # endif +#endif static int read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, diff --git a/m4/readutmp.m4 b/m4/readutmp.m4 index fff8d4eb7b..9dffe981b8 100644 --- a/m4/readutmp.m4 +++ b/m4/readutmp.m4 @@ -1,4 +1,4 @@ -# readutmp.m4 serial 28 +# readutmp.m4 serial 29 dnl Copyright (C) 2002-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -55,7 +55,7 @@ AC_DEFUN_ONCE([gl_PREREQ_READUTMP_H] if test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes; then dnl Prerequisites of lib/readutmp.h and lib/readutmp.c. AC_CHECK_FUNCS_ONCE([utmpname utmpxname]) - AC_CHECK_DECLS([getutent],,,[[ + AC_CHECK_DECLS([endutent],,,[[ /* <sys/types.h> is a prerequisite of <utmp.h> on FreeBSD 8.0, OpenBSD 4.6. */ #include <sys/types.h> #ifdef HAVE_UTMP_H ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 3:26 ` Po Lu 2023-08-13 6:35 ` Paul Eggert 2023-08-13 13:45 ` Bruno Haible @ 2023-08-13 14:16 ` Bruno Haible 2023-08-13 14:36 ` Bruno Haible 3 siblings, 0 replies; 24+ messages in thread From: Bruno Haible @ 2023-08-13 14:16 UTC (permalink / raw) To: Paul Eggert, Po Lu; +Cc: bug-gnulib, Emacs-devel Po Lu wrote: > During the automated build of the Android port, the following errors > were encountered with the Android NDK r10b and __ANDROID_API__ set to 8 > (which is the oldest configuration Emacs supports.)... > > In file included from boot-time.c:54:0: > boot-time-aux.h: In function 'get_linux_uptime': > boot-time-aux.h:70:3: error: implicit declaration of function 'sysinfo' [-Werror=implicit-function-declaration] > if (sysinfo (&info) >= 0) > ^ Should be fixed by the patch below. Paul Eggert wrote: > Gnulib should bypass sysinfo unless it's available. Yes. Note that it's available in Android libc already at API level 3. It's only the declaration that was added in API level 9. Also, if we write '#if HAVE_DECL_SYSINFO' instead of '9 <= __ANDROID_API__', the change might be helpful also with other Linux-based libcs that may be developed in the future. 2023-08-13 Bruno Haible <bruno@clisp.org> readutmp, boot-time: Fix compilation error on Android API 8. Reported by Po Lu in <https://lists.gnu.org/archive/html/bug-gnulib/2023-08/msg00108.html>. * m4/readutmp.m4 (gl_PREREQ_READUTMP_H): Test whether sysinfo is declared. * lib/boot-time-aux.h (get_linux_uptime): Invoke sysinfo only if it is declared. * doc/glibc-functions/sysinfo.texi: Mention the Android problem. diff --git a/doc/glibc-functions/sysinfo.texi b/doc/glibc-functions/sysinfo.texi index 3b1ade31a6..16e12b12ac 100644 --- a/doc/glibc-functions/sysinfo.texi +++ b/doc/glibc-functions/sysinfo.texi @@ -17,4 +17,7 @@ @item This function is missing on some platforms: macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, Cygwin 1.7.9, mingw, MSVC 14. +@item +This function is not declared and thus not part of the Android API +for Android API levels < 9. @end itemize diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h index 348611fc85..e59a0fd03c 100644 --- a/lib/boot-time-aux.h +++ b/lib/boot-time-aux.h @@ -65,6 +65,7 @@ get_linux_uptime (struct timespec *p_uptime) } # endif +# if HAVE_DECL_SYSINFO /* not available in Android API < 9 */ /* The sysinfo call returns the uptime with a resolution of 1 sec only. */ struct sysinfo info; if (sysinfo (&info) >= 0) @@ -73,6 +74,7 @@ get_linux_uptime (struct timespec *p_uptime) p_uptime->tv_nsec = 0; return 0; } +# endif return -1; } diff --git a/m4/readutmp.m4 b/m4/readutmp.m4 index 9dffe981b8..0a47f4bb77 100644 --- a/m4/readutmp.m4 +++ b/m4/readutmp.m4 @@ -1,4 +1,4 @@ -# readutmp.m4 serial 29 +# readutmp.m4 serial 30 dnl Copyright (C) 2002-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -103,6 +103,10 @@ AC_DEFUN_ONCE([gl_PREREQ_READUTMP_H] AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination],,,[$utmp_includes]) fi + AC_CHECK_DECLS([sysinfo],,,[[ + #include <sys/sysinfo.h> + ]]) + AC_CHECK_HEADERS_ONCE([sys/param.h]) dnl <sys/sysctl.h> requires <sys/param.h> on OpenBSD 4.0. AC_CHECK_HEADERS([sys/sysctl.h],,, ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 3:26 ` Po Lu ` (2 preceding siblings ...) 2023-08-13 14:16 ` Bruno Haible @ 2023-08-13 14:36 ` Bruno Haible 2023-08-13 23:44 ` Po Lu 3 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-13 14:36 UTC (permalink / raw) To: Paul Eggert, Po Lu; +Cc: bug-gnulib, Emacs-devel Po Lu wrote: > During the automated build of the Android port, the following errors > were encountered with the Android NDK r10b and __ANDROID_API__ set to 8 > (which is the oldest configuration Emacs supports.) > ... > boot-time.c: In function 'get_boot_time_uncached': > boot-time.c:111:26: error: 'BOOT_TIME' undeclared (first use in this function) > if (ut->ut_type == BOOT_TIME) > ^ Unlike USER_PROCESS, which is defined in all versions of Android's <utmp.h>, BOOT_TIME is only defined in newer versions. When compiling against an older version, we need to use the value from the newer versions — otherwise a binary built against an older version might not work right when running on a newer Android. This patch does it. 2023-08-13 Bruno Haible <bruno@clisp.org> readutmp, boot-time: Fix compilation error on old Android. Reported by Po Lu in <https://lists.gnu.org/archive/html/bug-gnulib/2023-08/msg00108.html>. * lib/readutmp.h (BOOT_TIME): Add fallback. diff --git a/lib/readutmp.h b/lib/readutmp.h index 1cf588d265..f7cad36d44 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -249,6 +249,13 @@ struct utmpx32 # define WTMP_FILE "/etc/wtmp" #endif +/* In early versions of Android, <utmp.h> did not define BOOT_TIME, only + USER_PROCESS. We need to use the value that is defined in newer versions + of Android. */ +#if defined __ANDROID__ && !defined BOOT_TIME +# define BOOT_TIME 2 +#endif + /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have the BOOT_TIME and USER_PROCESS macros. But we want to support them in 'struct gl_utmp'. */ ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 14:36 ` Bruno Haible @ 2023-08-13 23:44 ` Po Lu 2023-08-13 23:59 ` Bruno Haible 0 siblings, 1 reply; 24+ messages in thread From: Po Lu @ 2023-08-13 23:44 UTC (permalink / raw) To: Bruno Haible; +Cc: Paul Eggert, bug-gnulib, Emacs-devel Bruno Haible <bruno@clisp.org> writes: > Po Lu wrote: >> During the automated build of the Android port, the following errors >> were encountered with the Android NDK r10b and __ANDROID_API__ set to 8 >> (which is the oldest configuration Emacs supports.) >> ... >> boot-time.c: In function 'get_boot_time_uncached': >> boot-time.c:111:26: error: 'BOOT_TIME' undeclared (first use in this function) >> if (ut->ut_type == BOOT_TIME) >> ^ > > Unlike USER_PROCESS, which is defined in all versions of Android's <utmp.h>, > BOOT_TIME is only defined in newer versions. > > When compiling against an older version, we need to use the value from the > newer versions — otherwise a binary built against an older version might > not work right when running on a newer Android. > > This patch does it. > > > 2023-08-13 Bruno Haible <bruno@clisp.org> > > readutmp, boot-time: Fix compilation error on old Android. > Reported by Po Lu in > <https://lists.gnu.org/archive/html/bug-gnulib/2023-08/msg00108.html>. > * lib/readutmp.h (BOOT_TIME): Add fallback. > > diff --git a/lib/readutmp.h b/lib/readutmp.h > index 1cf588d265..f7cad36d44 100644 > --- a/lib/readutmp.h > +++ b/lib/readutmp.h > @@ -249,6 +249,13 @@ struct utmpx32 > # define WTMP_FILE "/etc/wtmp" > #endif > > +/* In early versions of Android, <utmp.h> did not define BOOT_TIME, only > + USER_PROCESS. We need to use the value that is defined in newer versions > + of Android. */ > +#if defined __ANDROID__ && !defined BOOT_TIME > +# define BOOT_TIME 2 > +#endif > + > /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have > the BOOT_TIME and USER_PROCESS macros. But we want to support them in > 'struct gl_utmp'. */ Both of your patches appear to work. Thanks. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 23:44 ` Po Lu @ 2023-08-13 23:59 ` Bruno Haible 2023-08-14 1:07 ` Po Lu 0 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-13 23:59 UTC (permalink / raw) To: Po Lu; +Cc: Paul Eggert, bug-gnulib, Emacs-devel Po Lu wrote: > Both of your patches appear to work. Thanks for the confirmation. As you know, I'm using a Termux environment for testing on Android. This has only approximately, not exactly, the same include files and libc as what you are using when you compile with some Android NDK. Therefore I'm relying on your reports for the (few) portability problems that arise because of differences between Android API levels or between Android versions. Bruno ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 23:59 ` Bruno Haible @ 2023-08-14 1:07 ` Po Lu 2023-08-14 2:14 ` Corwin Brust 0 siblings, 1 reply; 24+ messages in thread From: Po Lu @ 2023-08-14 1:07 UTC (permalink / raw) To: Bruno Haible; +Cc: Paul Eggert, bug-gnulib, Emacs-devel Bruno Haible <bruno@clisp.org> writes: > Po Lu wrote: >> Both of your patches appear to work. > > Thanks for the confirmation. As you know, I'm using a Termux environment > for testing on Android. This has only approximately, not exactly, the same > include files and libc as what you are using when you compile with some > Android NDK. Therefore I'm relying on your reports for the (few) portability > problems that arise because of differences between Android API levels > or between Android versions. > > Bruno Regular merges from Gnulib into Emacs should facilitate that, since I've set aside a machine for the express purpose of building the Android port automatically in response to every large change to the branch. And thanks again for your help. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 1:07 ` Po Lu @ 2023-08-14 2:14 ` Corwin Brust 2023-08-15 19:57 ` Windows port binaries Bruno Haible 0 siblings, 1 reply; 24+ messages in thread From: Corwin Brust @ 2023-08-14 2:14 UTC (permalink / raw) To: Po Lu; +Cc: Bruno Haible, Paul Eggert, bug-gnulib, Emacs-devel On Sun, Aug 13, 2023 at 8:07 PM Po Lu <luangruo@yahoo.com> wrote: > > Bruno Haible <bruno@clisp.org> writes: > > > Po Lu wrote: > >> Both of your patches appear to work. > > > > Thanks for the confirmation. As you know, I'm using a Termux environment > > Regular merges from Gnulib into Emacs should facilitate that, since I've > set aside a machine for the express purpose of building the Android port > automatically in response to every large change to the branch. > In case it helps others to assist with testing, for the moment I am aggressively rebuilding the Windows port also, from (not quite every) commit to emacs-29 or master, posting to: https://corwin.bru.st/emacs-29 https://corwin.bru.st/emacs-30 Note, older release sets get all but the no-deps and source archives removed; unpack the no-deps archive atop an existing install of the same version of Emacs to use them for testing purposes after the installer and full-zip have been pruned. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Windows port binaries 2023-08-14 2:14 ` Corwin Brust @ 2023-08-15 19:57 ` Bruno Haible 2023-08-16 6:45 ` Po Lu 2023-08-16 11:36 ` Eli Zaretskii 0 siblings, 2 replies; 24+ messages in thread From: Bruno Haible @ 2023-08-15 19:57 UTC (permalink / raw) To: Corwin Brust, Emacs-devel; +Cc: Po Lu, Paul Eggert Corwin Brust wrote: > In case it helps others to assist with testing, for the moment I am > aggressively rebuilding the Windows port also, from (not quite every) > commit to emacs-29 or master, posting to: > > https://corwin.bru.st/emacs-29 > https://corwin.bru.st/emacs-30 Thanks. I tried to use the https://corwin.bru.st/emacs-30/emacs-30-latest-no-deps.zip binary from today, but they don't work for me (on Windows 10), because they rely on two DLLs which are not contained in the 'bin' directory: - libgmp-10.dll - libwinpthread-1.dll Find below the output of "dumpbin.exe /imports emacs.exe". Additionally, I find it strange: 1) Why are the imports from libgmp all prefixed with '__'? That's a bit unusual. 2) emacs/nt/mingw-cfg.site contains this comment: # We don't want to check for these functions # because they are implemented in libwinpthread. corresponding to this ChangeLog entry: 2016-04-21 Fabrice Popineau <fabrice.popineau@gmail.com> Avoid run-time dependency on libwinpthread DLL on MS-Windows * nt/mingw-cfg.site (ac_cv_search_clock_gettime) (ac_cv_func_clock_gettime, ac_cv_func_clock_settime): Force to not present, so that MinGW64 builds don't depend on libwinpthread. (Bug#22959) However, the binaries rely on nanosleep() from libwinpthread. Is it intended or unintended? If it is unintended, does it come from Gnulib? In this case, I'll gladly help to do anything needed in Gnulib to help avoid this import. Bruno ==================== dumpbin /imports ============================== Microsoft (R) COFF/PE Dumper Version 14.00.24210.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file emacs.exe File Type: EXECUTABLE IMAGE Section contains the following imports: ADVAPI32.dll 400810540 Import Address Table 40080F140 Import Name Table 0 time date stamp 0 Index of first forwarder reference 407 AdjustTokenPrivileges 4A9 CryptAcquireContextA 4BA CryptGenRandom 563 GetUserNameA 596 LookupPrivilegeValueA 643 RegCloseKey 664 RegEnumValueA 673 RegOpenKeyExA 680 RegQueryValueExA COMCTL32.dll 400810590 Import Address Table 40080F190 Import Name Table 0 time date stamp 0 Index of first forwarder reference 68 InitCommonControls comdlg32.dll 4008105A0 Import Address Table 40080F1A0 Import Name Table 0 time date stamp 0 Index of first forwarder reference 3 ChooseFontA 5 CommDlgExtendedError A GetOpenFileNameA B GetOpenFileNameW GDI32.dll 4008105C8 Import Address Table 40080F1C8 Import Name Table 0 time date stamp 0 Index of first forwarder reference 14 BitBlt 23 CombineRgn 2A CreateBitmap 31 CreateCompatibleBitmap 32 CreateCompatibleDC 33 CreateDCA 38 CreateDIBSection 41 CreateFontIndirectA 4E CreatePalette 50 CreatePen 54 CreateRectRgn 55 CreateRectRgnIndirect 5B CreateSolidBrush 181 DeleteDC 184 DeleteObject 1C4 EnumFontFamiliesExA 1CD EqualRgn 1D7 ExtTextOutA 1D8 ExtTextOutW 270 GetClipBox 271 GetClipRgn 275 GetCurrentObject 27D GetDeviceCaps 28B GetFontData 2AD GetObjectA 2B6 GetPixel 2D0 GetTextExtentPoint32A 2D1 GetTextExtentPoint32W 2D5 GetTextFaceA 2D8 GetTextMetricsA 2EB LineTo 2FF MoveToEx 30B PatBlt 321 RealizePalette 324 Rectangle 32E RestoreDC 335 SaveDC 364 SelectClipRgn 366 SelectObject 367 SelectPalette 36D SetBkColor 36E SetBkMode 371 SetBrushOrgEx 391 SetStretchBltMode 393 SetTextAlign 395 SetTextColor 3A2 StretchBlt 3A9 TranslateCharsetInfo libgmp-10.dll 400810750 Import Address Table 40080F350 Import Name Table 0 time date stamp 0 Index of first forwarder reference 3D __gmp_set_memory_functions 1F8 __gmpn_popcount 2DC __gmpz_add 2DD __gmpz_add_ui 2DE __gmpz_addmul 2DF __gmpz_addmul_ui 2E0 __gmpz_and 2E5 __gmpz_cdiv_q 2EE __gmpz_clear 2F1 __gmpz_cmp 2F2 __gmpz_cmp_d 2F4 __gmpz_cmp_ui 2F5 __gmpz_cmpabs 2F8 __gmpz_com 2FD __gmpz_divexact 304 __gmpz_export 306 __gmpz_fdiv_q 307 __gmpz_fdiv_q_2exp 308 __gmpz_fdiv_q_ui 309 __gmpz_fdiv_qr 30B __gmpz_fdiv_r 317 __gmpz_gcd 31A __gmpz_get_d 31D __gmpz_get_str 321 __gmpz_import 322 __gmpz_init 328 __gmpz_init_set_ui 32E __gmpz_ior 335 __gmpz_limbs_finish 337 __gmpz_limbs_read 338 __gmpz_limbs_write 33F __gmpz_mul 340 __gmpz_mul_2exp 342 __gmpz_mul_ui 34C __gmpz_pow_ui 358 __gmpz_roinit_n 35D __gmpz_scan1 35E __gmpz_set 35F __gmpz_set_d 362 __gmpz_set_si 363 __gmpz_set_str 364 __gmpz_set_ui 368 __gmpz_sizeinbase 36C __gmpz_sub 36D __gmpz_sub_ui 36E __gmpz_submul 370 __gmpz_swap 371 __gmpz_tdiv_q 374 __gmpz_tdiv_qr 376 __gmpz_tdiv_r 379 __gmpz_tdiv_ui 37C __gmpz_ui_pow_ui 380 __gmpz_xor KERNEL32.dll 400810900 Import Address Table 40080F500 Import Name Table 0 time date stamp 0 Index of first forwarder reference 29 BackupWrite 6B Beep 78 CancelIo 8D CloseHandle 9E CompareFileTime A2 CompareStringW B1 CopyFileA B6 CopyFileW C5 CreateEventA CC CreateFileA CD CreateFileMappingA D4 CreateFileW EA CreateProcessA FC CreateThread 111 DebugBreak 11B DeleteCriticalSection 12B DeviceIoControl 12C DisableThreadLibraryCalls 139 DuplicateHandle 13F EnterCriticalSection 15A EnumSystemCodePagesA 161 EnumSystemLocalesA 171 ExpandEnvironmentStringsA 17B FillConsoleOutputAttribute 17C FillConsoleOutputCharacterA 185 FindClose 189 FindFirstFileA 190 FindFirstFileW 19A FindNextFileA 19C FindNextFileW 1AE FlushConsoleInputBuffer 1B6 FormatMessageA 1BB FreeLibrary 1C1 GenerateConsoleCtrlEvent 1C2 GetACP 1D2 GetCPInfo 1E5 GetCommState 1E6 GetCommTimeouts 1E7 GetCommandLineA 1ED GetComputerNameA 1FB GetConsoleCP 201 GetConsoleCursorInfo 20D GetConsoleMode 211 GetConsoleOutputCP 213 GetConsoleScreenBufferInfo 217 GetConsoleTitleW 221 GetCurrentDirectoryA 222 GetCurrentDirectoryW 228 GetCurrentProcess 229 GetCurrentProcessId 22C GetCurrentThread 22D GetCurrentThreadId 239 GetDiskFreeSpaceA 23C GetDiskFreeSpaceW 241 GetDriveTypeA 24C GetEnvironmentVariableA 250 GetExitCodeProcess 251 GetExitCodeThread 256 GetFileAttributesA 25B GetFileAttributesW 25D GetFileInformationByHandle 261 GetFileSize 264 GetFileType 26C GetFullPathNameA 26F GetFullPathNameW 276 GetLastError 279 GetLocaleInfoA 289 GetModuleFileNameA 28A GetModuleFileNameW 28B GetModuleHandleA 298 GetNamedPipeInfo 2AD GetNumberOfConsoleInputEvents 2AF GetOEMCP 2B0 GetOverlappedResult 2C6 GetProcAddress 2CC GetProcessHeap 2E0 GetProfileStringA 2E4 GetShortPathNameA 2E5 GetShortPathNameW 2E7 GetStartupInfoA 2EA GetStdHandle 2F3 GetSystemDefaultLCID 2FB GetSystemInfo 2FC GetSystemPowerStatus 301 GetSystemTimeAsFileTime 317 GetThreadLocale 31F GetTickCount 32C GetUserDefaultLCID 333 GetVersion 334 GetVersionExA 336 GetVolumeInformationA 338 GetVolumeInformationW 347 GlobalAlloc 34E GlobalFree 351 GlobalHandle 352 GlobalLock 359 GlobalUnlock 35F HeapAlloc 361 HeapCreate 365 HeapFree 369 HeapReAlloc 37C InitializeCriticalSection 397 IsDBCSLeadByteEx 3A5 IsValidCodePage 3A7 IsValidLocale 3D8 LeaveCriticalSection 3DC LoadLibraryA 3DF LoadLibraryW 3EA LocalFree 3FB MapViewOfFile 3FC MapViewOfFileEx 40C MultiByteToWideChar 42D OpenProcess 436 OutputDebugStringA 440 PeekNamedPipe 45B PulseEvent 45C PurgeComm 475 QueueUserAPC 481 RaiseException 486 ReadConsoleInputA 489 ReadConsoleInputW 491 ReadDirectoryChangesW 492 ReadFile 495 ReadProcessMemory 4BE ResetEvent 4C5 ResumeThread 4D7 ScrollConsoleScreenBufferA 4E3 SetCommState 4E4 SetCommTimeouts 4EA SetConsoleActiveScreenBuffer 4EB SetConsoleCP 4ED SetConsoleCtrlHandler 4EF SetConsoleCursorInfo 4F1 SetConsoleCursorPosition 4FD SetConsoleMode 502 SetConsoleOutputCP 505 SetConsoleScreenBufferSize 508 SetConsoleTitleW 509 SetConsoleWindowInfo 514 SetEndOfFile 519 SetErrorMode 51A SetEvent 51F SetFileAttributesA 522 SetFileAttributesW 527 SetFilePointer 52B SetFileTime 536 SetLastError 53F SetNamedPipeHandleState 540 SetPriorityClass 54E SetStdHandle 560 SetThreadLocale 562 SetThreadPriority 572 SetUnhandledExceptionFilter 582 Sleep 58A SuspendThread 58D SystemTimeToFileTime 591 TerminateProcess 592 TerminateThread 5A5 TlsGetValue 5B6 UnmapViewOfFile 5CE VirtualAlloc 5D1 VirtualFree 5D4 VirtualProtect 5D6 VirtualQuery 5DD WaitForMultipleObjects 5DF WaitForSingleObject 5E0 WaitForSingleObjectEx 60B WideCharToMultiByte 615 WriteConsoleInputA 618 WriteConsoleInputW 61B WriteConsoleOutputCharacterA 61F WriteFile 642 lstrcmpiA 64C lstrlenW MPR.dll 400810E78 Import Address Table 40080FA78 Import Name Table 0 time date stamp 0 Index of first forwarder reference E WNetAddConnection2A F WNetAddConnection2W 19 WNetCloseEnum 24 WNetEnumResourceA 25 WNetEnumResourceW 48 WNetOpenEnumA 49 WNetOpenEnumW msvcrt.dll 400810EB8 Import Address Table 40080FAB8 Import Name Table 0 time date stamp 0 Index of first forwarder reference 38 __C_specific_handler 40 ___lc_codepage_func 43 ___mb_cur_max_func 52 __getmainargs 53 __initenv 54 __iob_func 62 __set_app_type 64 __setusermatherr 74 _acmdln 7C _amsg_exit 89 _beginthread 8E _cexit 91 _chdir 97 _chmod 9B _close 9D _commit 9E _commode A7 _chdir AA _creat B0 _ctime64 BF _difftime64 C1 _dup C2 _dup2 C9 _environ CB _errno FB _exit DE _fdopen E8 _fileno FF _fmode 11C _futime64 127 _get_osfhandle 135 _getmbcp 136 _getpid 13E _gmtime64 14B _initterm 153 _hypot 150 _isatty 1BA _localtime64 1BB _lock 1C6 _lseeki64 1ED _mbschr 1FF _mbsinc 203 _mbslwr 227 _mbsncpy 22B _mbsnextc 239 _mbspbrk 23B _mbsrchr 258 _memccpy 25D _mkdir 261 _mktime64 267 _onexit 269 _open 26A _open_osfhandle 271 _pipe 27A _putenv 281 _read 284 _rmdir 29E _setjmp 2A2 _setmode 2A6 _snprintf 2C0 _spawnlp 2DA _stricmp 2D8 _strdup 2E4 _strlwr 2F1 _strnicmp 313 _sys_errlist 314 _sys_nerr 319 _time64 324 _tzname 325 _tzset 32F _umask 333 _unlink 334 _unlock 373 _wchdir 374 _wchmod 376 _wcreat 3C7 _wgetenv 3CF _wmkdir 3D1 _wopen 3DE _wrename 3E0 _write 3E1 _wrmdir 406 _wunlink 41F abort 41D acos 410 asin 412 atan 417 atof 418 atoi 421 calloc 424 clearerr 426 clock 42E exit 432 fclose 433 feof 434 ferror 435 fflush 437 fgetpos 439 fgets 442 fprintf 444 fputc 445 fputs 448 fread 449 free 451 fseek 456 fwrite 45A getc 45B getchar 45C getenv 464 isalpha 469 islower 46C isspace 46D isupper 47B isxdigit 47F localeconv 482 log10 485 longjmp 486 malloc 48C memchr 48D memcmp 48E memcpy 48F memmove 490 memset 49A putc 49B putchar 49F qsort 4A1 raise 4A3 realloc 4A2 rand 4A6 rename 4AC setlocale 4AD setvbuf 4AE signal 4B7 srand 4BB strcat 4BD strchr 4BE strcmp 4C0 strcpy 4C3 strerror 4C4 strftime 4C5 strlen 4C6 strncat 4C8 strncmp 4C9 strncpy 4CB strpbrk 4CC strrchr 4CD strspn 4CE strstr 4D1 strtok 4D3 strtol 4D4 strtoul 4DD tan 4E5 tolower 4E6 toupper 4E9 ungetc 4EC vfprintf 4FC wcscat 501 wcscpy 505 wcslen 509 wcsncpy ole32.dll 4008113C0 Import Address Table 40080FFC0 Import Name Table 0 time date stamp 0 Index of first forwarder reference 1E CoCreateGuid 55 CoInitialize 85 CoUninitialize 1FA StringFromGUID2 libwinpthread-1.dll 4008113E8 Import Address Table 40080FFE8 Import Name Table 0 time date stamp 0 Index of first forwarder reference 10 nanosleep SHELL32.dll 4008113F8 Import Address Table 40080FFF8 Import Name Table 0 time date stamp 0 Index of first forwarder reference 20 DragAcceptFiles 21 DragFinish 23 DragQueryFileA 25 DragQueryFileW 26 DragQueryPoint BD SHFileOperationA BE SHFileOperationW 152 ShellExecuteExA 153 ShellExecuteExW 160 Shell_NotifyIconW USER32.dll 400811450 Import Address Table 400810050 Import Name Table 0 time date stamp 0 Index of first forwarder reference 1 ActivateKeyboardLayout 3 AdjustWindowRect B AppendMenuA F AttachThreadInput 10 BeginDeferWindowPos 11 BeginPaint 13 BringWindowToTop 1F CallNextHookEx 31 CharLowerW 32 CharNextA 33 CharNextExA 35 CharPrevA 48 ChildWindowFromPoint 4C ClientToScreen 4E CloseClipboard 5E CreateCaret 70 CreateMenu 71 CreatePopupMenu 73 CreateWindowExA A4 DefWindowProcA A5 DefWindowProcW A6 DeferWindowPos A8 DeleteMenu AB DestroyCaret AE DestroyIcon AF DestroyMenu B1 DestroyWindow B9 DispatchMessageA BA DispatchMessageW DB DrawTextW E6 EmptyClipboard EC EnableWindow ED EndDeferWindowPos F1 EndPaint F5 EnumClipboardFormats 107 EnumWindows 10D FillRect 10E FindWindowA 111 FindWindowW 112 FlashWindow 114 FrameRect 11E GetAsyncKeyState 12D GetClassNameA 130 GetClientRect 133 GetClipboardData 134 GetClipboardFormatNameA 13E GetCursorPos 13F GetDC 142 GetDesktopWindow 147 GetDlgItem 14B GetDoubleClickTime 14F GetFocus 150 GetForegroundWindow 15E GetKeyNameTextA 160 GetKeyState 161 GetKeyboardLayout 162 GetKeyboardLayoutList 165 GetKeyboardState 16E GetMenu 16F GetMenuBarInfo 174 GetMenuItemCount 17C GetMessageA 17F GetMessageTime 180 GetMessageW 187 GetParent 1AF GetScrollInfo 1B8 GetSystemMetrics 1C1 GetTopWindow 1C4 GetUpdateRect 1CB GetWindow 1D0 GetWindowDC 1D4 GetWindowInfo 1D5 GetWindowLongA 1DD GetWindowPlacement 1DE GetWindowRect 1E6 GetWindowThreadProcessId 1EB HideCaret 20A InvalidateRect 238 KillTimer 241 LoadIconA 243 LoadImageA 244 LoadImageW 25C MapVirtualKeyA 260 MapWindowPoints 264 MessageBeep 265 MessageBoxA 273 MsgWaitForMultipleObjects 27D OpenClipboard 28A PeekMessageA 28B PeekMessageW 28E PostMessageA 291 PostThreadMessageA 2B8 RegisterClassA 2BB RegisterClassW 2C4 RegisterHotKey 2D6 RegisterWindowMessageA 2D8 ReleaseCapture 2D9 ReleaseDC 2E3 ScreenToClient 2E7 ScrollWindowEx 2EC SendInput 2ED SendMessageA 2F0 SendMessageTimeoutA 2F2 SendMessageW 2F6 SetCapture 2F8 SetCaretPos 2FE SetClipboardData 302 SetCursor 304 SetCursorPos 30E SetFocus 30F SetForegroundWindow 313 SetKeyboardState 31B SetMenu 325 SetParent 331 SetRectEmpty 332 SetScrollInfo 340 SetTimer 34B SetWindowLongA 34F SetWindowPlacement 350 SetWindowPos 354 SetWindowTextA 355 SetWindowTextW 358 SetWindowsHookExA 35B ShowCaret 35C ShowCursor 361 ShowWindow 36F SystemParametersInfoA 371 SystemParametersInfoW 376 ToAscii 378 ToUnicode 37B TrackPopupMenu 381 TranslateMessage 385 UnhookWindowsHookEx 386 UnionRect 38D UnregisterHotKey 3AB VkKeyScanW 3B8 WindowFromPoint 3BC keybd_event USP10.dll 4008118A8 Import Address Table 4008104A8 Import Name Table 0 time date stamp 0 Index of first forwarder reference 7 ScriptFreeCache 8 ScriptGetCMap E ScriptGetGlyphABCWidth 12 ScriptItemize 16 ScriptPlace 1A ScriptShape WINMM.dll 4008118E0 Import Address Table 4008104E0 Import Name Table 0 time date stamp 0 Index of first forwarder reference 3B mciGetErrorStringA 41 mciSendStringA 42 mciSendStringW BB waveOutGetErrorTextA C2 waveOutGetVolume CB waveOutSetVolume WINSPOOL.DRV 400811918 Import Address Table 400810518 Import Name Table 0 time date stamp 0 Index of first forwarder reference 1E ClosePrinter 81 GetPrinterA 8E GetPrinterW 96 OpenPrinterA Summary 1000 .CRT 9B000 .bss 476000 .data 7000 .debug_abbrev 1000 .debug_aranges 4000 .debug_frame 1F000 .debug_info F000 .debug_line 6000 .debug_line_str 13000 .debug_loclists 1000 .debug_rnglists 1000 .debug_str 6000 .idata F000 .pdata 3B000 .rdata 4000 .reloc 5C000 .rsrc 23000 .subrs 280000 .text 1000 .tls 10000 .xdata ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Windows port binaries 2023-08-15 19:57 ` Windows port binaries Bruno Haible @ 2023-08-16 6:45 ` Po Lu 2023-08-16 11:36 ` Eli Zaretskii 1 sibling, 0 replies; 24+ messages in thread From: Po Lu @ 2023-08-16 6:45 UTC (permalink / raw) To: Bruno Haible; +Cc: Corwin Brust, Emacs-devel, Paul Eggert Bruno Haible <bruno@clisp.org> writes: > Corwin Brust wrote: >> In case it helps others to assist with testing, for the moment I am >> aggressively rebuilding the Windows port also, from (not quite every) >> commit to emacs-29 or master, posting to: >> >> https://corwin.bru.st/emacs-29 >> https://corwin.bru.st/emacs-30 > > Thanks. I tried to use the > https://corwin.bru.st/emacs-30/emacs-30-latest-no-deps.zip > binary from today, but they don't work for me (on Windows 10), because > they rely on two DLLs which are not contained in the 'bin' directory: > - libgmp-10.dll > - libwinpthread-1.dll > > Find below the output of "dumpbin.exe /imports emacs.exe". > > Additionally, I find it strange: > > 1) Why are the imports from libgmp all prefixed with '__'? That's > a bit unusual. GMP prefers such a naming convention for their exported symbols. These symbols are defined to their programmer-facing names in gmp.h. > 2) emacs/nt/mingw-cfg.site contains this comment: > # We don't want to check for these functions > # because they are implemented in libwinpthread. > corresponding to this ChangeLog entry: > > 2016-04-21 Fabrice Popineau <fabrice.popineau@gmail.com> > > Avoid run-time dependency on libwinpthread DLL on MS-Windows > > * nt/mingw-cfg.site (ac_cv_search_clock_gettime) > (ac_cv_func_clock_gettime, ac_cv_func_clock_settime): Force to not > present, so that MinGW64 builds don't depend on libwinpthread. > (Bug#22959) > > However, the binaries rely on nanosleep() from libwinpthread. > Is it intended or unintended? > If it is unintended, does it come from Gnulib? In this case, I'll gladly > help to do anything needed in Gnulib to help avoid this import. I was under the impression that Emacs is supposed to use the nanosleep from MinGW, so this should be investigated. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Windows port binaries 2023-08-15 19:57 ` Windows port binaries Bruno Haible 2023-08-16 6:45 ` Po Lu @ 2023-08-16 11:36 ` Eli Zaretskii 2023-08-17 14:01 ` Bruno Haible 1 sibling, 1 reply; 24+ messages in thread From: Eli Zaretskii @ 2023-08-16 11:36 UTC (permalink / raw) To: Bruno Haible; +Cc: corwin, Emacs-devel, luangruo, eggert > From: Bruno Haible <bruno@clisp.org> > Cc: Po Lu <luangruo@yahoo.com>, Paul Eggert <eggert@cs.ucla.edu> > Date: Tue, 15 Aug 2023 21:57:47 +0200 > > > https://corwin.bru.st/emacs-29 > > https://corwin.bru.st/emacs-30 > > Thanks. I tried to use the > https://corwin.bru.st/emacs-30/emacs-30-latest-no-deps.zip > binary from today, but they don't work for me (on Windows 10), because > they rely on two DLLs which are not contained in the 'bin' directory: > - libgmp-10.dll > - libwinpthread-1.dll libwinpthread-1.dll shouldn't be there. But maybe there's no way to avoid that with MinGW64 ports of GCC. See below. > Find below the output of "dumpbin.exe /imports emacs.exe". A more GNU-friendly way is objdump -p emacs.exe | fgrep "DLL Name:" > Additionally, I find it strange: > > 1) Why are the imports from libgmp all prefixed with '__'? That's > a bit unusual. Why are you asking us? The Emacs project doesn't build libgmp, it only uses it. This question shouldf go to the GMP developers, IMO. > 2) emacs/nt/mingw-cfg.site contains this comment: > # We don't want to check for these functions > # because they are implemented in libwinpthread. > corresponding to this ChangeLog entry: > > 2016-04-21 Fabrice Popineau <fabrice.popineau@gmail.com> > > Avoid run-time dependency on libwinpthread DLL on MS-Windows > > * nt/mingw-cfg.site (ac_cv_search_clock_gettime) > (ac_cv_func_clock_gettime, ac_cv_func_clock_settime): Force to not > present, so that MinGW64 builds don't depend on libwinpthread. > (Bug#22959) > > However, the binaries rely on nanosleep() from libwinpthread. > Is it intended or unintended? I guess this is some kind of regression. But I'm not sure we can avoid this, when MinGW64 is used. (I use mingw.org's MinGW, and my Emacs on Windows doesn't have the libwinpthread dependency.) ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Windows port binaries 2023-08-16 11:36 ` Eli Zaretskii @ 2023-08-17 14:01 ` Bruno Haible 2023-08-17 14:14 ` Eli Zaretskii 0 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-17 14:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: corwin, Emacs-devel, luangruo, eggert Eli Zaretskii wrote: > > they rely on two DLLs which are not contained in the 'bin' directory: > > - libgmp-10.dll > > - libwinpthread-1.dll > > libwinpthread-1.dll shouldn't be there. ... > But I'm not sure we can avoid this, when MinGW64 is used. The dependency comes from Gnulib. Emacs uses the gnulib module 'nanosleep', and it picks the nanosleep function from libwinpthread-1.dll. I can reproduce this directly in Gnulib. Since this DLL dependency is an annoyance also for other people who produce Windows binaries (I'm thinking of gettext and others), I'll change Gnulib to avoid this dependency. > A more GNU-friendly way is > > objdump -p emacs.exe | fgrep "DLL Name:" Thanks; that's a nice shortcut, because I usually have 'objdump' in my $PATH. Bruno ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Windows port binaries 2023-08-17 14:01 ` Bruno Haible @ 2023-08-17 14:14 ` Eli Zaretskii 0 siblings, 0 replies; 24+ messages in thread From: Eli Zaretskii @ 2023-08-17 14:14 UTC (permalink / raw) To: Bruno Haible; +Cc: corwin, Emacs-devel, luangruo, eggert > From: Bruno Haible <bruno@clisp.org> > Cc: corwin@bru.st, Emacs-devel@gnu.org, luangruo@yahoo.com, eggert@cs.ucla.edu > Date: Thu, 17 Aug 2023 16:01:23 +0200 > > Eli Zaretskii wrote: > > > they rely on two DLLs which are not contained in the 'bin' directory: > > > - libgmp-10.dll > > > - libwinpthread-1.dll > > > > libwinpthread-1.dll shouldn't be there. ... > > But I'm not sure we can avoid this, when MinGW64 is used. > > The dependency comes from Gnulib. Emacs uses the gnulib module 'nanosleep', > and it picks the nanosleep function from libwinpthread-1.dll. I can reproduce > this directly in Gnulib. > > Since this DLL dependency is an annoyance also for other people who produce > Windows binaries (I'm thinking of gettext and others), I'll change Gnulib > to avoid this dependency. Thanks, but please allow MinGW to use its own implementation if time.h declares it and a test program calling it links without pthreads. At least mingw.org's MinGW does have nanosleep which doesn't need pthreads. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 2:49 ` boot-time: straighten code Paul Eggert 2023-08-13 3:26 ` Po Lu @ 2023-08-14 8:02 ` Andreas Schwab 2023-08-14 9:15 ` Bruno Haible 2023-08-15 21:12 ` Bruno Haible 2 siblings, 1 reply; 24+ messages in thread From: Andreas Schwab @ 2023-08-14 8:02 UTC (permalink / raw) To: Paul Eggert; +Cc: Bruno Haible, bug-gnulib, Emacs Development In file included from boot-time.c:47: readutmp.h:145:16: error: ‘__UT_USERSIZE’ undeclared here (not in a function); did you mean ‘UT_USER_SIZE’? 145 | char ut_user[__UT_USERSIZE]; /* Username. */ | ^~~~~~~~~~~~~ | UT_USER_SIZE make[3]: *** [Makefile:102: boot-time.o] Error 1 -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 8:02 ` boot-time: straighten code Andreas Schwab @ 2023-08-14 9:15 ` Bruno Haible 2023-08-14 9:20 ` Andreas Schwab 0 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-14 9:15 UTC (permalink / raw) To: Paul Eggert, Andreas Schwab; +Cc: bug-gnulib, Emacs Development Andreas Schwab wrote: > In file included from boot-time.c:47: > readutmp.h:145:16: error: ‘__UT_USERSIZE’ undeclared here (not in a function); did you mean ‘UT_USER_SIZE’? > 145 | char ut_user[__UT_USERSIZE]; /* Username. */ > | ^~~~~~~~~~~~~ > | UT_USER_SIZE > make[3]: *** [Makefile:102: boot-time.o] Error 1 On which distro or glibc version, please? Bruno ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 9:15 ` Bruno Haible @ 2023-08-14 9:20 ` Andreas Schwab 2023-08-14 10:19 ` Bruno Haible 0 siblings, 1 reply; 24+ messages in thread From: Andreas Schwab @ 2023-08-14 9:20 UTC (permalink / raw) To: Bruno Haible; +Cc: Paul Eggert, bug-gnulib, Emacs Development On Aug 14 2023, Bruno Haible wrote: > Andreas Schwab wrote: >> In file included from boot-time.c:47: >> readutmp.h:145:16: error: ‘__UT_USERSIZE’ undeclared here (not in a function); did you mean ‘UT_USER_SIZE’? >> 145 | char ut_user[__UT_USERSIZE]; /* Username. */ >> | ^~~~~~~~~~~~~ >> | UT_USER_SIZE >> make[3]: *** [Makefile:102: boot-time.o] Error 1 > > On which distro or glibc version, please? Any. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 9:20 ` Andreas Schwab @ 2023-08-14 10:19 ` Bruno Haible 2023-08-14 10:33 ` Andreas Schwab 0 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-14 10:19 UTC (permalink / raw) To: Andreas Schwab; +Cc: Paul Eggert, bug-gnulib, Emacs-devel Andreas Schwab wrote: > >> In file included from boot-time.c:47: > >> readutmp.h:145:16: error: ‘__UT_USERSIZE’ undeclared here (not in a function); did you mean ‘UT_USER_SIZE’? > >> 145 | char ut_user[__UT_USERSIZE]; /* Username. */ > >> | ^~~~~~~~~~~~~ > >> | UT_USER_SIZE > >> make[3]: *** [Makefile:102: boot-time.o] Error 1 > > > > On which distro or glibc version, please? > > Any. Ah, you mean: on any 32-bit build with glibc. Fixed through this patch: 2023-08-14 Bruno Haible <bruno@clisp.org> readutmp, boot-time: Fix build on 32-bit glibc (regression 2023-08-11). Reported by Andreas Schwab <schwab@suse.de> in <https://lists.gnu.org/archive/html/bug-gnulib/2023-08/msg00125.html>. * lib/readutmp.h (struct utmpx32): Reference __UT_NAMESIZE, not __UT_USERSIZE. diff --git a/lib/readutmp.h b/lib/readutmp.h index f7cad36d44..1fbe29d86f 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -142,7 +142,7 @@ struct utmpx32 pid_t ut_pid; /* Process ID of login process. */ char ut_line[__UT_LINESIZE]; /* Devicename. */ char ut_id[4]; /* Inittab ID. */ - char ut_user[__UT_USERSIZE]; /* Username. */ + char ut_user[__UT_NAMESIZE]; /* Username. */ char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 10:19 ` Bruno Haible @ 2023-08-14 10:33 ` Andreas Schwab 2023-08-14 13:51 ` Bruno Haible 0 siblings, 1 reply; 24+ messages in thread From: Andreas Schwab @ 2023-08-14 10:33 UTC (permalink / raw) To: Bruno Haible; +Cc: Paul Eggert, bug-gnulib, Emacs-devel On Aug 14 2023, Bruno Haible wrote: > diff --git a/lib/readutmp.h b/lib/readutmp.h > index f7cad36d44..1fbe29d86f 100644 > --- a/lib/readutmp.h > +++ b/lib/readutmp.h > @@ -142,7 +142,7 @@ struct utmpx32 > pid_t ut_pid; /* Process ID of login process. */ > char ut_line[__UT_LINESIZE]; /* Devicename. */ > char ut_id[4]; /* Inittab ID. */ > - char ut_user[__UT_USERSIZE]; /* Username. */ > + char ut_user[__UT_NAMESIZE]; /* Username. */ > char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ That's still using reserved symbols. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 10:33 ` Andreas Schwab @ 2023-08-14 13:51 ` Bruno Haible 2023-08-15 23:03 ` Paul Eggert 0 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-14 13:51 UTC (permalink / raw) To: Andreas Schwab; +Cc: Paul Eggert, bug-gnulib, Emacs-devel Andreas Schwab wrote: > > char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ > > That's still using reserved symbols. Fixed through the patch below. But that is just a workaround. Is someone among the glibc people looking at the original glibc bug https://sourceware.org/bugzilla/show_bug.cgi?id=30701 ? 2023-08-14 Bruno Haible <bruno@clisp.org> readutmp, boot-time: Don't use __UT_* symbols (regression 2023-08-11). * lib/readutmp.h (_GL_UT_USER_SIZE, _GL_UT_ID_SIZE, _GL_UT_LINE_SIZE, _GL_UT_HOST_SIZE): New macros. (struct utmpx32): Use them. diff --git a/lib/readutmp.h b/lib/readutmp.h index 1fbe29d86f..3ddecf3727 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -136,14 +136,18 @@ enum { UT_HOST_SIZE = -1 }; /* This is a near-copy of glibc's struct utmpx, which stops working after the year 2038. Unlike the glibc version, struct utmpx32 describes the file format even if time_t is 64 bits. */ +#define _GL_UT_USER_SIZE sizeof (((struct utmpx *) 0)->ut_user) +#define _GL_UT_ID_SIZE sizeof (((struct utmpx *) 0)->ut_id) +#define _GL_UT_LINE_SIZE sizeof (((struct utmpx *) 0)->ut_line) +#define _GL_UT_HOST_SIZE sizeof (((struct utmpx *) 0)->ut_host) struct utmpx32 { short int ut_type; /* Type of login. */ pid_t ut_pid; /* Process ID of login process. */ - char ut_line[__UT_LINESIZE]; /* Devicename. */ - char ut_id[4]; /* Inittab ID. */ - char ut_user[__UT_NAMESIZE]; /* Username. */ - char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ + char ut_line[_GL_UT_LINE_SIZE]; /* Devicename. */ + char ut_id[_GL_UT_ID_SIZE]; /* Inittab ID. */ + char ut_user[_GL_UT_USER_SIZE]; /* Username. */ + char ut_host[_GL_UT_HOST_SIZE]; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ /* The fields ut_session and ut_tv must be the same size when compiled ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-14 13:51 ` Bruno Haible @ 2023-08-15 23:03 ` Paul Eggert 0 siblings, 0 replies; 24+ messages in thread From: Paul Eggert @ 2023-08-15 23:03 UTC (permalink / raw) To: Bruno Haible, Andreas Schwab; +Cc: bug-gnulib, Emacs-devel On 2023-08-14 06:51, Bruno Haible wrote: > But that is just a workaround. Is someone among the glibc people looking at the > original glibc bughttps://sourceware.org/bugzilla/show_bug.cgi?id=30701 ? As far as I know, nobody is looking into it other than you and me. I think it's low priority as people are assuming that until 2038 nobody should use both _TIME_BITS=64 and utmp/utmpx on 32-bit x86 or arm, and by 2038 (when things also stop working on 64-bit x86-64 and arm64) utmp/utmpx will be gone anyway. Given the slow rate of progress in the Y2038 area I'm not sure this assumption is correct. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-13 2:49 ` boot-time: straighten code Paul Eggert 2023-08-13 3:26 ` Po Lu 2023-08-14 8:02 ` boot-time: straighten code Andreas Schwab @ 2023-08-15 21:12 ` Bruno Haible 2023-08-16 10:13 ` Bruno Haible 2 siblings, 1 reply; 24+ messages in thread From: Bruno Haible @ 2023-08-15 21:12 UTC (permalink / raw) To: Paul Eggert; +Cc: bug-gnulib, Emacs-devel Paul Eggert wrote: > I installed the attached patch into Emacs > master, which you should be able to test via: > > git clone https://git.savannah.gnu.org/git/emacs.git > cd emacs > ./autogen.sh > ./configure > make > src/emacs > > Please give it a try, especially on any MS-Windows platform you happen > to have. I have tested only on Ubuntu 23.04 so far. > > A simple way to test is to use Emacs to start editing a file (without > saving) and then inspect the symbolic link .#* that Emacs uses as a lock > file. The trailing digits of that link's contents should be the boot > time. These symlinks are Emacs's only use of boot time. Here are my test results. On each of the following platforms, after regenerating the current 'configure' file and then building the 'emacs' directory from today, with the configure options --disable-silent-rules --without-all --without-x then running "./emacs $HOME/hello.c", editing that buffer, opening a 'M-x shell' buffer, and looking at the $HOME/.#hello.c symlink, I can see that its last component is exactly the time_t value of the boot time, as displayed by the gnulib 'test-readutmp' test. So, the test passes on all these platforms: - Linux: Ubuntu 22.04, Alpine Linux - Debian GNU/Hurd 2022 - Debian GNU/kFreeBSD 7 - NetBSD 9.3 - OpenBSD 7.2 - Cygwin 2.9.0 I could not test the Windows binaries from corwin, due to problems mentioned in <https://lists.gnu.org/archive/html/emacs-devel/2023-08/msg00543.html>. Also, I could not test on Android (in Termux), due to a build failure, cf. <https://github.com/termux/termux-packages/issues/6592>. Bruno ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: boot-time: straighten code 2023-08-15 21:12 ` Bruno Haible @ 2023-08-16 10:13 ` Bruno Haible 0 siblings, 0 replies; 24+ messages in thread From: Bruno Haible @ 2023-08-16 10:13 UTC (permalink / raw) To: Paul Eggert; +Cc: bug-gnulib, Emacs-devel I wrote: > So, the test passes on all these platforms: > - Linux: Ubuntu 22.04, Alpine Linux > - Debian GNU/Hurd 2022 > - Debian GNU/kFreeBSD 7 > - NetBSD 9.3 > - OpenBSD 7.2 > - Cygwin 2.9.0 It passes also on Android 11, within the Termux app. (I now got past the build failure.) Bruno ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2023-08-17 14:14 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <4536176.VaOIPsP7d9@nimes> 2023-08-13 2:49 ` boot-time: straighten code Paul Eggert 2023-08-13 3:26 ` Po Lu 2023-08-13 6:35 ` Paul Eggert 2023-08-13 13:45 ` Bruno Haible 2023-08-13 14:16 ` Bruno Haible 2023-08-13 14:36 ` Bruno Haible 2023-08-13 23:44 ` Po Lu 2023-08-13 23:59 ` Bruno Haible 2023-08-14 1:07 ` Po Lu 2023-08-14 2:14 ` Corwin Brust 2023-08-15 19:57 ` Windows port binaries Bruno Haible 2023-08-16 6:45 ` Po Lu 2023-08-16 11:36 ` Eli Zaretskii 2023-08-17 14:01 ` Bruno Haible 2023-08-17 14:14 ` Eli Zaretskii 2023-08-14 8:02 ` boot-time: straighten code Andreas Schwab 2023-08-14 9:15 ` Bruno Haible 2023-08-14 9:20 ` Andreas Schwab 2023-08-14 10:19 ` Bruno Haible 2023-08-14 10:33 ` Andreas Schwab 2023-08-14 13:51 ` Bruno Haible 2023-08-15 23:03 ` Paul Eggert 2023-08-15 21:12 ` Bruno Haible 2023-08-16 10:13 ` Bruno Haible
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).