* 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: 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: 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: 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-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: 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: 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
* 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
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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.