From 925b435faf6c5c3971b74c00298f3dd679256d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 21 Mar 2022 13:04:36 +0200 Subject: [PATCH] portability: add qsort_r --- portability/meson.build | 1 + portability/qsort_r.c | 26 ++++++++++++++++++++++++++ portability/stdlib.h | 7 +++++++ 3 files changed, 34 insertions(+) create mode 100644 portability/qsort_r.c create mode 100644 portability/stdlib.h diff --git a/portability/meson.build b/portability/meson.build index ae8f6bc..d077345 100644 --- a/portability/meson.build +++ b/portability/meson.build @@ -9,6 +9,7 @@ check_functions = [ ['strlcpy', 'strlcpy.c', 'NEED_STRLCPY', 'string.h'], ['pipe2', 'pipe2.c', 'NEED_PIPE2', 'unistd.h'], ['mknodat', 'mknodat.c', 'NEED_MKNODAT', 'sys/stat.h'], + ['qsort_r', 'qsort_r.c', 'NEED_QSORT_R', 'stdlib.h'], ] diff --git a/portability/qsort_r.c b/portability/qsort_r.c new file mode 100644 index 0000000..7c5df27 --- /dev/null +++ b/portability/qsort_r.c @@ -0,0 +1,26 @@ +#include + +struct qsortr_ctx { + int (*compar)(const void *, const void *, void *); + void *arg; +}; + +static __thread struct qsortr_ctx *__ctx; + +static int cmp_wrapper(const void *a, const void *b) +{ + return __ctx->compar(a, b, __ctx->arg); +} + +void qsort_r(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg) +{ + struct qsortr_ctx ctx = { + .compar = compar, + .arg = arg, + }; + __ctx = &ctx; + qsort(base, nmemb, size, cmp_wrapper); + __ctx = 0; +} diff --git a/portability/stdlib.h b/portability/stdlib.h new file mode 100644 index 0000000..6254c7c --- /dev/null +++ b/portability/stdlib.h @@ -0,0 +1,7 @@ +#include_next + +#ifdef NEED_QSORT_R +void qsort_r(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg); +#endif