From: Po Lu Date: Fri, 20 Jan 2023 13:21:15 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=26f0dd508982b9680a3cc5d7c56d5f978e06dc8f;p=emacs.git Update Android port * src/android.c (android_run_select_thread, android_init_events) (android_select): Add alternative android_select implementation for API 16 and lower. * src/androidterm.c (handle_one_android_event): Fix use-after-frees. --- diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 38f1418c759..a6824cb2267 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -140,8 +140,9 @@ cp -- "$gnulib_srcdir"/lib/af_alg.h \ { test -z "$src" || cd "$src"; } && ./autogen.sh -# Finally, update the files in lib/ to xcompile/lib. -rsync -r "$src"/lib "$src"/xcompile +# Finally, copy gnulib stuff in lib/ to xcompile/lib. +rm -rf "$src"xcompile/lib +cp -r "$src"lib "$src"xcompile # Remove unnecessary files. -rm -f "$src"/xcompile/lib/*.mk.in "$src"/xcompile/lib/Makefile.in +rm -f "$src"xcompile/lib/*.mk.in "$src"xcompile/lib/Makefile.in diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h index fa15b1b25e8..6ecea98b54a 100644 --- a/lib/_Noreturn.h +++ b/lib/_Noreturn.h @@ -26,6 +26,11 @@ AIX system header files and several gnulib header files use precisely this syntax with 'extern'. */ # define _Noreturn [[noreturn]] +# elif (defined __clang__ && __clang_major__ < 16 \ + && defined _GL_WORK_AROUND_LLVM_BUG_59792) + /* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around + that rare LLVM bug, though you may get many false-alarm warnings. */ +# define _Noreturn # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ || (!defined __STRICT_ANSI__ \ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 66ba4a4adf9..96108982f6d 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -186,6 +186,7 @@ ANDROID_JAR = @ANDROID_JAR@ ANDROID_LIBS = @ANDROID_LIBS@ ANDROID_MIN_SDK = @ANDROID_MIN_SDK@ ANDROID_OBJ = @ANDROID_OBJ@ +ANDROID_SDK_18_OR_EARLIER = @ANDROID_SDK_18_OR_EARLIER@ APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ AR = @AR@ ARFLAGS = @ARFLAGS@ diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4 index 03cb0aec93f..d319645fd3f 100644 --- a/m4/canonicalize.m4 +++ b/m4/canonicalize.m4 @@ -1,4 +1,4 @@ -# canonicalize.m4 serial 37 +# canonicalize.m4 serial 38 dnl Copyright (C) 2003-2007, 2009-2023 Free Software Foundation, Inc. @@ -12,7 +12,8 @@ AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE], [ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) - AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + gl_CHECK_FUNCS_ANDROID([faccessat], [[#include ]]) AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) if test $ac_cv_func_canonicalize_file_name = no; then @@ -58,7 +59,8 @@ AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], [ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) - AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + gl_CHECK_FUNCS_ANDROID([faccessat], [[#include ]]) dnl On native Windows, we use _getcwd(), regardless whether getcwd() is dnl available through the linker option '-loldnames'. diff --git a/m4/euidaccess.m4 b/m4/euidaccess.m4 index f0eb5bde84a..7429779c152 100644 --- a/m4/euidaccess.m4 +++ b/m4/euidaccess.m4 @@ -1,4 +1,4 @@ -# euidaccess.m4 serial 16 +# euidaccess.m4 serial 17 dnl Copyright (C) 2002-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -32,7 +32,7 @@ AC_DEFUN([gl_FUNC_EUIDACCESS], # Prerequisites of lib/euidaccess.c. AC_DEFUN([gl_PREREQ_EUIDACCESS], [ dnl Prefer POSIX faccessat over non-standard euidaccess. - AC_CHECK_FUNCS_ONCE([faccessat]) + gl_CHECK_FUNCS_ANDROID([faccessat], [[#include ]]) dnl Try various other non-standard fallbacks. AC_CHECK_HEADERS([libgen.h]) AC_FUNC_GETGROUPS diff --git a/m4/faccessat.m4 b/m4/faccessat.m4 index 934c1f41546..958c4978b7d 100644 --- a/m4/faccessat.m4 +++ b/m4/faccessat.m4 @@ -1,4 +1,4 @@ -# serial 10 +# serial 11 # See if we need to provide faccessat replacement. dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. @@ -16,7 +16,7 @@ AC_DEFUN([gl_FUNC_FACCESSAT], dnl Persuade glibc to declare faccessat(). AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([faccessat]) + gl_CHECK_FUNCS_ANDROID([faccessat], [[#include ]]) if test $ac_cv_func_faccessat = no; then HAVE_FACCESSAT=0 else diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4 index 7a3ee863e3c..5356da40bae 100644 --- a/m4/fchmodat.m4 +++ b/m4/fchmodat.m4 @@ -1,4 +1,4 @@ -# fchmodat.m4 serial 7 +# fchmodat.m4 serial 8 dnl Copyright (C) 2004-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -97,6 +97,6 @@ AC_DEFUN([gl_FUNC_FCHMODAT], # Prerequisites of lib/fchmodat.c. AC_DEFUN([gl_PREREQ_FCHMODAT], [ - AC_CHECK_FUNCS_ONCE([readlinkat]) + gl_CHECK_FUNCS_ANDROID([readlinkat], [[#include ]]) : ]) diff --git a/m4/futimens.m4 b/m4/futimens.m4 index 3aaa10a0b52..8e997d6ea63 100644 --- a/m4/futimens.m4 +++ b/m4/futimens.m4 @@ -1,4 +1,4 @@ -# serial 9 +# serial 10 # See if we need to provide futimens replacement. dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. @@ -13,7 +13,7 @@ AC_DEFUN([gl_FUNC_FUTIMENS], AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([futimens]) + gl_CHECK_FUNCS_ANDROID([futimens], [[#include ]]) if test $ac_cv_func_futimens = no; then HAVE_FUTIMENS=0 else diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 index 9aaed202abe..bbd7c03bcba 100644 --- a/m4/getdelim.m4 +++ b/m4/getdelim.m4 @@ -1,4 +1,4 @@ -# getdelim.m4 serial 16 +# getdelim.m4 serial 17 dnl Copyright (C) 2005-2007, 2009-2023 Free Software Foundation, Inc. dnl @@ -18,7 +18,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], AC_CHECK_DECLS_ONCE([getdelim]) - AC_CHECK_FUNCS_ONCE([getdelim]) + gl_CHECK_FUNCS_ANDROID([getdelim], [[#include ]]) if test $ac_cv_func_getdelim = yes; then HAVE_GETDELIM=1 dnl Found it in some library. Verify that it works. diff --git a/m4/getline.m4 b/m4/getline.m4 index 03569f06b2c..f68fa3a1acf 100644 --- a/m4/getline.m4 +++ b/m4/getline.m4 @@ -1,4 +1,4 @@ -# getline.m4 serial 30 +# getline.m4 serial 31 dnl Copyright (C) 1998-2003, 2005-2007, 2009-2023 Free Software Foundation, dnl Inc. @@ -23,12 +23,9 @@ AC_DEFUN([gl_FUNC_GETLINE], AC_CHECK_DECLS_ONCE([getline]) - gl_getline_needs_run_time_check=no - AC_CHECK_FUNC([getline], - [dnl Found it in some library. Verify that it works. - gl_getline_needs_run_time_check=yes], - [am_cv_func_working_getline=no]) - if test $gl_getline_needs_run_time_check = yes; then + gl_CHECK_FUNCS_ANDROID([getline], [[#include ]]) + if test $ac_cv_func_getline = yes; then + dnl Found it in some library. Verify that it works. AC_CACHE_CHECK([for working getline function], [am_cv_func_working_getline], [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data @@ -85,6 +82,8 @@ AC_DEFUN([gl_FUNC_GETLINE], ]) ]) ]) + else + am_cv_func_working_getline=no fi if test $ac_cv_have_decl_getline = no; then diff --git a/m4/getloadavg.m4 b/m4/getloadavg.m4 index 79e420baae8..067f142abce 100644 --- a/m4/getloadavg.m4 +++ b/m4/getloadavg.m4 @@ -7,7 +7,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 10 +#serial 11 # Autoconf defines AC_FUNC_GETLOADAVG, but that is obsolescent. # New applications should use gl_GETLOADAVG instead. @@ -25,8 +25,9 @@ gl_save_LIBS=$LIBS # getloadavg is present in libc on glibc >= 2.2, Mac OS X, FreeBSD >= 2.0, # NetBSD >= 0.9, OpenBSD >= 2.0, Solaris >= 7. HAVE_GETLOADAVG=1 -AC_CHECK_FUNC([getloadavg], [], - [gl_func_getloadavg_done=no +gl_CHECK_FUNCS_ANDROID([getloadavg], [[#include ]]) +if test $ac_cv_func_getloadavg != yes; then + gl_func_getloadavg_done=no # Some systems with -lutil have (and need) -lkvm as well, some do not. # On Solaris, -lkvm requires nlist from -lelf, so check that first @@ -73,7 +74,8 @@ AC_CHECK_FUNC([getloadavg], [], AC_DEFINE([DGUX], [1], [Define to 1 for DGUX with .]) AC_CHECK_LIB([dgc], [dg_sys_info])]) fi - fi]) + fi +fi if test "x$gl_save_LIBS" = x; then GETLOADAVG_LIBS=$LIBS diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 2db3376b01e..fa814222ce8 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -38,6 +38,11 @@ AC_DEFUN([gl_COMMON_BODY], [ AIX system header files and several gnulib header files use precisely this syntax with 'extern'. */ # define _Noreturn [[noreturn]] +# elif (defined __clang__ && __clang_major__ < 16 \ + && defined _GL_WORK_AROUND_LLVM_BUG_59792) + /* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around + that rare LLVM bug, though you may get many false-alarm warnings. */ +# define _Noreturn # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ || (!defined __STRICT_ANSI__ \ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 501fe20f4e5..1e4eccff712 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -28,7 +28,7 @@ # other built files. -# This macro should be invoked from ./configure.ac, in the section +# This macro should be invoked from .//configure.ac, in the section # "Checks for programs", right after AC_PROG_CC, and certainly before # any checks for libraries, header files, types and library functions. AC_DEFUN([gl_EARLY], @@ -214,7 +214,7 @@ AC_DEFUN([gl_EARLY], # Code from module xalloc-oversized: ]) -# This macro should be invoked from ./configure.ac, in the section +# This macro should be invoked from .//configure.ac, in the section # "Check for header files, types and library functions". AC_DEFUN([gl_INIT], [ @@ -252,7 +252,7 @@ AC_DEFUN([gl_INIT], gl_STDLIB_MODULE_INDICATOR([canonicalize_file_name]) gl_STDLIB_MODULE_INDICATOR([realpath]) AC_REQUIRE([AC_C_RESTRICT]) - AC_CHECK_FUNCS_ONCE([readlinkat]) + gl_CHECK_FUNCS_ANDROID([readlinkat], [[#include ]]) gl_CLOCK_TIME gl_MODULE_INDICATOR([close-stream]) gl_FUNC_COPY_FILE_RANGE diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4 index 55bee2ab7a2..d663b671749 100644 --- a/m4/mempcpy.m4 +++ b/m4/mempcpy.m4 @@ -1,4 +1,4 @@ -# mempcpy.m4 serial 12 +# mempcpy.m4 serial 13 dnl Copyright (C) 2003-2004, 2006-2007, 2009-2023 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation @@ -14,7 +14,7 @@ AC_DEFUN([gl_FUNC_MEMPCPY], AC_REQUIRE([AC_C_RESTRICT]) AC_REQUIRE([gl_STRING_H_DEFAULTS]) - AC_CHECK_FUNCS([mempcpy]) + gl_CHECK_FUNCS_ANDROID([mempcpy], [[#include ]]) if test $ac_cv_func_mempcpy = no; then HAVE_MEMPCPY=0 fi diff --git a/m4/mkostemp.m4 b/m4/mkostemp.m4 index a7cfac4cb87..9424f85f430 100644 --- a/m4/mkostemp.m4 +++ b/m4/mkostemp.m4 @@ -1,4 +1,4 @@ -# mkostemp.m4 serial 2 +# mkostemp.m4 serial 3 dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,7 +11,7 @@ AC_DEFUN([gl_FUNC_MKOSTEMP], dnl Persuade glibc to declare mkostemp(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([mkostemp]) + gl_CHECK_FUNCS_ANDROID([mkostemp], [[#include ]]) if test $ac_cv_func_mkostemp != yes; then HAVE_MKOSTEMP=0 fi diff --git a/m4/nproc.m4 b/m4/nproc.m4 index 3065b7b9bff..c892ad74b7d 100644 --- a/m4/nproc.m4 +++ b/m4/nproc.m4 @@ -1,4 +1,4 @@ -# nproc.m4 serial 5 +# nproc.m4 serial 6 dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -25,8 +25,8 @@ AC_DEFUN([gl_PREREQ_NPROC], #endif ]) - AC_CHECK_FUNCS([sched_getaffinity sched_getaffinity_np \ - pstat_getdynamic sysmp sysctl]) + AC_CHECK_FUNCS([sched_getaffinity_np pstat_getdynamic sysmp sysctl]) + gl_CHECK_FUNCS_ANDROID([sched_getaffinity], [[#include ]]) dnl Test whether sched_getaffinity has the expected declaration. dnl glibc 2.3.[0-2]: diff --git a/m4/pipe2.m4 b/m4/pipe2.m4 index 501f3a4303d..c7ec02e8736 100644 --- a/m4/pipe2.m4 +++ b/m4/pipe2.m4 @@ -1,4 +1,4 @@ -# pipe2.m4 serial 2 +# pipe2.m4 serial 3 dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,7 +11,7 @@ AC_DEFUN([gl_FUNC_PIPE2], dnl Persuade glibc to declare pipe2(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([pipe2]) + gl_CHECK_FUNCS_ANDROID([pipe2], [[#include ]]) if test $ac_cv_func_pipe2 != yes; then HAVE_PIPE2=0 fi diff --git a/m4/readlinkat.m4 b/m4/readlinkat.m4 index ffd0b8e9bc1..416f9c0d640 100644 --- a/m4/readlinkat.m4 +++ b/m4/readlinkat.m4 @@ -1,4 +1,4 @@ -# serial 6 +# serial 7 # See if we need to provide readlinkat replacement. dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. @@ -12,7 +12,7 @@ AC_DEFUN([gl_FUNC_READLINKAT], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([readlinkat]) + gl_CHECK_FUNCS_ANDROID([readlinkat], [[#include ]]) AC_REQUIRE([gl_FUNC_READLINK]) if test $ac_cv_func_readlinkat = no; then HAVE_READLINKAT=0 diff --git a/m4/stpcpy.m4 b/m4/stpcpy.m4 index e8a76bc34f3..462f511d25d 100644 --- a/m4/stpcpy.m4 +++ b/m4/stpcpy.m4 @@ -1,4 +1,4 @@ -# stpcpy.m4 serial 9 +# stpcpy.m4 serial 10 dnl Copyright (C) 2002, 2007, 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -13,7 +13,7 @@ AC_DEFUN([gl_FUNC_STPCPY], AC_REQUIRE([AC_C_RESTRICT]) AC_REQUIRE([gl_STRING_H_DEFAULTS]) - AC_CHECK_FUNCS([stpcpy]) + gl_CHECK_FUNCS_ANDROID([stpcpy], [[#include ]]) if test $ac_cv_func_stpcpy = no; then HAVE_STPCPY=0 fi diff --git a/m4/timegm.m4 b/m4/timegm.m4 index 6079f1a39c8..fa84e98db3e 100644 --- a/m4/timegm.m4 +++ b/m4/timegm.m4 @@ -1,4 +1,4 @@ -# timegm.m4 serial 13 +# timegm.m4 serial 14 dnl Copyright (C) 2003, 2007, 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -9,7 +9,7 @@ AC_DEFUN([gl_FUNC_TIMEGM], AC_REQUIRE([gl_TIME_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_MKTIME_WORKS]) REPLACE_TIMEGM=0 - AC_CHECK_FUNCS_ONCE([timegm]) + gl_CHECK_FUNCS_ANDROID([timegm], [[#include ]]) if test $ac_cv_func_timegm = yes; then if test "$gl_cv_func_working_mktime" != yes; then # Assume that timegm is buggy if mktime is. diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index dd799ae27db..f4384027e37 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -50,7 +50,6 @@ AC_DEFUN_ONCE([gl_UNISTD_H], group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite readlink readlinkat rmdir sethostname sleep symlink symlinkat truncate ttyname_r unlink unlinkat usleep]) - gl_CHECK_FUNCS_ANDROID([ftruncate], [[#include ]]) AC_REQUIRE([AC_C_RESTRICT]) diff --git a/m4/utimens.m4 b/m4/utimens.m4 index 2b87f0149b5..5f8606167a6 100644 --- a/m4/utimens.m4 +++ b/m4/utimens.m4 @@ -3,7 +3,7 @@ dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -dnl serial 12 +dnl serial 15 AC_DEFUN([gl_UTIMENS], [ @@ -11,10 +11,11 @@ AC_DEFUN([gl_UTIMENS], AC_REQUIRE([gl_FUNC_UTIMES]) AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CHECK_FUNCS_ONCE([futimens lutimes]) - gl_CHECK_FUNCS_ANDROID([utimensat], [[#include ]]) gl_CHECK_FUNCS_ANDROID([futimes], [[#include ]]) gl_CHECK_FUNCS_ANDROID([futimesat], [[#include ]]) + gl_CHECK_FUNCS_ANDROID([lutimes], [[#include ]]) + gl_CHECK_FUNCS_ANDROID([futimens], [[#include ]]) + gl_CHECK_FUNCS_ANDROID([utimensat], [[#include ]]) if test $ac_cv_func_futimens = no && test $ac_cv_func_futimesat = yes; then dnl FreeBSD 8.0-rc2 mishandles futimesat(fd,NULL,time). It is not diff --git a/m4/utimensat.m4 b/m4/utimensat.m4 index f92fc3af7d1..1d3db2efa23 100644 --- a/m4/utimensat.m4 +++ b/m4/utimensat.m4 @@ -1,4 +1,4 @@ -# serial 9 +# serial 10 # See if we need to provide utimensat replacement. dnl Copyright (C) 2009-2023 Free Software Foundation, Inc. @@ -13,8 +13,6 @@ AC_DEFUN([gl_FUNC_UTIMENSAT], AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - # This is necessary for cross-compiles, because otherwise utimensat - # will appear to work. gl_CHECK_FUNCS_ANDROID([utimensat], [[#include ]]) if test $ac_cv_func_utimensat = no; then HAVE_UTIMENSAT=0 diff --git a/src/android.c b/src/android.c index 43ac3b3f754..47120a6b5f5 100644 --- a/src/android.c +++ b/src/android.c @@ -257,30 +257,88 @@ static struct android_event_queue event_queue; /* Semaphores used to signal select completion and start. */ static sem_t android_pselect_sem, android_pselect_start_sem; +#if __ANDROID_API__ < 16 + +/* Select self-pipe. */ +static int select_pipe[2]; + +#endif + static void * android_run_select_thread (void *data) { + int rc; +#if __ANDROID_API__ < 16 + int nfds; + fd_set readfds; + char byte; +#else sigset_t signals, waitset; - int rc, sig; - - sigfillset (&signals); +#endif #if __ANDROID_API__ < 16 - /* sigprocmask must be used instead of pthread_sigmask due to a bug - in Android versions earlier than 16. It only affects the calling - thread on Android anyhow. */ + /* A completely different implementation is used when building for + Android versions earlier than 16, because pselect with a signal + mask does not work there. Instead of blocking SIGUSR1 and + unblocking it inside pselect, a file descriptor is used instead. + Something is written to the file descriptor every time select is + supposed to return. */ - if (sigprocmask (SIG_BLOCK, &signals, NULL)) - __android_log_print (ANDROID_LOG_FATAL, __func__, - "sigprocmask: %s", - strerror (errno)); + while (true) + { + /* Wait for the thread to be released. */ + while (sem_wait (&android_pselect_start_sem) < 0) + ;; + + /* Get the select lock and call pselect. API 8 does not have + working pselect in any sense. Instead, pselect wakes up on + select_pipe[0]. */ + + pthread_mutex_lock (&event_queue.select_mutex); + nfds = android_pselect_nfds; + readfds = *android_pselect_readfds; + + if (nfds < select_pipe[0] + 1) + nfds = select_pipe[0] + 1; + FD_SET (select_pipe[0], &readfds); + + rc = pselect (nfds, &readfds, + android_pselect_writefds, + android_pselect_exceptfds, + android_pselect_timeout, + NULL); + + /* Subtract 1 from rc if writefds contains the select pipe. */ + if (FD_ISSET (select_pipe[0], + android_pselect_writefds)) + rc -= 1; + + android_pselect_rc = rc; + pthread_mutex_unlock (&event_queue.select_mutex); + + /* Signal the main thread that there is now data to read. + It is ok to signal this condition variable without holding + the event queue lock, because android_select will always + wait for this to complete before returning. */ + android_pselect_completed = true; + pthread_cond_signal (&event_queue.read_var); + + /* Read a single byte from the select pipe. */ + read (select_pipe[0], &byte, 1); + + + /* Signal the Emacs thread that pselect is done. If read_var + was signaled by android_write_event, event_queue.mutex could + still be locked, so this must come before. */ + sem_post (&android_pselect_sem); + } #else if (pthread_sigmask (SIG_BLOCK, &signals, NULL)) __android_log_print (ANDROID_LOG_FATAL, __func__, "pthread_sigmask: %s", strerror (errno)); -#endif + sigfillset (&signals); sigdelset (&signals, SIGUSR1); sigemptyset (&waitset); sigaddset (&waitset, SIGUSR1); @@ -321,10 +379,13 @@ android_run_select_thread (void *data) still be locked, so this must come before. */ sem_post (&android_pselect_sem); } +#endif return NULL; } +#if __ANDROID_API__ >= 16 + static void android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) { @@ -332,6 +393,8 @@ android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) sure the disposition of SIGUSR1 is enough. */ } +#endif + /* Set up the global event queue by initializing the mutex and two condition variables, and the linked list of events. This must be called before starting the Emacs thread. Also, initialize the @@ -366,12 +429,29 @@ android_init_events (void) event_queue.events.next = &event_queue.events; event_queue.events.last = &event_queue.events; +#if __ANDROID_API__ >= 16 + /* Before starting the select thread, make sure the disposition for SIGUSR1 is correct. */ sigfillset (&sa.sa_mask); sa.sa_sigaction = android_handle_sigusr1; sa.sa_flags = SA_SIGINFO; +#else + + /* Set up the file descriptor used to wake up pselect. */ + if (pipe2 (select_pipe, O_CLOEXEC) < 0) + __android_log_print (ANDROID_LOG_FATAL, __func__, + "pipe2: %s", strerror (errno)); + + /* Make sure the read end will fit in fd_set. */ + if (select_pipe[0] >= FD_SETSIZE) + __android_log_print (ANDROID_LOG_FATAL, __func__, + "read end of select pipe" + " lies outside FD_SETSIZE!"); + +#endif + if (sigaction (SIGUSR1, &sa, NULL)) __android_log_print (ANDROID_LOG_FATAL, __func__, "sigaction: %s", @@ -479,6 +559,7 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timespec *timeout) { int nfds_return; + static char byte; pthread_mutex_lock (&event_queue.mutex); @@ -505,9 +586,16 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds, /* Start waiting for the event queue condition to be set. */ pthread_cond_wait (&event_queue.read_var, &event_queue.mutex); +#if __ANDROID_API__ >= 16 /* Interrupt the select thread now, in case it's still in pselect. */ pthread_kill (event_queue.select_thread, SIGUSR1); +#else + /* Interrupt the select thread by writing to the select pipe. */ + if (write (select_pipe[1], &byte, 1) != 1) + __android_log_print (ANDROID_LOG_FATAL, __func__, + "write: %s", strerror (errno)); +#endif /* Wait for pselect to return in any case. */ while (sem_wait (&android_pselect_sem) < 0) @@ -4425,8 +4513,6 @@ android_project_image_nearest (struct android_image *image, int android_ftruncate (int fd, off_t length) { - int rc; - #if defined __arm__ || defined __mips__ return syscall (SYS_ftruncate64, fd, 0, (unsigned int) (length & 0xffffffff), diff --git a/src/androidterm.c b/src/androidterm.c index 3024890d789..1141f50f266 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -966,6 +966,7 @@ handle_one_android_event (struct android_display_info *dpyinfo, touchpoint->x = event->touch.x; touchpoint->y = event->touch.x; touchpoint->next = FRAME_OUTPUT_DATA (any)->touch_points; + touchpoint->tool_bar_p = false; FRAME_OUTPUT_DATA (any)->touch_points = touchpoint; /* Figure out whether or not the tool was pressed on the tool @@ -1072,13 +1073,10 @@ handle_one_android_event (struct android_display_info *dpyinfo, { *last = touchpoint->next; - /* The tool was unlinked. Free it and generate the - appropriate Emacs event (assuming that it was not - grabbed by the tool bar). */ - xfree (touchpoint); - if (touchpoint->tool_bar_p) { + xfree (touchpoint); + /* Do what is necessary to release the tool bar and possibly trigger a click. */ @@ -1094,6 +1092,11 @@ handle_one_android_event (struct android_display_info *dpyinfo, goto OTHER; } + /* The tool was unlinked. Free it and generate the + appropriate Emacs event (assuming that it was not + grabbed by the tool bar). */ + xfree (touchpoint); + inev.ie.kind = TOUCHSCREEN_END_EVENT; inev.ie.timestamp = event->touch.time;