Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
5 changes: 4 additions & 1 deletion ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
17 changes: 13 additions & 4 deletions ci/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 9 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,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.
Expand Down Expand Up @@ -1350,7 +1358,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 #######################################################################
Expand Down
6 changes: 6 additions & 0 deletions libenv/sysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -3809,6 +3809,12 @@ static void SysOSNameHuman(EvalContext *ctx)
"Alpine", CF_DATA_TYPE_STRING,
"source=agent,derived-from=alpine");
}
else if (EvalContextClassGet(ctx, NULL, "termux") != NULL)
{
EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval,
"Termux", CF_DATA_TYPE_STRING,
"source=agent,derived-from=termux");
}
else if (EvalContextClassGet(ctx, NULL, "gentoo") != NULL)
{
EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval,
Expand Down
2 changes: 1 addition & 1 deletion libntech
11 changes: 6 additions & 5 deletions libpromises/dbm_test_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
included file COSL.txt.
*/

#ifndef __ANDROID__
#include <platform.h>
#include <stdlib.h> /* lrand48_r() */
#include <stdlib.h> /* lrand48() */
#include <unistd.h> /* usleep(), syscall()/gettid() */
#include <alloc.h> /* xstrndup() */
#include <dbm_api.h>
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -735,3 +735,4 @@ void RemoveFilament(DBFilament *filament)
free(filament);
CloseDB(db);
}
#endif /* not __ANDROID__ */
2 changes: 2 additions & 0 deletions libpromises/dbm_test_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
included file COSL.txt.
*/

#ifndef __ANDROID__
#ifndef CFENGINE_DBM_TEST_API_H
#define CFENGINE_DBM_TEST_API_H

Expand Down Expand Up @@ -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__ */
26 changes: 26 additions & 0 deletions libpromises/evalfunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include <version_comparison.h>
#include <mutex.h> /* ThreadWait */
#include <glob_lib.h>
#include <signal_lib.h> /* MaskTerminationSignalsInThread */

#include <math_eval.h>

Expand Down Expand Up @@ -9672,10 +9673,29 @@ 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);

#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)
Expand Down Expand Up @@ -9827,7 +9847,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");
Expand Down Expand Up @@ -9857,10 +9881,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);
}
Expand Down
62 changes: 31 additions & 31 deletions tests/acceptance/testall
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ workdir() {
}

# Example: fgrepvar 'word' VARNAME
# Silent fgrep for variables: search for "word" in $VARNAME
fgrepvar() {
eval echo \$$2 | fgrep "$1" > /dev/null
# Silent grep -F for variables: search for "word" in $VARNAME
fgrepvar(){
eval echo \$$2 | grep -F "$1" > /dev/null
}

# Same but instead of word search for a regex
Expand Down Expand Up @@ -524,22 +524,22 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR
echo "Return code is $RETVAL." >> "$WORKDIR/$LOG"

# Try to collect test metadata if any
if egrep "R: test description: " $OUTFILE > /dev/null
if grep -E "R: test description: " $OUTFILE > /dev/null
then
TEST_DESCRIPTION="$(egrep "R: test description" $OUTFILE | sed -e "s,.*test description: \([A-Za-z0-9_]*\),\1,")"
TEST_DESCRIPTION="$(grep -E "R: test description" $OUTFILE | sed -e "s,.*test description: \([A-Za-z0-9_]*\),\1,")"
fi
if egrep -e "R: test story_id: " $OUTFILE > /dev/null
if grep -E -e "R: test story_id: " $OUTFILE > /dev/null
then
TEST_STORY="$(egrep "R: test story_id" $OUTFILE | sed -e "s,.*test story_id: \([0-9][0-9]*\),\1,")"
TEST_STORY="$(grep -E "R: test story_id" $OUTFILE | sed -e "s,.*test story_id: \([0-9][0-9]*\),\1,")"
fi
if egrep -e "R: test covers: " $OUTFILE > /dev/null
if grep -E -e "R: test covers: " $OUTFILE > /dev/null
then
TEST_COVERS="$(egrep "R: test covers" $OUTFILE | sed -e "s,.*test covers: \([A-Za-z0-9_]*\),\1,")"
TEST_COVERS="$(grep -E "R: test covers" $OUTFILE | sed -e "s,.*test covers: \([A-Za-z0-9_]*\),\1,")"
fi

if [ $TEST_TYPE = errorexit ]
then
if [ $RETVAL -gt 0 ] && [ $RETVAL -lt 128 ] && egrep "error:|aborted on defined class" $OUTFILE > /dev/null
if [ $RETVAL -gt 0 ] && [ $RETVAL -lt 128 ] && grep -E "error:|aborted on defined class" $OUTFILE > /dev/null
then
RESULT=Pass
RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}"
Expand All @@ -557,7 +557,7 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR
then
RESULT=FAIL
RESULT_MSG="${COLOR_FAILURE}FAIL (NON-ZERO EXIT CODE!)${COLOR_NORMAL}"
elif fgrep 'error: ' "$OUTFILE" > /dev/null
elif grep -F 'error: ' "$OUTFILE" > /dev/null
then
RESULT=Pass
RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}"
Expand All @@ -575,21 +575,21 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR
# Some states are output by dcs.sub.cf, therefore check for both TEST
# prefix and dcs.sub.cf prefix.
ESCAPED_TEST="$(echo "($TEST|dcs.sub.cf)" | sed -e 's/\./\\./g')"
if egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE > /dev/null && ! egrep "R: .*$ESCAPED_TEST Wait/" $OUTFILE > /dev/null
if grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE > /dev/null && ! grep -E "R: .*$ESCAPED_TEST Wait/" $OUTFILE > /dev/null
then
# Check for passed outcome, which should not happen.
if egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep "R: .*$ESCAPED_TEST Pass" > /dev/null
if grep -E "R: .*$ESCAPED_TEST " $OUTFILE | grep -E "R: .*$ESCAPED_TEST Pass" > /dev/null
then
RESULT=FAIL
RESULT_MSG="${COLOR_FAILURE}FAIL (The test Passed, but failure was expected)${COLOR_NORMAL}"
elif egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep -v "R: .*$ESCAPED_TEST [XS]?FAIL" > /dev/null
elif grep -E "R: .*$ESCAPED_TEST " $OUTFILE | grep -E -v "R: .*$ESCAPED_TEST [XS]?FAIL" > /dev/null
then
# Other test case outcomes than fail. Should not happen.
RESULT=FAIL
RESULT_MSG="${COLOR_FAILURE}FAIL (Failure was expected, but the test had an unexpected test outcome, check test output, Pass/FAIL need to match exactly)${COLOR_NORMAL}"
else
TICKET="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*[XS]FAIL/\(.*\),\1,")"
RESULT="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*\([XS]FAIL\).*,\1,")"
TICKET="$(grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*[XS]FAIL/\(.*\),\1,")"
RESULT="$(grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*\([XS]FAIL\).*,\1,")"
if [ "$RESULT" = "XFAIL" ]
then
RESULT_MSG="${COLOR_WARNING}FAIL (Suppressed, $TICKET)${COLOR_NORMAL}"
Expand All @@ -600,38 +600,38 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR
elif [ $RETVAL -ne 0 ]
then
RESULT=FAIL
elif egrep "R: .*$ESCAPED_TEST FAIL/no_ticket_number" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST FAIL/no_ticket_number" $OUTFILE > /dev/null
then
RESULT=FAIL
RESULT_MSG="${COLOR_FAILURE}FAIL (Tried to suppress failure, but no issue number is provided)${COLOR_NORMAL}"
elif egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE > /dev/null
then
if [ -z "$NEXT_TIMEOUT_VAR" ]
then
RESULT=FAIL
RESULT_MSG="${COLOR_FAILURE}FAIL (Test tried to wait but is not in \"timed\" directory)${COLOR_NORMAL}"
else
WAIT_TIME=$(egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE | sed -e 's,.*Wait/\([0-9][0-9]*\).*,\1,')
WAIT_TIME=$(grep -E "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE | sed -e 's,.*Wait/\([0-9][0-9]*\).*,\1,')
eval $NEXT_TIMEOUT_VAR=$(($TEST_END_TIME+$WAIT_TIME))
RESULT=Wait
RESULT_MSG="Awaiting ($WAIT_TIME seconds)..."
fi
elif egrep "R: .*$ESCAPED_TEST Pass" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST Pass" $OUTFILE > /dev/null
then
RESULT=Pass
RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}"
elif egrep "R: .*$ESCAPED_TEST Skip/unsupported" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST Skip/unsupported" $OUTFILE > /dev/null
then
RESULT=Skip
RESULT_MSG="${COLOR_WARNING}Skipped (No platform support)${COLOR_NORMAL}"
elif egrep "R: .*$ESCAPED_TEST Skip/needs_work" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST Skip/needs_work" $OUTFILE > /dev/null
then
RESULT=Skip
RESULT_MSG="${COLOR_WARNING}Skipped (Test needs work)${COLOR_NORMAL}"
elif egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE > /dev/null
elif grep -E "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE > /dev/null
then
RESULT=FLAKEY
TICKET="$(egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE | sed -e "s,.*FLAKEY/\(.*\),\1,")"
TICKET="$(grep -E "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE | sed -e "s,.*FLAKEY/\(.*\),\1,")"
RESULT_MSG="${COLOR_WARNING}Flakey fail ($TICKET)${COLOR_NORMAL}"

else
Expand Down Expand Up @@ -1075,7 +1075,7 @@ fi

for addtest in $ALL_TESTS
do
if echo "$addtest" | fgrep "/timed/" > /dev/null
if echo "$addtest" | grep -F "/timed/" > /dev/null
then
if [ "$TIMED_TESTS" = 1 ]
then
Expand Down Expand Up @@ -1133,12 +1133,12 @@ print_header() {

print_footer() {
# Recalculate results since sub invocations may not have been recorded.
PASSED_TESTS=`egrep '^Pass ' $SUMMARY | wc -l | tr -d ' '`
FAILED_TESTS=`egrep '^(FAIL|XFAIL) ' $SUMMARY | wc -l | tr -d ' '`
SUPPRESSED_FAILURES=`egrep '^XFAIL ' $SUMMARY | wc -l | tr -d ' '`
SOFT_FAILURES=`egrep '^SFAIL ' $SUMMARY | wc -l | tr -d ' '`
FLAKEY_FAILURES=`egrep '^FLAKEY ' $SUMMARY | wc -l | tr -d ' '`
SKIPPED_TESTS=`egrep '^Skip ' $SUMMARY | wc -l | tr -d ' '`
PASSED_TESTS=`grep -E '^Pass ' $SUMMARY | wc -l | tr -d ' '`
FAILED_TESTS=`grep -E '^(FAIL|XFAIL) ' $SUMMARY | wc -l | tr -d ' '`
SUPPRESSED_FAILURES=`grep -E '^XFAIL ' $SUMMARY | wc -l | tr -d ' '`
SOFT_FAILURES=`grep -E '^SFAIL ' $SUMMARY | wc -l | tr -d ' '`
FLAKEY_FAILURES=`grep -E '^FLAKEY ' $SUMMARY | wc -l | tr -d ' '`
SKIPPED_TESTS=`grep -E '^Skip ' $SUMMARY | wc -l | tr -d ' '`

( echo
echo ======================================================================
Expand Down
Loading