diff --git a/pkgs/by-name/gd/gdbm/package.nix b/pkgs/by-name/gd/gdbm/package.nix index 92f9e48eaefc..8edf67ea8926 100644 --- a/pkgs/by-name/gd/gdbm/package.nix +++ b/pkgs/by-name/gd/gdbm/package.nix @@ -15,6 +15,12 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-0C2zxZJu2Hf4gXuBzR+S9T73TKjG21Q/u6AnGzTzk+w="; }; + patches = [ + # Remove on next release. + ./upstream-darwin-clock-nanosleep-fix.patch + ./upstream-lockwait-test-fixes.patch + ]; + nativeBuildInputs = [ updateAutotoolsGnuConfigScriptsHook ]; configureFlags = [ (lib.enableFeature true "libgdbm-compat") ]; diff --git a/pkgs/by-name/gd/gdbm/upstream-darwin-clock-nanosleep-fix.patch b/pkgs/by-name/gd/gdbm/upstream-darwin-clock-nanosleep-fix.patch new file mode 100644 index 000000000000..cbc1045305b7 --- /dev/null +++ b/pkgs/by-name/gd/gdbm/upstream-darwin-clock-nanosleep-fix.patch @@ -0,0 +1,26 @@ +From ed0a865345681982ea02c6159c0f3d7702c928a1 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Thu, 27 Mar 2025 20:29:10 +0200 +Subject: Use nanosleep instead of clock_nanosleep + +The latter is not available on macOS +--- + src/lock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lock.c b/src/lock.c +index a43d9c3..cf28478 100644 +--- a/src/lock.c ++++ b/src/lock.c +@@ -291,7 +291,7 @@ _gdbm_lockwait_retry (GDBM_FILE dbf, struct timespec const *ts, + if (timespec_cmp (&ttw, iv) < 0) + break; + timespec_sub (&ttw, iv); +- if (clock_nanosleep (CLOCK_REALTIME, 0, iv, &r)) ++ if (nanosleep (iv, &r)) + { + if (errno == EINTR) + timespec_add (&ttw, &r); +-- +cgit v1.2.3 + diff --git a/pkgs/by-name/gd/gdbm/upstream-lockwait-test-fixes.patch b/pkgs/by-name/gd/gdbm/upstream-lockwait-test-fixes.patch new file mode 100644 index 000000000000..1bf42fde28fb --- /dev/null +++ b/pkgs/by-name/gd/gdbm/upstream-lockwait-test-fixes.patch @@ -0,0 +1,192 @@ +From 5be83b4c5da7c6a68817908b19f8925af09e9b2c Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +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.2.3 + +From 6f165a8e1745dbd9b88f6fb6882dff7997cfdf74 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +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.2.3 + +From aa9baca52ad155ae501ba586ff7b08f4b08e5434 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +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.2.3 +