Taken from
https://git.savannah.gnu.org/cgit/gdbm.git/commit/?id=5be83b4c5da7c6a68817908b19f8925af09e9b2c
https://git.savannah.gnu.org/cgit/gdbm.git/commit/?id=6f165a8e1745dbd9b88f6fb6882dff7997cfdf74
https://git.savannah.gnu.org/cgit/gdbm.git/commit/?id=aa9baca52ad155ae501ba586ff7b08f4b08e5434
Can be removed with 1.26.

From 5be83b4c5da7c6a68817908b19f8925af09e9b2c Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org>
Date: Thu, 10 Apr 2025 17:31:56 +0300
Subject: Fix timeout calculation in lockwait signal test.

* tests/t_lockwait.c (runtest_signal): mark start time right
after setting alarm, not before it.
---
 tests/t_lockwait.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tests/t_lockwait.c b/tests/t_lockwait.c
index a5e74c8..3547af7 100644
--- a/tests/t_lockwait.c
+++ b/tests/t_lockwait.c
@@ -323,9 +323,6 @@ runtest_signal (struct timespec *ts)
       struct sigaction act;
       struct timeval now;
 
-      gettimeofday (&now, NULL);
-      start = tv_to_ms (&now);
-
       if (pipe (sig_fd))
 	{
 	  perror ("pipe");
@@ -341,6 +338,8 @@ runtest_signal (struct timespec *ts)
 	  return -1;
 	}
       alarm (ts_to_ms (&ts[1]) / MILLI);
+      gettimeofday (&now, NULL);
+      start = tv_to_ms (&now);
     }
 
   op.lock_wait = GDBM_LOCKWAIT_SIGNAL;
-- 
cgit v1.1

From 6f165a8e1745dbd9b88f6fb6882dff7997cfdf74 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org>
Date: Thu, 10 Apr 2025 21:07:41 +0300
Subject: More fixes to lockwait test

* tests/t_lockwait.c (sighan): Close fd.
(runtest_signal): compensate for alarm(2) second precision
---
 tests/t_lockwait.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/t_lockwait.c b/tests/t_lockwait.c
index 3547af7..b378819 100644
--- a/tests/t_lockwait.c
+++ b/tests/t_lockwait.c
@@ -170,6 +170,7 @@ static void
 sighan (int sig)
 {
   write (sig_fd[1], &sig, sizeof (sig));
+  close (sig_fd[1]);
 }
 
 static int runtest_retry (struct timespec *ts);
@@ -364,7 +365,8 @@ runtest_signal (struct timespec *ts)
 
       pfd.fd = sig_fd[0];
       pfd.events = POLLIN;
-      switch (poll (&pfd, 1, ts_to_ms (&ts[1]) - tv_to_ms (&now) + start)) {
+      switch (poll (&pfd, 1,
+		    ts_to_ms (&ts[1]) - tv_to_ms (&now) + start + MILLI)) {
       case 1:
 	break;
 
-- 
cgit v1.1

From aa9baca52ad155ae501ba586ff7b08f4b08e5434 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org>
Date: Fri, 11 Apr 2025 07:53:58 +0300
Subject: Adjust timeouts for setitimer interface in lockwait test.

* tests/t_lockwait.c: Setitimer (at least on some systems) restarts
the timer set by alarm(2). To calculate the ETA of SIGALRM, call
alarm after gdbm_open_ext returns.
---
 tests/t_lockwait.c | 66 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/tests/t_lockwait.c b/tests/t_lockwait.c
index b378819..dfae838 100644
--- a/tests/t_lockwait.c
+++ b/tests/t_lockwait.c
@@ -322,7 +322,6 @@ runtest_signal (struct timespec *ts)
   if (!(ts[1].tv_sec == 0 && ts[1].tv_nsec == 0))
     {
       struct sigaction act;
-      struct timeval now;
 
       if (pipe (sig_fd))
 	{
@@ -338,9 +337,6 @@ runtest_signal (struct timespec *ts)
 	  fprintf (stderr, "%s: sigaction: %s", progname, strerror (errno));
 	  return -1;
 	}
-      alarm (ts_to_ms (&ts[1]) / MILLI);
-      gettimeofday (&now, NULL);
-      start = tv_to_ms (&now);
     }
 
   op.lock_wait = GDBM_LOCKWAIT_SIGNAL;
@@ -354,42 +350,58 @@ runtest_signal (struct timespec *ts)
     }
   gdbm_close (dbf);
 
-  if (start > 0)
+  if (!(ts[1].tv_sec == 0 && ts[1].tv_nsec == 0))
     {
       struct pollfd pfd;
       struct timeval now;
-      int sig;
+      int n, t, sig;
 
-    restart:
+      alarm (ts_to_ms (&ts[1]) / MILLI);
       gettimeofday (&now, NULL);
+      start = tv_to_ms (&now);
 
       pfd.fd = sig_fd[0];
       pfd.events = POLLIN;
-      switch (poll (&pfd, 1,
-		    ts_to_ms (&ts[1]) - tv_to_ms (&now) + start + MILLI)) {
-      case 1:
-	break;
 
-      case 0:
-	fprintf (stderr, "%s: failed waiting for alarm\n", progname);
-	return 1;
-
-      default:
-	if (errno == EINTR) goto restart;
-	fprintf (stderr, "%s: poll: %s\n", progname, strerror (errno));
-	return 1;
-      }
-
-      if (read (sig_fd[0], &sig, sizeof (sig)) != sizeof (sig))
+      do
 	{
-	  fprintf (stderr, "%s: read: %s\n", progname, strerror (errno));
-	  return 1;
+	  gettimeofday (&now, NULL);
+	  t = ts_to_ms (&ts[1]) - tv_to_ms (&now) + start + MILLI;
+	  if (t < 0)
+	    {
+	      n = 0;
+	      break;
+	    }
 	}
-      close (sig_fd[0]);
-      if (sig != SIGALRM)
+      while ((n = poll (&pfd, 1, t)) == -1 && errno == EINTR);
+
+      switch (n)
 	{
-	  fprintf (stderr, "%s: unexpected data read\n", progname);
+	case 1:
+	  if (read (sig_fd[0], &sig, sizeof (sig)) != sizeof (sig))
+	    {
+	      fprintf (stderr, "%s: read: %s\n", progname, strerror (errno));
+	      return 1;
+	    }
+	  close (sig_fd[0]);
+	  if (sig != SIGALRM)
+	    {
+	      fprintf (stderr, "%s: unexpected data read\n", progname);
+	      return 1;
+	    }
+	  break;
+
+	case 0:
+	  fprintf (stderr, "%s: failed waiting for alarm\n", progname);
 	  return 1;
+
+	default:
+	  if (errno != EINTR)
+	    {
+	      fprintf (stderr, "%s: poll: %s\n",
+		       progname, strerror (errno));
+	      return 1;
+	    }
 	}
     }
 
-- 
cgit v1.1

