From cb70ddbb8d6cce50267dc51732eecd93d9bc70d4 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 8 Jul 2024 11:11:13 -0500 Subject: [PATCH 1/5] Adjusted use of pthreads for Android/Termux platform Android/Termux doesn't have pthread_cancel so use pthred_kill instead Ticket: CFE-4401 Changelog: title (cherry picked from commit ebd52a29238122c4bcc2f86d2313f9f4a258243c) (cherry picked from commit 1e965d3ce15697271dd554b0dafe89c320fe0fcf) --- configure.ac | 8 ++++++++ libpromises/evalfunction.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/configure.ac b/configure.ac index 96609095da..e68b44cf08 100644 --- a/configure.ac +++ b/configure.ac @@ -170,6 +170,14 @@ CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" +dnl ###################################################################### +dnl libpromises/evalfunction.c isreadable() uses pthread_cancel so check +dnl if available and reverts to pthread_kill if not. +dnl This check must come after ACX_PTHREAD is called so that CC, CFLAGS, +dnl and LIBS are appropriately set for the local pthreads situation. +dnl ###################################################################### +AC_CHECK_FUNCS([pthread_cancel]) + dnl ###################################################################### dnl Whether to build extensions as builtin extensions or a separate dnl plugin. The default is plugin. diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 2e925c03fa..b0532227f2 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -8668,7 +8668,11 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, "Read operation timed out, exceeded %ld seconds.", path, timeout); +#ifdef HAVE_PTHREAD_CANCEL ret = pthread_cancel(thread_data.thread); +#else + ret = pthread_kill(thread_data.thread, 0); +#endif if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to cancel thread"); @@ -8700,10 +8704,12 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, return FnFailure(); } +#ifdef HAVE_PTHREAD_CANCEL if (status == PTHREAD_CANCELED) { Log(LOG_LEVEL_DEBUG, "Thread was canceled"); } +#endif return result; } From bb794bf2a0f3afcedce71a11f6d6fd818540567f Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 26 Jul 2024 10:03:59 -0500 Subject: [PATCH 2/5] Take patch in downstream termux-packages project and adjust to use HAVE_PTHREAD_CANCEL instead of __ANDROID__ https://github.com/termux/termux-packages/blob/master/packages/cfengine/pthread_cancel.patch Ticket: CFE-4401 Changelog: none (cherry picked from commit 5cebd756944c9fd49b11c822bcfcdb734589a6c7) --- libpromises/evalfunction.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index b0532227f2..7c35129104 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -8513,10 +8513,27 @@ struct IsReadableThreadData FnCallResult result; }; +#ifndef HAVE_PTHREAD_CANCEL +#define PTHREAD_CANCELED ((void *)-1) +static void ThreadSignalHandler(int signum) +{ + pthread_exit(PTHREAD_CANCELED); +} +#endif + static void *IsReadableThreadRoutine(void *data) { assert(data != NULL); +#ifndef HAVE_PTHREAD_CANCEL + struct sigaction actions; + memset(&actions, 0, sizeof(actions)); + sigemptyset(&actions.sa_mask); + actions.sa_flags = 0; + actions.sa_handler = ThreadSignalHandler; + sigaction(SIGUSR2, &actions, NULL); +#endif + struct IsReadableThreadData *const thread_data = data; // Give main thread time to call pthread_cond_timedwait(3) @@ -8671,7 +8688,7 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, #ifdef HAVE_PTHREAD_CANCEL ret = pthread_cancel(thread_data.thread); #else - ret = pthread_kill(thread_data.thread, 0); + ret = pthread_kill(thread_data.thread, SIGUSR2); #endif if (ret != 0) { From c3504d35996a700048efc537cae04356bfc2f6b5 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:04:21 -0500 Subject: [PATCH 3/5] updated termux make/install instructions --- INSTALL | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index f58de97ab5..046eb76b4a 100644 --- a/INSTALL +++ b/INSTALL @@ -158,7 +158,8 @@ sudo apk add alpine-sdk lmdb-dev openssl-dev bison flex-dev acl-dev pcre2-dev au * Termux (2020-04-24) pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml -./autogen.sh --without-pam +LDFLAGS='-landroid-glob' ./autogen.sh --without-pam +make && make install * OSX (2021-10-20) From dd7fe679c6103a32b56fa8fea6e934ca37234559 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:04:52 -0500 Subject: [PATCH 4/5] help compilation from source on android termux platform --- libpromises/dbm_test_api.c | 2 ++ libpromises/dbm_test_api.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libpromises/dbm_test_api.c b/libpromises/dbm_test_api.c index def4d50b92..2d8f3d4007 100644 --- a/libpromises/dbm_test_api.c +++ b/libpromises/dbm_test_api.c @@ -22,6 +22,7 @@ included file COSL.txt. */ +#ifndef __ANDROID__ #include #include /* lrand48_r() */ #include /* usleep(), syscall()/gettid() */ @@ -735,3 +736,4 @@ void RemoveFilament(DBFilament *filament) free(filament); CloseDB(db); } +#endif /* not __ANDROID__ */ diff --git a/libpromises/dbm_test_api.h b/libpromises/dbm_test_api.h index ffda177d75..a6fe0ae63d 100644 --- a/libpromises/dbm_test_api.h +++ b/libpromises/dbm_test_api.h @@ -22,6 +22,7 @@ included file COSL.txt. */ +#ifndef __ANDROID__ #ifndef CFENGINE_DBM_TEST_API_H #define CFENGINE_DBM_TEST_API_H @@ -55,3 +56,4 @@ DBFilament *FillUpDB(dbid db_id, int usage_pct); void RemoveFilament(DBFilament *filament); #endif /* CFENGINE_DBM_TEST_API_H */ +#endif /* not __ANDROID__ */ From 0078633c2fdb08ccb160850d4e0f36349aab5b76 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:05:24 -0500 Subject: [PATCH 5/5] transition to MaskTerminationSignalsInThread() (from libntech soon) and SIGHUP --- libpromises/evalfunction.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 7c35129104..204c70bb5b 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -76,6 +76,7 @@ #include #include /* ThreadWait */ #include +#include /* MaskTerminationSignalsInThread */ #include @@ -8526,12 +8527,14 @@ static void *IsReadableThreadRoutine(void *data) assert(data != NULL); #ifndef HAVE_PTHREAD_CANCEL + MaskTerminationSignalsInThread(); struct sigaction actions; memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = ThreadSignalHandler; - sigaction(SIGUSR2, &actions, NULL); + sigaction(SIGHUP, &actions, NULL); + MaskTerminationSignalsInThread(); #endif struct IsReadableThreadData *const thread_data = data;