pthread_cancel is not supported by Android Bionic C library pthread. Based on my searched information online, pthread_cancel sometimes is likely to lead to memory leaks and dead locks. If we use android NDK or standalone toolchain to cross complile sg3_utils, below failure appeared. "....aarch64-linux-android/bin/ld: cannot find -lpthread collect2: error: ld returned 1 exit status Makefile:990: recipe for target 'sgp_dd' failed" This patch is using signal to replace the cancel call when host_os is android system. Signed-off-by: beanhuo <beanhuo@xxxxxxxxxx> --- configure | 30 ++++++++++++++++++++++++++++++ configure.ac | 6 ++++++ src/Makefile.am | 4 ++++ src/sgp_dd.c | 17 +++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/configure b/configure index 9958be2..d9f23f2 100755 --- a/configure +++ b/configure @@ -635,6 +635,8 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +OS_ANDROID_FALSE +OS_ANDROID_TRUE OS_WIN32_CYGWIN_FALSE OS_WIN32_CYGWIN_TRUE OS_WIN32_MINGW_FALSE @@ -12292,6 +12294,21 @@ _ACEOF case "${host}" in + *-*-android*) + +cat >>confdefs.h <<_ACEOF +#define SG_ON_ANDROID 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SG_LIB_LINUX 1 +_ACEOF + + os_cflags='' + + os_libs='' + ;; *-*-linux-gnu*) cat >>confdefs.h <<_ACEOF @@ -12428,6 +12445,14 @@ else OS_WIN32_CYGWIN_FALSE= fi + if echo $host_os | grep 'android' > /dev/null; then + OS_ANDROID_TRUE= + OS_ANDROID_FALSE='#' +else + OS_ANDROID_TRUE='#' + OS_ANDROID_FALSE= +fi + # Check whether --enable-linuxbsg was given. if test "${enable_linuxbsg+set}" = set; then : @@ -12624,6 +12649,10 @@ if test -z "${OS_WIN32_CYGWIN_TRUE}" && test -z "${OS_WIN32_CYGWIN_FALSE}"; then as_fn_error $? "conditional \"OS_WIN32_CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${OS_ANDROID_TRUE}" && test -z "${OS_ANDROID_FALSE}"; then + as_fn_error $? "conditional \"OS_ANDROID\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -14211,6 +14240,7 @@ $as_echo X"$file" | cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff --git a/configure.ac b/configure.ac index 6c35d1a..cef0686 100644 --- a/configure.ac +++ b/configure.ac @@ -37,6 +37,11 @@ AC_CANONICAL_HOST AC_DEFINE_UNQUOTED(SG_LIB_BUILD_HOST, "${host}", [sg3_utils Build Host]) case "${host}" in + *-*-android*) + AC_DEFINE_UNQUOTED(SG_ON_ANDROID, 1, [sg3_utils on android]) + AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [sg3_utils on linux]) + AC_SUBST([os_cflags], ['']) + AC_SUBST([os_libs], ['']) ;; *-*-linux-gnu*) AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [sg3_utils on linux]) AC_SUBST([os_cflags], ['']) @@ -79,6 +84,7 @@ AM_CONDITIONAL(OS_OSF, [echo $host_os | grep '^osf' > /dev/null]) AM_CONDITIONAL(OS_SOLARIS, [echo $host_os | grep '^solaris' > /dev/null]) AM_CONDITIONAL(OS_WIN32_MINGW, [echo $host_os | grep '^mingw' > /dev/null]) AM_CONDITIONAL(OS_WIN32_CYGWIN, [echo $host_os | grep '^cygwin' > /dev/null]) +AM_CONDITIONAL(OS_ANDROID, [echo $host_os | grep 'android' > /dev/null]) AC_ARG_ENABLE([linuxbsg], AC_HELP_STRING([--disable-linuxbsg], [ignore linux bsg (sgv4) if present]), diff --git a/src/Makefile.am b/src/Makefile.am index 1012a78..daada79 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,7 +86,11 @@ sg_modes_LDADD = ../lib/libsgutils2.la @os_libs@ sg_opcodes_LDADD = ../lib/libsgutils2.la @os_libs@ +if OS_ANDROID +sgp_dd_LDADD = ../lib/libsgutils2.la @os_libs@ +else sgp_dd_LDADD = ../lib/libsgutils2.la @os_libs@ -lpthread +endif sg_persist_LDADD = ../lib/libsgutils2.la @os_libs@ diff --git a/src/sgp_dd.c b/src/sgp_dd.c index e154555..d59167c 100644 --- a/src/sgp_dd.c +++ b/src/sgp_dd.c @@ -1121,6 +1121,11 @@ process_flags(const char * arg, struct flags_t * fp) return 0; } +void +thread_exit_handler(int sig) +{ + pthread_exit(0); +} #define STR_SZ 1024 #define INOUTF_SZ 512 @@ -1147,6 +1152,14 @@ main(int argc, char * argv[]) int in_sect_sz, out_sect_sz, status, n, flags; void * vp; char ebuff[EBUFF_SZ]; +#if SG_ON_ANDROID + struct sigaction actions; + memset(&actions, 0, sizeof(actions)); + sigemptyset(&actions.sa_mask); + actions.sa_flags = 0; + actions.sa_handler = thread_exit_handler; + sigaction(SIGUSR1,&actions,NULL); +#endif memset(&rcoll, 0, sizeof(Rq_coll)); rcoll.bpt = DEF_BLOCKS_PER_TRANSFER; @@ -1629,7 +1642,11 @@ main(int argc, char * argv[]) } } +#if SG_ON_ANDROID + status = pthread_kill(sig_listen_thread_id, SIGUSR1); +#else status = pthread_cancel(sig_listen_thread_id); +#endif if (0 != status) err_exit(status, "pthread_cancel"); if (STDIN_FILENO != rcoll.infd) close(rcoll.infd); -- 2.7.4