From adde4d1462dd4c0ac39f7856da3e0659434cb03a Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Thu, 3 Apr 2014 14:50:04 +0000
Subject: [PATCH] main/musl: backport hsearch from upstream

needed for drbd
---
 main/musl/APKBUILD        |  10 +-
 main/musl/hsearch-1.patch | 213 ++++++++++++++++++++++++++++++++++++++
 main/musl/hsearch-2.patch | 138 ++++++++++++++++++++++++
 3 files changed, 360 insertions(+), 1 deletion(-)
 create mode 100644 main/musl/hsearch-1.patch
 create mode 100644 main/musl/hsearch-2.patch

diff --git a/main/musl/APKBUILD b/main/musl/APKBUILD
index e8a48e32f7a5..c3bf4bb42eb2 100644
--- a/main/musl/APKBUILD
+++ b/main/musl/APKBUILD
@@ -2,7 +2,7 @@
 # Maintainer: Timo Teräs <timo.teras@iki.fi>
 pkgname=musl
 pkgver=1.0.0
-pkgrel=3
+pkgrel=4
 pkgdesc="the musl c library (libc) implementation"
 url="http://www.musl-libc.org/"
 arch="all"
@@ -17,6 +17,8 @@ source="http://www.musl-libc.org/releases/musl-$pkgver.tar.gz
 	0001-v1.0.0-to-2b74315d.patch
 	1001-add-basic-dns-record-parsing-functions.patch
 	1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
+	hsearch-1.patch
+	hsearch-2.patch
 
 	getopt_long.c
 	__stack_chk_fail_local.c
@@ -116,6 +118,8 @@ md5sums="e54664fdf211d27737e328c4462b545e  musl-1.0.0.tar.gz
 d081fc3424229c639e636be2dd00d221  0001-v1.0.0-to-2b74315d.patch
 a3810683ef61ac27e2f6ec9801280c81  1001-add-basic-dns-record-parsing-functions.patch
 e2bdd9d7d057c28c1f45c8930e40276a  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
+f82a3988422584cda506ca1ca59114ef  hsearch-1.patch
+6045d289d7b1b12c02ce583f407fdb17  hsearch-2.patch
 61c6c1e84ed1df82abbe6d75e90cf21c  getopt_long.c
 0df687757221bbb0fc1aa67f1bd646f9  __stack_chk_fail_local.c
 7b391300396e58fe9073866b5a80cfe8  getconf.c
@@ -125,6 +129,8 @@ sha256sums="1ad7f45d2972daff19c9e6a92714e6d70f4aad003cd8c3d1e6113432114c1a32  mu
 aa632b635d472d5a6a49800899ce34cddc89a63a489690faa683d08622b9cd60  0001-v1.0.0-to-2b74315d.patch
 758390768b1bc4159d56908ca332b9640cd0552ed3b4b2b8d4a6d499c54c11a1  1001-add-basic-dns-record-parsing-functions.patch
 2069f2de91fc584282fefef8618808f3182837ec3f09848028b9480cfc90d46f  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
+35c93d9e14fc136b6f31940425b43bb42de6ea64045b6cacb5fae41625049bb6  hsearch-1.patch
+c501b141a6d401dbb5a78ba3758a4b7c78907da11052878a2a73ca81554ef740  hsearch-2.patch
 d9b644ec20bc33e81a7c52b9fcf7973d835923a69faf50f03db45534b811bd96  getopt_long.c
 299a7d75a09de3e2e11e7fb4acc3182e4a14e868093d2f30938fce9bfcff13da  __stack_chk_fail_local.c
 530ea449f93d53fafcb377fa0a23a7564f2961e49c07a8fdef6c960110317301  getconf.c
@@ -134,6 +140,8 @@ sha512sums="c76cbfe60cbe9b1ceb1faedddf2dcce0f11c942c8f74e4f217efe63e8e1d7be70fcb
 e04f0f9de2859d18cb13aa8bfd839cc757aa9d835f133e46b48a760c7e689a92c641abe1e84dcaab6134c22500603e66d9a880f9b80b77e36a063348f5879878  0001-v1.0.0-to-2b74315d.patch
 dad965258daf69371b844f76bfe5a914b0eca0ca76f3fc340b8fd7acf598b5f87bbe6d68b1f43ed0293ee0ed3bfd85d5173ccc169aa6265646248d5b8a906708  1001-add-basic-dns-record-parsing-functions.patch
 afbec2ae86e3406cc4116b217ecee7fbd0b995c6635a455e6166cb04798968abbd5be33161e3bc19e2665cdec07a4249ca3b7c535da97922c03d8d6ac6535a76  1002-use-armv6-opcodes-for-atomics-if-targetting-such-arc.patch
+c226aec49a7935de3d31c708da7c3493a67153cc443c4b3fe534cbe4442bb66cc07aa73cd6a9651f3088b8951ad8849bc9adcba89ce9be26398ed7c51c5c1701  hsearch-1.patch
+43583e071487813b6f0f8759c92b2c1ef7523fd33076040e545cdd645e9a6aa4274611cb3b4a7b401f4a99b455cf7637c3dc26c97255bbde79c4eef900d2c224  hsearch-2.patch
 140f3f20d30bd95ebce8c41b8cc7f616c6cbedf4ea06c729c21014e74f6043796825cc40ebc5180620ea38173afdba23f09ebf6d8b11fa05440b14d23764fca9  getopt_long.c
 062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b  __stack_chk_fail_local.c
 d638cdd02371351190fd0545fb83f44b822fa8c930e9fb47ef93d32a1aaee27641f875e10fa2e9833f1a56dfc2055fb89932a89c88da3e2eb17529bca58f5182  getconf.c
diff --git a/main/musl/hsearch-1.patch b/main/musl/hsearch-1.patch
new file mode 100644
index 000000000000..ced1cc4af552
--- /dev/null
+++ b/main/musl/hsearch-1.patch
@@ -0,0 +1,213 @@
+From fe1ba7dbf187e34985896b40d469d84a7a4a98d0 Mon Sep 17 00:00:00 2001
+From: sin <sin@2f30.org>
+Date: Tue, 25 Mar 2014 16:37:51 +0000
+Subject: implement hcreate_r, hdestroy_r and hsearch_r
+
+the size and alignment of struct hsearch_data are matched to the glibc
+definition for binary compatibility. the members of the structure do
+not match, which should not be a problem as long as applications
+correctly treat the structure as opaque.
+
+unlike the glibc implementation, this version of hcreate_r does not
+require the caller to zero-fill the structure before use.
+---
+diff --git a/include/search.h b/include/search.h
+index 27f6107..02e407e 100644
+--- a/include/search.h
++++ b/include/search.h
+@@ -22,6 +22,18 @@ int hcreate(size_t);
+ void hdestroy(void);
+ ENTRY *hsearch(ENTRY, ACTION);
+ 
++#ifdef _GNU_SOURCE
++struct hsearch_data {
++	struct __tab *__tab;
++	unsigned int __unused1;
++	unsigned int __unused2;
++};
++
++int hcreate_r(size_t, struct hsearch_data *);
++void hdestroy_r(struct hsearch_data *);
++int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
++#endif
++
+ void insque(void *, void *);
+ void remque(void *);
+ 
+diff --git a/src/search/hsearch.c b/src/search/hsearch.c
+index 6fe5ced..88edb26 100644
+--- a/src/search/hsearch.c
++++ b/src/search/hsearch.c
+@@ -1,6 +1,8 @@
++#define _GNU_SOURCE
+ #include <stdlib.h>
+ #include <string.h>
+ #include <search.h>
++#include "libc.h"
+ 
+ /*
+ open addressing hash table with 2^n table size
+@@ -19,9 +21,17 @@ struct elem {
+ 	size_t hash;
+ };
+ 
+-static size_t mask;
+-static size_t used;
+-static struct elem *tab;
++struct __tab {
++	struct elem *elems;
++	size_t mask;
++	size_t used;
++};
++
++static struct hsearch_data htab;
++
++int __hcreate_r(size_t, struct hsearch_data *);
++void __hdestroy_r(struct hsearch_data *);
++int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+ 
+ static size_t keyhash(char *k)
+ {
+@@ -33,29 +43,29 @@ static size_t keyhash(char *k)
+ 	return h;
+ }
+ 
+-static int resize(size_t nel)
++static int resize(size_t nel, struct hsearch_data *htab)
+ {
+ 	size_t newsize;
+ 	size_t i, j;
+ 	struct elem *e, *newe;
+-	struct elem *oldtab = tab;
+-	struct elem *oldend = tab + mask + 1;
++	struct elem *oldtab = htab->__tab->elems;
++	struct elem *oldend = htab->__tab->elems + htab->__tab->mask + 1;
+ 
+ 	if (nel > MAXSIZE)
+ 		nel = MAXSIZE;
+ 	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
+-	tab = calloc(newsize, sizeof *tab);
+-	if (!tab) {
+-		tab = oldtab;
++	htab->__tab->elems = calloc(newsize, sizeof *htab->__tab->elems);
++	if (!htab->__tab->elems) {
++		htab->__tab->elems = oldtab;
+ 		return 0;
+ 	}
+-	mask = newsize - 1;
++	htab->__tab->mask = newsize - 1;
+ 	if (!oldtab)
+ 		return 1;
+ 	for (e = oldtab; e < oldend; e++)
+ 		if (e->item.key) {
+ 			for (i=e->hash,j=1; ; i+=j++) {
+-				newe = tab + (i & mask);
++				newe = htab->__tab->elems + (i & htab->__tab->mask);
+ 				if (!newe->item.key)
+ 					break;
+ 			}
+@@ -67,27 +77,21 @@ static int resize(size_t nel)
+ 
+ int hcreate(size_t nel)
+ {
+-	mask = 0;
+-	used = 0;
+-	tab = 0;
+-	return resize(nel);
++	return __hcreate_r(nel, &htab);
+ }
+ 
+ void hdestroy(void)
+ {
+-	free(tab);
+-	tab = 0;
+-	mask = 0;
+-	used = 0;
++	__hdestroy_r(&htab);
+ }
+ 
+-static struct elem *lookup(char *key, size_t hash)
++static struct elem *lookup(char *key, size_t hash, struct hsearch_data *htab)
+ {
+ 	size_t i, j;
+ 	struct elem *e;
+ 
+ 	for (i=hash,j=1; ; i+=j++) {
+-		e = tab + (i & mask);
++		e = htab->__tab->elems + (i & htab->__tab->mask);
+ 		if (!e->item.key ||
+ 		    (e->hash==hash && strcmp(e->item.key, key)==0))
+ 			break;
+@@ -97,22 +101,61 @@ static struct elem *lookup(char *key, size_t hash)
+ 
+ ENTRY *hsearch(ENTRY item, ACTION action)
+ {
++	ENTRY *e;
++
++	__hsearch_r(item, action, &e, &htab);
++	return e;
++}
++
++int __hcreate_r(size_t nel, struct hsearch_data *htab)
++{
++	int r;
++
++	htab->__tab = calloc(1, sizeof *htab->__tab);
++	if (!htab->__tab)
++		return 0;
++	r = resize(nel, htab);
++	if (r == 0) {
++		free(htab->__tab);
++		htab->__tab = 0;
++	}
++	return r;
++}
++weak_alias(__hcreate_r, hcreate_r);
++
++void __hdestroy_r(struct hsearch_data *htab)
++{
++	if (htab->__tab) free(htab->__tab->elems);
++	free(htab->__tab);
++	htab->__tab = 0;
++}
++weak_alias(__hdestroy_r, hdestroy_r);
++
++int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
++{
+ 	size_t hash = keyhash(item.key);
+-	struct elem *e = lookup(item.key, hash);
++	struct elem *e = lookup(item.key, hash, htab);
+ 
+-	if (e->item.key)
+-		return &e->item;
+-	if (action == FIND)
++	if (e->item.key) {
++		*retval = &e->item;
++		return 1;
++	}
++	if (action == FIND) {
++		*retval = 0;
+ 		return 0;
++	}
+ 	e->item = item;
+ 	e->hash = hash;
+-	if (++used > mask - mask/4) {
+-		if (!resize(2*used)) {
+-			used--;
++	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
++		if (!resize(2*htab->__tab->used, htab)) {
++			htab->__tab->used--;
+ 			e->item.key = 0;
++			*retval = 0;
+ 			return 0;
+ 		}
+-		e = lookup(item.key, hash);
++		e = lookup(item.key, hash, htab);
+ 	}
+-	return &e->item;
++	*retval = &e->item;
++	return 1;
+ }
++weak_alias(__hsearch_r, hsearch_r);
+--
+cgit v0.9.0.3-65-g4555
diff --git a/main/musl/hsearch-2.patch b/main/musl/hsearch-2.patch
new file mode 100644
index 000000000000..3f795dce8751
--- /dev/null
+++ b/main/musl/hsearch-2.patch
@@ -0,0 +1,138 @@
+From 141d3b5c2a93dd48096a13ce051d09eaf3ec0b4a Mon Sep 17 00:00:00 2001
+From: sin <sin@2f30.org>
+Date: Thu, 27 Mar 2014 11:20:17 +0000
+Subject: remove struct elem entirely from hsearch.c
+
+There are two changes here, both of which make sense to be done in a
+single patch:
+
+- Remove hash from struct elem and compute it at runtime wherever
+  necessary.
+- Eliminate struct elem and use ENTRY directly.
+
+As a result we cut down on the memory usage as each element in the
+hash table now contains only an ENTRY not an ENTRY + size_t for the
+hash. The downside is that the hash needs to be computed at runtime.
+---
+diff --git a/src/search/hsearch.c b/src/search/hsearch.c
+index 88edb26..5c89651 100644
+--- a/src/search/hsearch.c
++++ b/src/search/hsearch.c
+@@ -16,13 +16,8 @@ with the posix api items cannot be iterated and length cannot be queried
+ #define MINSIZE 8
+ #define MAXSIZE ((size_t)-1/2 + 1)
+ 
+-struct elem {
+-	ENTRY item;
+-	size_t hash;
+-};
+-
+ struct __tab {
+-	struct elem *elems;
++	ENTRY *entries;
+ 	size_t mask;
+ 	size_t used;
+ };
+@@ -47,26 +42,26 @@ static int resize(size_t nel, struct hsearch_data *htab)
+ {
+ 	size_t newsize;
+ 	size_t i, j;
+-	struct elem *e, *newe;
+-	struct elem *oldtab = htab->__tab->elems;
+-	struct elem *oldend = htab->__tab->elems + htab->__tab->mask + 1;
++	ENTRY *e, *newe;
++	ENTRY *oldtab = htab->__tab->entries;
++	ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
+ 
+ 	if (nel > MAXSIZE)
+ 		nel = MAXSIZE;
+ 	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
+-	htab->__tab->elems = calloc(newsize, sizeof *htab->__tab->elems);
+-	if (!htab->__tab->elems) {
+-		htab->__tab->elems = oldtab;
++	htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
++	if (!htab->__tab->entries) {
++		htab->__tab->entries = oldtab;
+ 		return 0;
+ 	}
+ 	htab->__tab->mask = newsize - 1;
+ 	if (!oldtab)
+ 		return 1;
+ 	for (e = oldtab; e < oldend; e++)
+-		if (e->item.key) {
+-			for (i=e->hash,j=1; ; i+=j++) {
+-				newe = htab->__tab->elems + (i & htab->__tab->mask);
+-				if (!newe->item.key)
++		if (e->key) {
++			for (i=keyhash(e->key),j=1; ; i+=j++) {
++				newe = htab->__tab->entries + (i & htab->__tab->mask);
++				if (!newe->key)
+ 					break;
+ 			}
+ 			*newe = *e;
+@@ -85,15 +80,14 @@ void hdestroy(void)
+ 	__hdestroy_r(&htab);
+ }
+ 
+-static struct elem *lookup(char *key, size_t hash, struct hsearch_data *htab)
++static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
+ {
+ 	size_t i, j;
+-	struct elem *e;
++	ENTRY *e;
+ 
+ 	for (i=hash,j=1; ; i+=j++) {
+-		e = htab->__tab->elems + (i & htab->__tab->mask);
+-		if (!e->item.key ||
+-		    (e->hash==hash && strcmp(e->item.key, key)==0))
++		e = htab->__tab->entries + (i & htab->__tab->mask);
++		if (!e->key || strcmp(e->key, key) == 0)
+ 			break;
+ 	}
+ 	return e;
+@@ -125,7 +119,7 @@ weak_alias(__hcreate_r, hcreate_r);
+ 
+ void __hdestroy_r(struct hsearch_data *htab)
+ {
+-	if (htab->__tab) free(htab->__tab->elems);
++	if (htab->__tab) free(htab->__tab->entries);
+ 	free(htab->__tab);
+ 	htab->__tab = 0;
+ }
+@@ -134,28 +128,27 @@ weak_alias(__hdestroy_r, hdestroy_r);
+ int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
+ {
+ 	size_t hash = keyhash(item.key);
+-	struct elem *e = lookup(item.key, hash, htab);
++	ENTRY *e = lookup(item.key, hash, htab);
+ 
+-	if (e->item.key) {
+-		*retval = &e->item;
++	if (e->key) {
++		*retval = e;
+ 		return 1;
+ 	}
+ 	if (action == FIND) {
+ 		*retval = 0;
+ 		return 0;
+ 	}
+-	e->item = item;
+-	e->hash = hash;
++	*e = item;
+ 	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
+ 		if (!resize(2*htab->__tab->used, htab)) {
+ 			htab->__tab->used--;
+-			e->item.key = 0;
++			e->key = 0;
+ 			*retval = 0;
+ 			return 0;
+ 		}
+ 		e = lookup(item.key, hash, htab);
+ 	}
+-	*retval = &e->item;
++	*retval = e;
+ 	return 1;
+ }
+ weak_alias(__hsearch_r, hsearch_r);
+--
+cgit v0.9.0.3-65-g4555
-- 
GitLab