about summary refs log tree commit homepage
path: root/lib/PublicInbox/xap_helper.h
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-08-30 05:10:45 +0000
committerEric Wong <e@80x24.org>2023-08-30 05:27:36 +0000
commitafc61ae0464000121f67414777f1feccfcce6d13 (patch)
tree9d93aaeaab2945cf718616eb9b4a8a18418afc92 /lib/PublicInbox/xap_helper.h
parent1bc05a93b7a7259fece20655e65220cdc05cce5d (diff)
downloadpublic-inbox-afc61ae0464000121f67414777f1feccfcce6d13.tar.gz
hdestroy on OpenBSD assumes each key in the table can be freed,
so use strdup to fulfil that requirement.

This behavior differs from tested behavior on glibc and FreeBSD,
as well as what I can see from reading the musl and NetBSD
source code.  OpenBSD may be the only relevant OS which requires
this workaround.
Diffstat (limited to 'lib/PublicInbox/xap_helper.h')
-rw-r--r--lib/PublicInbox/xap_helper.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/lib/PublicInbox/xap_helper.h b/lib/PublicInbox/xap_helper.h
index 92210511..17085adc 100644
--- a/lib/PublicInbox/xap_helper.h
+++ b/lib/PublicInbox/xap_helper.h
@@ -460,6 +460,16 @@ static enum exc_iter dump_roots_iter(struct req *req,
         return ITER_OK;
 }
 
+static char *hsearch_enter_key(char *s)
+{
+#if defined(__OpenBSD__) /* hdestroy frees each key */
+        char *ret = strdup(s);
+        if (!ret) perror("strdup");
+        return ret;
+#endif // glibc, musl, FreeBSD, NetBSD do not free keys
+        return s;
+}
+
 static bool cmd_dump_roots(struct req *req)
 {
         CLEANUP_DUMP_ROOTS struct dump_roots_tmp drt = {};
@@ -511,7 +521,8 @@ static bool cmd_dump_roots(struct req *req)
         }
         for (size_t i = 0; i < tot; ) {
                 ENTRY e;
-                e.key = drt.entries[i++];
+                e.key = hsearch_enter_key(drt.entries[i++]);
+                if (!e.key) return false;
                 e.data = drt.entries[i++];
                 if (!hsearch(e, ENTER)) {
                         warn("hsearch(%s => %s, ENTER)", e.key,