~ chicken-core (chicken-5) d152736aac8dcb9b3d5a5dd0254351ad32e1d9c6


commit d152736aac8dcb9b3d5a5dd0254351ad32e1d9c6
Author:     felix <address@hidden>
AuthorDate: Wed Dec 18 14:36:16 2013 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Mon Jan 20 15:35:38 2014 +0100

    Added Android-specific changes to posix-unit and runtime and added a simple makefile.
    
    Signed-off-by: Peter Bex <address@hidden>
    Signed-off-by: felix <felix@call-with-current-continuation.org>

diff --git a/Makefile.android b/Makefile.android
new file mode 100644
index 00000000..7aafbd50
--- /dev/null
+++ b/Makefile.android
@@ -0,0 +1,108 @@
+# Makefile.android - configuration for Android -*- Makefile -*-
+#
+# Copyright (c) 2013, The Chicken Team
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
+# conditions are met:
+#
+#   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+#     disclaimer. 
+#   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+#     disclaimer in the documentation and/or other materials provided with the distribution. 
+#   Neither the name of the author nor the names of its contributors may be used to endorse or promote
+#     products derived from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+
+ifneq ($(CONFIG),)
+include $(CONFIG)
+endif
+
+SRCDIR ?= ./
+
+# platform configuration
+
+ARCH ?= $(shell sh $(SRCDIR)/config-arch.sh)
+
+# options
+
+C_COMPILER_OPTIONS ?= -fno-strict-aliasing -fwrapv -DHAVE_CHICKEN_CONFIG_H
+ifdef DEBUGBUILD
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -g -Wall -Wno-unused
+else
+ifdef OPTIMIZE_FOR_SPEED
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -O3 -fomit-frame-pointer
+else
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -Os -fomit-frame-pointer
+endif
+endif
+LINKER_LINK_SHARED_LIBRARY_OPTIONS = -shared
+LINKER_LINK_SHARED_DLOADABLE_OPTIONS = -L. -shared -Wl,-R"$(RUNTIME_LINKER_PATH)"
+LINKER_LINK_SHARED_PROGRAM_OPTIONS = -Wl,-R"$(RUNTIME_LINKER_PATH)"
+# Android NDK build system currently does not understand
+# versioned sonames, so don't try to embed a soname.
+#LIBCHICKEN_SO_LINKER_OPTIONS = -Wl,-soname,lib$(PROGRAM_PREFIX)chicken$(PROGRAM_SUFFIX).so.$(BINARYVERSION)
+LIBRARIES = -lm -ldl -llog
+NEEDS_RELINKING = yes
+# See above
+#USES_SONAME = yes
+
+# special files
+
+CHICKEN_CONFIG_H = chicken-config.h
+
+# select default and internal settings
+
+include $(SRCDIR)/defaults.make
+
+chicken-config.h: chicken-defaults.h
+	echo "/* GENERATED */" >$@
+	echo "#define HAVE_DIRENT_H 1" >>$@
+	echo "#define HAVE_DLFCN_H 1" >>$@
+	echo "#define HAVE_INTTYPES_H 1" >>$@
+	echo "#define HAVE_LIMITS_H 1" >>$@
+	echo "#define HAVE_LONG_LONG 1" >>$@
+	echo "#define HAVE_MEMMOVE 1" >>$@
+	echo "#define HAVE_MEMORY_H 1" >>$@
+	echo "#define HAVE_SIGACTION 1" >>$@
+	echo "#define HAVE_SIGSETJMP 1" >>$@
+	echo "#define HAVE_STDINT_H 1" >>$@
+	echo "#define HAVE_STDLIB_H 1" >>$@
+	echo "#define HAVE_STRERROR 1" >>$@
+	echo "#define HAVE_STRINGS_H 1" >>$@
+	echo "#define HAVE_STRING_H 1" >>$@
+	echo "#define HAVE_STRTOLL 1" >>$@
+	echo "#define HAVE_STRTOQ 1" >>$@
+	echo "#define HAVE_SYS_STAT_H 1" >>$@
+	echo "#define HAVE_SYS_TYPES_H 1" >>$@
+	echo "#define HAVE_UNISTD_H 1" >>$@
+	echo "#define HAVE_UNSIGNED_LONG_LONG 1" >>$@
+	echo "#define STDC_HEADERS 1" >>$@
+	echo "#define HAVE_ALLOCA 1" >>$@
+	echo "#define HAVE_ALLOCA_H 1" >>$@
+	echo "#define HAVE_GRP_H 1" >>$@
+	echo "#define HAVE_ERRNO_H 1" >>$@
+	echo "#define HAVE_MEMMOVE 1" >>$@
+	echo "#define C_STACK_GROWS_DOWNWARD 1" >>$@
+ifdef GCHOOKS
+	echo "#define C_GC_HOOKS" >>$@
+endif
+ifdef SYMBOLGC
+	echo "#define C_COLLECT_ALL_SYMBOLS" >>$@
+endif
+ifneq ($(HACKED_APPLY),)
+	echo "#define C_HACKED_APPLY" >>$@
+endif
+	cat chicken-defaults.h >>$@
+
+include $(SRCDIR)/rules.make
diff --git a/README b/README
index 82781122..bb3a1060 100644
--- a/README
+++ b/README
@@ -359,6 +359,30 @@
         
  5. Platform issues
 
+        Android:
+     
+	  - The Android SDK and NDK are required. Make sure you have
+	    set up a project and have a suitable NDK toolchain
+	    available. You will have to override the make(1) variable
+	    C_COMPILER to contain the correct compiler; see
+	    docs/STANDALONE-TOOLCHAIN.html in your NDK root for notes
+	    on how to call the correct compiler. You will also need to
+	    override the ARCH variable to match the device you're
+	    targeting.  The build will produce a libchicken.so that
+	    can then be integrated into your project as a prebuilt
+	    shared library.  See the android section on
+	    http://wiki.call-cc.org/embedding for a complete example.
+
+	  - It is possible to use eggs, by copying them into the right
+	    place and probably renaming the files. This is somewhat
+	    awkward and requires various hacks to make the
+	    loading/linking of eggs work. It may be easier to build
+	    the eggs you need manually and linking them statically to
+	    your executable.
+
+	  - By default debug-logging is enabled and written to the
+	    Android log.
+
     	FreeBSD/NetBSD/OpenBSD:
 
           - *BSD system users *must* use GNU make ("gmake") - the makefiles
diff --git a/chicken.h b/chicken.h
index 51adeba9..bd6c23d7 100644
--- a/chicken.h
+++ b/chicken.h
@@ -657,6 +657,8 @@ static inline int isinf_ld (long double x)
 
 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_WIN32) || defined(__WINNT__)
 # define C_SOFTWARE_TYPE "windows"
+#elif defined(__ANDROID__)
+# define C_SOFTWARE_TYPE "android"
 #elif defined(__unix__) || defined(C_XXXBSD) || defined(_AIX)
 # define C_SOFTWARE_TYPE "unix"
 #elif defined(ECOS)
diff --git a/distribution/manifest b/distribution/manifest
index 10034894..682587ee 100644
--- a/distribution/manifest
+++ b/distribution/manifest
@@ -218,6 +218,7 @@ apply-hack.ppc.darwin.S
 apply-hack.ppc.sysv.S
 chicken.pdf
 Makefile
+Makefile.android
 Makefile.aix
 Makefile.linux
 Makefile.macosx
diff --git a/manual/Unit posix b/manual/Unit posix
index d27fa88a..1ede6c09 100644
--- a/manual/Unit posix	
+++ b/manual/Unit posix	
@@ -806,6 +806,10 @@ directory and the default shell. When {{AS-VECTOR}} is {{#t}} a vector of 7
 elements is returned instead of a list. If no user with this name or id then
 {{#f}} is returned.
 
+Note: on Android systems, the user-specific string is always {{""}},
+since {{pw_gecos}} is not available in the C {{passwd}} struct on that
+platform.
+
 ==== current-group-id
 
 <procedure>(current-group-id)</procedure>
diff --git a/posixunix.scm b/posixunix.scm
index 6a429117..da0d9f91 100644
--- a/posixunix.scm
+++ b/posixunix.scm
@@ -133,6 +133,14 @@ static C_TLS struct {
   char *gr_mem[ 1 ];
 } C_group = { "", "", 0, { "" } };
 #endif
+
+/* Android doesn't provide pw_gecos in the passwd struct */
+#ifdef __ANDROID__
+# define C_PW_GECOS ("")
+#else
+# define C_PW_GECOS (C_user->pw_gecos)
+#endif
+
 static C_TLS int C_pipefds[ 2 ];
 static C_TLS time_t C_secs;
 static C_TLS struct timeval C_timeval;
@@ -176,7 +184,7 @@ static C_TLS struct stat C_statbuf;
 #define C_do_readlink(f, b)    C_fix(readlink(C_data_pointer(f), C_data_pointer(b), FILENAME_MAX))
 #define C_getpwnam(n)       C_mk_bool((C_user = getpwnam((char *)C_data_pointer(n))) != NULL)
 #define C_getpwuid(u)       C_mk_bool((C_user = getpwuid(C_unfix(u))) != NULL)
-#ifdef HAVE_GRP_H
+#if !defined(__ANDROID__) && defined(HAVE_GRP_H)
 #define C_getgrnam(n)       C_mk_bool((C_group = getgrnam((char *)C_data_pointer(n))) != NULL)
 #define C_getgrgid(u)       C_mk_bool((C_group = getgrgid(C_unfix(u))) != NULL)
 #else
@@ -290,7 +298,7 @@ static C_TLS sigset_t C_sigset;
 
 #define C_ctime(n)          (C_secs = (n), ctime(&C_secs))
 
-#if defined(__SVR4) || defined(C_MACOSX) || defined(_AIX)
+#if defined(__SVR4) || defined(C_MACOSX) || defined(__ANDROID__) || defined(_AIX)
 /* Seen here: http://lists.samba.org/archive/samba-technical/2002-November/025571.html */
 
 static time_t C_timegm(struct tm *t)
@@ -368,7 +376,7 @@ static gid_t *C_groups = NULL;
 #define C_set_gid(n, id)  (C_groups[ C_unfix(n) ] = C_unfix(id), C_SCHEME_UNDEFINED)
 #define C_set_groups(n)   C_fix(setgroups(C_unfix(n), C_groups))
 
-#ifdef TIOCGWINSZ
+#if !defined(__ANDROID__) && defined(TIOCGWINSZ)
 static int get_tty_size(int p, int *rows, int *cols)
 {
  struct winsize tty_size;
@@ -976,7 +984,7 @@ EOF
 (define-foreign-variable _user-passwd nonnull-c-string "C_user->pw_passwd")
 (define-foreign-variable _user-uid int "C_user->pw_uid")
 (define-foreign-variable _user-gid int "C_user->pw_gid")
-(define-foreign-variable _user-gecos nonnull-c-string "C_user->pw_gecos")
+(define-foreign-variable _user-gecos nonnull-c-string "C_PW_GECOS")
 (define-foreign-variable _user-dir c-string "C_user->pw_dir")
 (define-foreign-variable _user-shell c-string "C_user->pw_shell")
 
diff --git a/runtime.c b/runtime.c
index a58eb809..c90b9ddd 100644
--- a/runtime.c
+++ b/runtime.c
@@ -37,6 +37,10 @@
 # include <sysexits.h>
 #endif
 
+#ifdef __ANDROID__
+# include <android/log.h>
+#endif
+
 #if !defined(PIC)
 # define NO_DLOAD2
 #endif
@@ -536,12 +540,16 @@ C_dbg(C_char *prefix, C_char *fstr, ...)
 {
   va_list va;
 
+  va_start(va, fstr);
+#ifdef __ANDROID__
+  __android_log_vprint(ANDROID_LOG_DEBUG, prefix, fstr, va);
+#else
   C_fflush(C_stdout);
   C_fprintf(C_stderr, "[%s] ", prefix);
-  va_start(va, fstr);
   C_vfprintf(C_stderr, fstr, va);
-  va_end(va);
   C_fflush(C_stderr);
+#endif
+  va_end(va);
 }
 
 
@@ -634,6 +642,10 @@ int CHICKEN_initialize(int heap, int stack, int symbols, void *toplevel)
   if(chicken_is_initialized) return 1;
   else chicken_is_initialized = 1;
 
+#ifdef __ANDROID__
+  debug_mode = 2;
+#endif
+
   if(debug_mode) 
     C_dbg(C_text("debug"), C_text("application startup...\n"));
 
Trap