diff --git a/INSTALL b/INSTALL index 75dc6b27d6..6553789ff0 100644 --- a/INSTALL +++ b/INSTALL @@ -157,10 +157,12 @@ sudo apk add alpine-sdk lmdb-dev openssl-dev bison flex-dev acl-dev pcre2-dev au Note that in order for process promises to work you must install the procps package for a "proper" ps command instead of busybox. -* Termux (2020-04-24) +* Termux (2025-10-10) -pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml -./autogen.sh --without-pam +pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml binutils librsync +# maybe binutils-is-llvm - Use llvm as binutils instead of binutils to get ld +LDFLAGS='-landroid-glob' ./autogen.sh --without-pam --prefix=$PREFIX --with-workdir=$PREFIX/var/lib/cfengine --without-systemd-service --without-selinux-policy +make && make install * OSX (2021-10-20) diff --git a/ci/build.sh b/ci/build.sh index 3bd306e6e8..3e47dfc761 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -5,7 +5,10 @@ set -ex thisdir="$(dirname "$0")" cd "$thisdir"/.. -source /etc/os-release +if [ -f /etc/os-release ]; then + source /etc/os-release +fi + CFLAGS="-Wall" if [ "$ID" != "alpine" ]; then CFLAGS="$CFLAGS -Werror" diff --git a/ci/configure.sh b/ci/configure.sh index dc66f9f7ed..e47d02b6e1 100755 --- a/ci/configure.sh +++ b/ci/configure.sh @@ -4,15 +4,24 @@ set -ex thisdir="$(dirname "$0")" cd "$thisdir"/.. -OPTS="--enable-debug" +OPTS="--config-cache --enable-debug" -source /etc/os-release -if [ "$ID" = "alpine" ]; then - OPTS="" # we don't want --enable-debug so that libpromises/dbm_test_api is not built due to lack of srand48_r() and friends on alpine linux libmusl +if [ -f /etc/os-release ]; then + source /etc/os-release + if [ "$ID" = "alpine" ]; then + OPTS="" # we don't want --enable-debug so that libpromises/dbm_test_api is not built due to lack of srand48_r() and friends on alpine linux libmusl + fi fi if [ -n "$TERMUX_VERSION" ] || [ "$ID" = "alpine" ]; then OPTS="$OPTS --without-pam" fi +if [ -n "$TERMUX_VERSION" ]; then + export LDFLAGS+=" -landroid-glob" + OPTS="$OPTS --prefix=$PREFIX\ + --with-workdir=$PREFIX/var/lib/cfengine \ + --without-selinux-policy \ + --without-systemd-service" +fi ./autogen.sh $OPTS diff --git a/configure.ac b/configure.ac index ac3bc601e4..6544163a29 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,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. @@ -1347,7 +1355,7 @@ AC_CHECK_DECLS([FALLOC_FL_PUNCH_HOLE], [], [], [ ]) AC_CHECK_HEADERS([sys/sendfile.h]) AC_CHECK_FUNCS([sendfile]) -AC_CHECK_FUNCS([copy_file_range]) +AC_CHECK_DECL([copy_file_range]) dnl ####################################################################### diff --git a/libntech b/libntech index 90fa0bc2fa..0b42abd55b 160000 --- a/libntech +++ b/libntech @@ -1 +1 @@ -Subproject commit 90fa0bc2fa2404332c4ec04743b305cab65ac4cf +Subproject commit 0b42abd55bded89d45a5099d2546df838716cda9 diff --git a/libpromises/dbm_test_api.c b/libpromises/dbm_test_api.c index def4d50b92..0ea5ba94e7 100644 --- a/libpromises/dbm_test_api.c +++ b/libpromises/dbm_test_api.c @@ -22,8 +22,9 @@ included file COSL.txt. */ +#ifndef __ANDROID__ #include -#include /* lrand48_r() */ +#include /* lrand48() */ #include /* usleep(), syscall()/gettid() */ #include /* xstrndup() */ #include @@ -70,23 +71,22 @@ static void DBItemDestroy(DBItem *item) } } -static __thread struct drand48_data rng_data; static void InitializeRNG(long int seed) { - srand48_r(seed, &rng_data); + srand48(seed); } static long GetRandomNumber(long limit) { long rnd_val; - lrand48_r(&rng_data, &rnd_val); /* generates a value in the [0, 2^31) interval */ + rnd_val = lrand48(); const long random_max = ((0x80000000 - 1) / limit) * limit; while (rnd_val > random_max) { /* got a bad value past the greatest multiple of the limit interval, * retry (see "modulo bias" if this is unclear) */ - lrand48_r(&rng_data, &rnd_val); + rnd_val = lrand48(); } return rnd_val % limit; } @@ -735,3 +735,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__ */ diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 8dfcdc8e42..8571a61c55 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -86,6 +86,7 @@ #include #include /* ThreadWait */ #include +#include /* MaskTerminationSignalsInThread */ #include @@ -9774,10 +9775,32 @@ struct IsReadableThreadData bool success; }; +#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); +/* + * Termux environment has no pthread_cancel() so use MaskTerminationSignalsInThread() and pthread_kill() + */ +#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(SIGHUP, &actions, NULL); + MaskTerminationSignalsInThread(); +#endif + struct IsReadableThreadData *const thread_data = data; // Give main thread time to call pthread_cond_timedwait(3) @@ -9929,7 +9952,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, SIGUSR2); +#endif if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to cancel thread"); @@ -9959,10 +9986,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 FnReturnContext(success); }