OSDN Git Service

Code drop from //branches/cupcake/...@124589
authorThe Android Open Source Project <initial-contribution@android.com>
Thu, 18 Dec 2008 02:08:09 +0000 (18:08 -0800)
committerThe Android Open Source Project <initial-contribution@android.com>
Thu, 18 Dec 2008 02:08:09 +0000 (18:08 -0800)
41 files changed:
su/su.c
tests/bionic/libc/Android.mk [new file with mode: 0644]
tests/bionic/libc/MODULE_LICENSE_BSD_AND_GPL [new file with mode: 0644]
tests/bionic/libc/README.TXT [new file with mode: 0644]
tests/bionic/libc/bionic/test_cond.c [new file with mode: 0644]
tests/bionic/libc/bionic/test_getgrouplist.c [new file with mode: 0644]
tests/bionic/libc/bionic/test_mutex.c [new file with mode: 0644]
tests/bionic/libc/bionic/test_netinet_icmp.c [new file with mode: 0644]
tests/bionic/libc/bionic/test_pthread_cond.c [new file with mode: 0644]
tests/bionic/libc/bionic/test_pthread_create.c [new file with mode: 0644]
tests/bionic/libc/common/test_gethostbyname.c [new file with mode: 0644]
tests/bionic/libc/common/test_gethostname.c [new file with mode: 0644]
tests/bionic/libc/common/test_libgen.c [new file with mode: 0644]
tests/bionic/libc/common/test_pthread_cleanup_push.c [new file with mode: 0644]
tests/bionic/libc/common/test_pthread_getcpuclockid.c [new file with mode: 0644]
tests/bionic/libc/common/test_pthread_join.c [new file with mode: 0644]
tests/bionic/libc/common/test_pthread_once.c [new file with mode: 0644]
tests/bionic/libc/common/test_semaphore.c [new file with mode: 0644]
tests/bionic/libc/common/test_seteuid.c [new file with mode: 0644]
tests/bionic/libc/common/test_static_cpp_mutex.cpp [new file with mode: 0644]
tests/bionic/libc/common/test_tm_zone.c [new file with mode: 0644]
tests/bionic/libc/common/test_udp.c [new file with mode: 0644]
tests/bionic/libc/glibc/assert/test-assert.c [new file with mode: 0644]
tests/bionic/libc/other/bench_locks.c [new file with mode: 0644]
tests/bionic/libc/other/test_aligned.c [new file with mode: 0644]
tests/bionic/libc/other/test_arc4random.c [new file with mode: 0644]
tests/bionic/libc/other/test_atomics.c [new file with mode: 0644]
tests/bionic/libc/other/test_jpeg.c [new file with mode: 0644]
tests/bionic/libc/other/test_sysconf.c [new file with mode: 0644]
tests/bionic/libc/other/test_system.c [new file with mode: 0644]
tests/bionic/libc/other/test_thread_max.c [new file with mode: 0644]
tests/bionic/libc/other/test_timer_create.c [new file with mode: 0644]
tests/bionic/libc/other/test_vfprintf_leak.c [new file with mode: 0644]
tests/bionic/libc/other/test_zlib.c [new file with mode: 0644]
tests/cpueater/Android.mk
tests/cpueater/daemonize.c [new file with mode: 0644]
tests/framebuffer/Android.mk [new file with mode: 0644]
tests/framebuffer/fb_test.c [new file with mode: 0644]
tests/framebuffer/minui.h [new file with mode: 0644]
tests/framebuffer/refresh.c [new file with mode: 0644]
tests/fstest/perm_checker.conf

diff --git a/su/su.c b/su/su.c
index aac981e..5c9ca10 100644 (file)
--- a/su/su.c
+++ b/su/su.c
 
 /*
  * SU can be given a specific command to exec. UID _must_ be
- * specified for this (ie argc => 3). Full path of file must be specified.
+ * specified for this (ie argc => 3).
  *
  * Usage:
  * su 1000
- * su 1000 /system/bin/ls -l
+ * su 1000 ls -l
  */
 int main(int argc, char **argv)
 {
@@ -70,7 +70,7 @@ int main(int argc, char **argv)
         char *exec_args[argc - 1];
         memset(exec_args, 0, sizeof(exec_args));
         memcpy(exec_args, &argv[2], sizeof(exec_args));
-        if (execv(argv[2], exec_args) < 0) {
+        if (execvp(argv[2], exec_args) < 0) {
             fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
                     strerror(errno));
             return -errno;
@@ -83,4 +83,3 @@ int main(int argc, char **argv)
     fprintf(stderr, "su: exec failed\n");
     return 1;
 }
-
diff --git a/tests/bionic/libc/Android.mk b/tests/bionic/libc/Android.mk
new file mode 100644 (file)
index 0000000..14ac0c0
--- /dev/null
@@ -0,0 +1,114 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Build control file for Bionic's test programs
+# define the BIONIC_TESTS environment variable to build the test programs
+#
+ifdef BIONIC_TESTS
+
+LOCAL_PATH:= $(call my-dir)
+
+# used to define a simple test program and build it as a standalone
+# device executable.
+#
+# you can use EXTRA_CFLAGS to indicate additional CFLAGS to use
+# in the build. the variable will be cleaned on exit
+#
+define device-test
+  $(foreach file,$(1), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.c=%))) \
+    $(eval $(info LOCAL_MODULE=$(LOCAL_MODULE))) \
+    $(eval LOCAL_CFLAGS += $(EXTRA_CFLAGS)) \
+    $(eval LOCAL_MODULE_TAGS := tests) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+  ) \
+  $(eval EXTRA_CFLAGS :=)
+endef
+
+# same as 'device-test' but builds a host executable instead
+# you can use EXTRA_LDLIBS to indicate additional linker flags
+#
+define host-test
+  $(foreach file,$(1), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.c=%))) \
+    $(eval $(info LOCAL_MODULE=$(LOCAL_MODULE) file=$(file))) \
+    $(eval LOCAL_CFLAGS += $(EXTRA_CFLAGS)) \
+    $(eval LOCAL_LDLIBS += $(EXTRA_LDLIBS)) \
+    $(eval LOCAL_MODULE_TAGS := tests) \
+    $(eval include $(BUILD_HOST_EXECUTABLE)) \
+  ) \
+  $(eval EXTRA_CFLAGS :=) \
+  $(eval EXTRA_LDLIBS :=)
+endef
+
+# First, the tests in 'common'
+
+sources := \
+    common/test_gethostbyname.c \
+    common/test_gethostname.c \
+    common/test_pthread_cleanup_push.c \
+    common/test_pthread_getcpuclockid.c \
+    common/test_pthread_join.c \
+    common/test_pthread_once.c \
+    common/test_semaphore.c \
+    common/test_seteuid.c \
+    common/test_static_cpp_mutex.cpp \
+    common/test_tm_zone.c \
+    common/test_udp.c \
+
+EXTRA_LDLIBS := -lpthread -lrt
+$(call host-test, $(sources))
+$(call device-test, $(sources))
+
+sources := \
+    common/test_libgen.c \
+
+EXTRA_CFLAGS := -DHOST
+$(call host-test, $(sources))
+$(call device-test, $(sources))
+
+# Second, the Bionic-specific tests
+
+sources :=  \
+    bionic/test_mutex.c \
+    bionic/test_cond.c \
+    bionic/test_getgrouplist.c \
+    bionic/test_netinet_icmp.c \
+    bionic/test_pthread_cond.c \
+    bionic/test_pthread_create.c \
+
+$(call device-test, $(sources))
+
+# Third, the other tests
+
+sources := \
+    other/bench_locks.c \
+    other/test_aligned.c \
+    other/test_arc4random.c \
+    other/test_atomics.c \
+    other/test_sysconf.c \
+    other/test_system.c \
+    other/test_thread_max.c \
+    other/test_timer_create.c \
+    other/test_vfprintf_leak.c \
+
+$(call device-test, $(sources))
+
+# TODO: Add a variety of GLibc test programs too...
+
+endif  # BIONIC_TESTS
diff --git a/tests/bionic/libc/MODULE_LICENSE_BSD_AND_GPL b/tests/bionic/libc/MODULE_LICENSE_BSD_AND_GPL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/bionic/libc/README.TXT b/tests/bionic/libc/README.TXT
new file mode 100644 (file)
index 0000000..5576b77
--- /dev/null
@@ -0,0 +1,32 @@
+This directory contains a set of tests for Android's Bionic C library.
+
+These sources are not distributed with Bionic itself because some of
+these tests come from the GNU C Library, and are licensed under the
+GNU Lesser General Public License (LGPL)
+
+You must define the BIONIC_TESTS environment variable to build these
+test programs. For example, do:
+
+    cd system/bionic-tests/
+    mm BIONIC_TESTS=1
+
+All test programs, except those in the 'other' directory, should exit
+with a status code of 0 in case of success, and 1 in case of failure.
+
+The directory layout is simple:
+
+  common/
+    Contains tests that can be compiled either with Bionic or another
+    C library.
+
+  glibc/
+    Contains tests that come from the GNU C Library. However, they can
+    be compiled with Bionic too.
+
+  bionic/
+    Contains tests that can *only* be compiled against Bionic
+
+  other/
+    Other unrelated tests. These are not run by the test runner
+    program but will be installed to your device nevertheless.
+    Put benchmarks and various debug/info stuff there.
diff --git a/tests/bionic/libc/bionic/test_cond.c b/tests/bionic/libc/bionic/test_cond.c
new file mode 100644 (file)
index 0000000..6a85f9b
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+
+static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+static pthread_cond_t  wait = PTHREAD_COND_INITIALIZER;
+
+static void* _thread1(void *__u __attribute__((unused)))
+{
+    printf("1: obtaining mutex\n");
+    pthread_mutex_lock(&lock);
+    printf("1: waiting on condition variable\n");
+    pthread_cond_wait(&wait, &lock);
+    printf("1: releasing mutex\n");
+    pthread_mutex_unlock(&lock);
+    printf("1: exiting\n");    
+    return NULL;
+}
+
+static void* _thread2(void *__u __attribute__((unused)))
+{
+    int cnt = 2;
+    while(cnt--) {
+        printf("2: obtaining mutex\n");
+        pthread_mutex_lock(&lock);
+        printf("2: signaling\n");
+        pthread_cond_signal(&wait);
+        printf("2: releasing mutex\n");
+        pthread_mutex_unlock(&lock);
+    }
+
+    printf("2: exiting\n");
+    return NULL;
+}
+
+typedef void* (*thread_func)(void*);
+static const  thread_func thread_routines[] =
+{
+    &_thread1,
+    &_thread2,
+};
+
+int main(void)
+{
+    pthread_t t[2];
+    int nn;
+    int count = (int)(sizeof t/sizeof t[0]);
+
+    for (nn = 0; nn < count; nn++) {
+        printf("main: creating thread %d\n", nn+1);
+        if (pthread_create( &t[nn], NULL, thread_routines[nn], NULL) < 0) {
+            printf("main: could not create thread %d: %s\n", nn+1, strerror(errno));
+            return -2;
+        }
+    }
+
+    for (nn = 0; nn < count; nn++) {
+        printf("main: joining thread %d\n", nn+1);
+        if (pthread_join(t[nn], NULL)) {
+            printf("main: could not join thread %d: %s\n", nn+1, strerror(errno));
+            return -2;
+        }
+    }
+
+    return 0;
+}
diff --git a/tests/bionic/libc/bionic/test_getgrouplist.c b/tests/bionic/libc/bionic/test_getgrouplist.c
new file mode 100644 (file)
index 0000000..e5b8ee2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <stdio.h>
+#include <grp.h>
+
+#define  MAX_GROUPS  100
+#define  TEST_GROUP  1337
+#define  TEST_USER   "nobodyisreallyhere"
+
+int  main(void)
+{
+    int    count = MAX_GROUPS;
+    gid_t  groups[MAX_GROUPS];
+    int    ret;
+
+    /* this only tests the funky behaviour of our stubbed getgrouplist()
+     * implementation. which should only return TEST_GROUP, independent
+     * of the user
+     */
+    ret = getgrouplist( TEST_USER, TEST_GROUP, groups, &count );
+    if (ret != 1) {
+        fprintf(stderr, "getgrouplist() returned %d (expecting 1), ngroups=%d\n", 
+                ret, count);
+        return 1;
+    }
+    if (groups[0] != TEST_GROUP) {
+        fprintf(stderr, "getgrouplist() returned group %d (expecting %d)\n",
+                        groups[0], TEST_GROUP);
+        return 1;
+    }
+    printf ("ok\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/bionic/test_mutex.c b/tests/bionic/libc/bionic/test_mutex.c
new file mode 100644 (file)
index 0000000..02257ba
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#define __USE_UNIX98  1  /* necessary to define pthread_mutexattr_set/gettype in Linux GLIBC headers. doh ! */
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+static void  panic( const char*  format, ... )
+{
+    va_list  args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+    exit(1);
+}
+
+#define  assert(cond)   do { if ( !(cond) ) panic( "%s:%d: assertion failure: %s\n", __FILE__, __LINE__, #cond ); } while (0)
+
+#define  expect(call,result)                                         \
+    do {                                                             \
+        int  ret = (call);                                           \
+        if (ret != (result)) {                                       \
+            panic( "%s:%d: call returned %d instead of %d: %s\n",    \
+                   __FILE__, __LINE__, ret, (result), #call );       \
+        }                                                            \
+    } while (0)
+
+
+int  main( void )
+{
+    pthread_mutex_t       lock = PTHREAD_MUTEX_INITIALIZER;
+    pthread_mutexattr_t   attr;
+    int                   attr_type;
+
+    expect( pthread_mutexattr_init( &attr ), 0 );
+
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_NORMAL ), 0 );
+    expect( pthread_mutexattr_gettype( &attr, &attr_type ), 0 );
+    assert( attr_type == PTHREAD_MUTEX_NORMAL );
+
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK ), 0 );
+    expect( pthread_mutexattr_gettype( &attr, &attr_type ), 0 );
+    assert( attr_type == PTHREAD_MUTEX_ERRORCHECK );
+
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ), 0 );
+    expect( pthread_mutexattr_gettype( &attr, &attr_type ), 0 );
+    assert( attr_type == PTHREAD_MUTEX_RECURSIVE );
+
+    /* standard mutexes */
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_NORMAL ), 0 );
+    expect( pthread_mutex_init( &lock, &attr ), 0 );
+    expect( pthread_mutex_lock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_destroy( &lock ), 0 );
+
+    /* error-check mutex */
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK ), 0 );
+    expect( pthread_mutex_init( &lock, &attr ), 0 );
+    expect( pthread_mutex_lock( &lock ), 0 );
+    expect( pthread_mutex_lock( &lock ), EDEADLK );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_trylock( &lock ), 0 );
+    expect( pthread_mutex_trylock( &lock ), EDEADLK );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), EPERM );
+    expect( pthread_mutex_destroy( &lock ), 0 );
+
+    /* recursive mutex */
+    expect( pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ), 0 );
+    expect( pthread_mutex_init( &lock, &attr ), 0 );
+    expect( pthread_mutex_lock( &lock ), 0 );
+    expect( pthread_mutex_lock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_trylock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), 0 );
+    expect( pthread_mutex_unlock( &lock ), EPERM );
+    expect( pthread_mutex_destroy( &lock ), 0 );
+
+    printf( "ok\n" );
+    return 0;
+}
diff --git a/tests/bionic/libc/bionic/test_netinet_icmp.c b/tests/bionic/libc/bionic/test_netinet_icmp.c
new file mode 100644 (file)
index 0000000..308ccce
--- /dev/null
@@ -0,0 +1,8 @@
+/* this test simply checks that we can compile the <netinet/ip_icmp.h> header */
+#include <netinet/ip_icmp.h>
+
+int  main( void )
+{
+    return 0;
+}
+
diff --git a/tests/bionic/libc/bionic/test_pthread_cond.c b/tests/bionic/libc/bionic/test_pthread_cond.c
new file mode 100644 (file)
index 0000000..26746fa
--- /dev/null
@@ -0,0 +1,83 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+
+static pthread_cond_t cond1;
+static pthread_cond_t cond2;
+static pthread_mutex_t test_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static void *
+thread1_func(void* arg)
+{
+    printf("Thread 1 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    printf("1 waiting for cond1\n");
+    pthread_mutex_lock(&test_lock);
+    pthread_cond_wait(&cond1, &test_lock );
+    pthread_mutex_unlock(&test_lock);
+    printf("Thread 1 done.\n");
+    return 0;
+}
+
+static void *
+thread2_func(void* arg)
+{
+    printf("Thread 2 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    printf("2 waiting for cond2\n");
+    pthread_mutex_lock(&test_lock);
+    pthread_cond_wait(&cond2, &test_lock );
+    pthread_mutex_unlock(&test_lock);
+
+    printf("Thread 2 done.\n");
+    return 0;
+}
+
+static void *
+thread3_func(void* arg)
+{
+    printf("Thread 3 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    printf("3 waiting for cond1\n");
+    pthread_mutex_lock(&test_lock);
+    pthread_cond_wait(&cond1, &test_lock );
+    pthread_mutex_unlock(&test_lock);
+    printf("3 Sleeping\n");
+    sleep(2);
+    printf("3 signal cond2\n");
+    pthread_cond_signal(&cond2);
+
+    printf("Thread 3 done.\n");
+    return 0;
+}
+
+static void *
+thread4_func(void* arg)
+{
+    printf("Thread 4 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    printf("4 Sleeping\n");
+    sleep(5);
+
+    printf("4 broadcast cond1\n");
+    pthread_cond_broadcast(&cond1);
+    printf("Thread 4 done.\n");
+    return 0;
+}
+
+int main(int argc, const char *argv[])
+{
+    pthread_t t[4];
+
+    pthread_cond_init(&cond1, NULL);
+    pthread_cond_init(&cond2, NULL);
+    pthread_create( &t[0], NULL, thread1_func, (void *)1 );
+    pthread_create( &t[1], NULL, thread2_func, (void *)2 );
+    pthread_create( &t[2], NULL, thread3_func, (void *)3 );
+    pthread_create( &t[3], NULL, thread4_func, (void *)4 );
+
+    pthread_join(t[0], NULL);
+    pthread_join(t[1], NULL);
+    pthread_join(t[2], NULL);
+    pthread_join(t[3], NULL);
+    return 0;
+}
diff --git a/tests/bionic/libc/bionic/test_pthread_create.c b/tests/bionic/libc/bionic/test_pthread_create.c
new file mode 100644 (file)
index 0000000..edac0ff
--- /dev/null
@@ -0,0 +1,30 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static void *
+thread1_func(void* arg)
+{
+    printf("Thread 1 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    return 0;
+}
+
+static void *
+thread2_func(void* arg)
+{
+    printf("thread 2 (arg=%d tid=%d) entered.\n", (unsigned)arg, gettid());
+    return 1;
+}
+
+
+int main( void )
+{
+    pthread_t t1, t2;
+
+    pthread_create( &t1, NULL, thread1_func, (void *)1 );
+
+    pthread_join(t1, NULL);
+
+    printf("OK\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_gethostbyname.c b/tests/bionic/libc/common/test_gethostbyname.c
new file mode 100644 (file)
index 0000000..1e932d6
--- /dev/null
@@ -0,0 +1,53 @@
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+int  main( int  argc, char**  argv )
+{
+    char*            hostname = "localhost";
+    struct hostent*  hent;
+    int    i, ret;
+
+    if (argc > 1)
+        hostname = argv[1];
+
+    hent = gethostbyname(hostname);
+    if (hent == NULL) {
+        printf("gethostbyname(%s) returned NULL !!\n", hostname);
+        return 1;
+    }
+    printf( "gethostbyname(%s) returned:\n", hostname);
+    printf( "  name: %s\n", hent->h_name );
+    printf( "  aliases:" );
+    for (i = 0; hent->h_aliases[i] != NULL; i++)
+        printf( " %s", hent->h_aliases[i] );
+    printf( "\n" );
+    printf( "  address type: " );
+    switch (hent->h_addrtype) {
+        case AF_INET:  printf( "AF_INET\n"); break;
+        case AF_INET6: printf( "AF_INET6\n"); break;
+        default: printf("UNKNOWN (%d)\n", hent->h_addrtype);
+    }
+    printf( "  address: " );
+    switch (hent->h_addrtype) {
+        case AF_INET:
+            {
+                const char*  dot = "";
+                for (i = 0; i < hent->h_length; i++) {
+                    printf("%s%d", dot, ((unsigned char*)hent->h_addr)[i]);
+                    dot = ".";
+                }
+            }
+            break;
+
+        default:
+            for (i = 0; i < hent->h_length; i++) {
+                printf( "%02x", ((unsigned char*)hent->h_addr)[i] );
+            }
+    }
+    printf("\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_gethostname.c b/tests/bionic/libc/common/test_gethostname.c
new file mode 100644 (file)
index 0000000..b9dcbaf
--- /dev/null
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+int  main( void )
+{
+    char  hostname[512];
+    int   ret;
+
+    ret = gethostname(hostname, sizeof(hostname));
+    if (ret < 0) {
+        printf("gethostname() returned error %d: %s\n", errno, strerror(errno));
+        return 1;
+    }
+
+    printf("gethostname() returned '%s'\n", hostname);
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_libgen.c b/tests/bionic/libc/common/test_libgen.c
new file mode 100644 (file)
index 0000000..4a2c29e
--- /dev/null
@@ -0,0 +1,221 @@
+// test the basename, dirname, basename_r and dirname_r
+#include <libgen.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+static int  fail = 0;
+
+static void
+test_basename(char*  _input, const char*  _expected, int  _errno)
+{
+    char   temp[256], *input = _input;
+    char*  ret;
+#if HOST
+    /* GLibc does modify the input string. bummer */
+    if (_input) {
+        strcpy(temp, _input);
+        input = temp;
+    }
+#endif
+    errno = 0;
+    ret   = basename(input);
+    if (_expected == NULL) {
+        if (ret != NULL) {
+            fprintf(stderr,
+                    "KO: basename(\"%s\") returned \"%s\", NULL expected)\n",
+                    _input, ret);
+            fail += 1;
+        } else if (errno != _errno) {
+            fprintf(stderr,
+                    "KO: basename(\"%s\") returned NULL with error: %d (%d expected)\n",
+                    _input, errno, _errno);
+            fail += 1;
+        } else {
+            printf( "OK: basename(\"%s\") returned NULL with error %d\n",
+                    _input, _errno );
+        }
+    } else {
+        if (ret == NULL) {
+            fprintf(stderr, "KO: basename(\"%s\") returned NULL with error %d\n",
+                    _input, errno);
+            fail += 1;
+        }
+        else if (strcmp(ret, _expected)) {
+            fprintf(stderr, "KO: basename(\"%s\") returned \"%s\", instead of \"%s\"\n",
+                    _input, ret, _expected);
+        }
+        else {
+            printf( "OK: basename(\"%s\") returned \"%s\"\n",
+                    _input, ret );
+        }
+    }
+}
+
+
+#if !HOST
+static void
+test_basename_r(char*  _input, const char*  _expected_content, int  _expected, char*  _buff, size_t  _bufflen, int  _errno)
+{
+    int   ret;
+    errno = 0;
+    ret   = basename_r(_input, _buff, _bufflen );
+    if (ret != _expected) {
+        fprintf(stderr,
+                "KO: basename_r(\"%s\", <buff>, %d) returned %d (expected %d)\n",
+                _input, _bufflen, ret, _expected);
+        fail += 1;
+        return;
+    }
+    if (ret == -1) {
+        if (errno != _errno) {
+            fprintf(stderr,
+                    "KO: basename_r(\"%s\", <buff>, %d) returned -1 with errno=%d (expected %d)\n",
+                    _input, _bufflen, errno, _errno);
+            fail += 1;
+            return;
+        }
+    }
+    else if ( memcmp( _buff, _expected_content, ret ) ) {
+        fprintf(stderr,
+                "KO: basename_r(\"%s\", <buff>, %d) returned \"%s\", expected \"%s\"\n",
+                _input, _bufflen, _buff, _expected_content );
+        fail += 1;
+        return;
+    }
+    printf("OK: basename_r(\"%s\", <buff>, %d) returned \"%s\"\n",
+            _input, _bufflen, _expected_content );
+}
+
+static void
+test_dirname_r(char*  _input, const char*  _expected_content, int  _expected, char*  _buff, size_t  _bufflen, int  _errno)
+{
+    int   ret;
+    errno = 0;
+    ret   = dirname_r(_input, _buff, _bufflen );
+    if (ret != _expected) {
+        fprintf(stderr,
+                "KO: dirname_r(\"%s\", <buff>, %d) returned %d (expected %d)\n",
+                _input, _bufflen, ret, _expected);
+        fail += 1;
+        return;
+    }
+    if (ret == -1) {
+        if (errno != _errno) {
+            fprintf(stderr,
+                    "KO: dirname_r(\"%s\", <buff>, %d) returned -1 with errno=%d (expected %d)\n",
+                    _input, _bufflen, errno, _errno);
+            fail += 1;
+            return;
+        }
+    }
+    else if ( memcmp( _buff, _expected_content, ret ) ) {
+        fprintf(stderr,
+                "KO: dirname_r(\"%s\", <buff>, %d) returned \"%s\", expected \"%s\"\n",
+                _input, _bufflen, _buff, _expected_content );
+        fail += 1;
+        return;
+    }
+    printf("OK: dirname_r(\"%s\", <buff>, %d) returned \"%s\"\n",
+            _input, _bufflen, _expected_content );
+}
+#endif
+
+
+static void
+test_dirname(char*  _input, const char*  _expected, int  _errno)
+{
+    char   temp[256], *input = _input;
+    char*  ret;
+#if HOST
+    /* GLibc does modify the input string. bummer */
+    if (_input) {
+        strcpy(temp, _input);
+        input = temp;
+    }
+#endif
+    errno = 0;
+    ret   = dirname(input);
+    if (_expected == NULL) {
+        if (ret != NULL) {
+            fprintf(stderr,
+                    "KO: dirname(\"%s\") returned \"%s\", NULL expected)\n",
+                    _input, ret);
+            fail += 1;
+        } else if (errno != _errno) {
+            fprintf(stderr,
+                    "KO: dirname(\"%s\") returned NULL with error: %d (%d expected)\n",
+                    _input, errno, _errno);
+            fail += 1;
+        } else {
+            printf( "OK: dirname(\"%s\") returned NULL with error %d\n",
+                    _input, _errno );
+        }
+    } else {
+        if (ret == NULL) {
+            fprintf(stderr, "KO: dirname(\"%s\") returned NULL with error %d\n",
+                    _input, errno);
+            fail += 1;
+        }
+        else if (strcmp(ret, _expected)) {
+            fprintf(stderr, "KO: dirname(\"%s\") returned \"%s\", instead of \"%s\"\n",
+                    _input, ret, _expected);
+        }
+        else {
+            printf( "OK: dirname(\"%s\") returned \"%s\"\n",
+                    _input, ret );
+        }
+    }
+}
+
+
+
+
+int  main( void )
+{
+    char  buff[256];
+
+    test_basename( "", ".", 0 );
+    test_basename( "/usr/lib", "lib", 0 );
+    test_basename( "/usr/", "usr", 0 );
+    test_basename( "usr", "usr", 0 );
+    test_basename( "/", "/", 0 );
+    test_basename( ".", ".", 0 );
+    test_basename( "..", "..", 0 );
+
+#if !HOST
+    test_basename_r( "", ".",  1, NULL, 0, 0 );
+    test_basename_r( "", ".", -1, buff, 0, ERANGE );
+    test_basename_r( "", ".", -1, buff, 1, ERANGE );
+    test_basename_r( "", ".", 1, buff, 2, 0 );
+    test_basename_r( "", ".", 1, buff, sizeof(buff), 0 );
+    test_basename_r( "/usr/lib", "lib", 3, buff, sizeof(buff), 0 );
+    test_basename_r( "/usr/", "usr", 3, buff, sizeof(buff), 0 );
+    test_basename_r( "usr", "usr", 3, buff, sizeof(buff), 0 );
+    test_basename_r( "/", "/", 1, buff, sizeof(buff), 0 );
+    test_basename_r( ".", ".", 1, buff, sizeof(buff), 0 );
+    test_basename_r( "..", "..", 2, buff, sizeof(buff), 0 );
+#endif
+
+    test_dirname( "", ".", 0 );
+    test_dirname( "/usr/lib", "/usr", 0 );
+    test_dirname( "/usr/", "/", 0 );
+    test_dirname( "usr", ".", 0 );
+    test_dirname( ".", ".", 0 );
+    test_dirname( "..", ".", 0 );
+
+#if !HOST
+    test_dirname_r( "", ".",  1, NULL, 0, 0 );
+    test_dirname_r( "", ".", -1, buff, 0, ERANGE );
+    test_dirname_r( "", ".", -1, buff, 1, ERANGE );
+    test_dirname_r( "", ".", 1, buff, 2, 0 );
+    test_dirname_r( "/usr/lib", "/usr", 4, buff, sizeof(buff), 0 );
+    test_dirname_r( "/usr/", "/", 1, buff, sizeof(buff), 0 );
+    test_dirname_r( "usr", ".", 1, buff, sizeof(buff), 0 );
+    test_dirname_r( ".", ".", 1, buff, sizeof(buff), 0 );
+    test_dirname_r( "..", ".", 1, buff, sizeof(buff), 0 );
+#endif
+
+    return (fail > 0);
+}
+
diff --git a/tests/bionic/libc/common/test_pthread_cleanup_push.c b/tests/bionic/libc/common/test_pthread_cleanup_push.c
new file mode 100644 (file)
index 0000000..87634ad
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define MAGIC1 0xcafebabeU
+#define MAGIC2 0x8badf00dU
+#define MAGIC3 0x12345667U
+
+static int g_ok1 = 0;
+static int g_ok2 = 0;
+static int g_ok3 = 0;
+
+static void
+cleanup1( void* arg )
+{
+    if ((unsigned)arg != MAGIC1)
+        g_ok1 = -1;
+    else
+        g_ok1 = +1;
+}
+
+static void
+cleanup2( void* arg )
+{
+    if ((unsigned)arg != MAGIC2) {
+        g_ok2 = -1;
+    } else
+        g_ok2 = +1;
+}
+
+static void
+cleanup3( void* arg )
+{
+    if ((unsigned)arg != MAGIC3)
+        g_ok3 = -1;
+    else
+        g_ok3 = +1;
+}
+
+
+static void*
+thread1_func( void* arg )
+{
+    pthread_cleanup_push( cleanup1, (void*)MAGIC1 );
+    pthread_cleanup_push( cleanup2, (void*)MAGIC2 );
+    pthread_cleanup_push( cleanup3, (void*)MAGIC3 );
+
+    if (arg != NULL)
+        pthread_exit(0);
+
+    pthread_cleanup_pop(0);
+    pthread_cleanup_pop(1);
+    pthread_cleanup_pop(1);
+
+    return NULL;
+}
+
+static int test( int do_exit )
+{
+    pthread_t t;
+
+    pthread_create( &t, NULL, thread1_func, (void*)do_exit );
+    pthread_join( t, NULL );
+
+    if (g_ok1 != +1) {
+        if (g_ok1 == 0) {
+            fprintf(stderr, "cleanup1 not called !!\n");
+        } else {
+            fprintf(stderr, "cleanup1 called with wrong argument\n" );
+        }
+        exit(1);
+    }
+    else if (g_ok2 != +1) {
+        if (g_ok2 == 0)
+            fprintf(stderr, "cleanup2 not called !!\n");
+        else
+            fprintf(stderr, "cleanup2 called with wrong argument\n");
+        exit(2);
+    }
+    else if (do_exit && g_ok3 != +1) {
+        if (g_ok3 == 0) {
+            fprintf(stderr, "cleanup3 not called !!\n");
+        } else {
+            fprintf(stderr, "cleanup3 called with bad argument !!\n");
+        }
+        exit(3);
+    }
+    else if (!do_exit && g_ok3 != 0) {
+        if (g_ok3 == 1) {
+            fprintf(stderr, "cleanup3 wrongly called !!\n");
+        } else {
+            fprintf(stderr, "cleanup3 wrongly called with bad argument !!\n");
+        }
+        exit(3);
+    }
+
+    return 0;
+}
+
+int main( void )
+{
+    test(0);
+    test(1);
+    printf("OK\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_pthread_getcpuclockid.c b/tests/bionic/libc/common/test_pthread_getcpuclockid.c
new file mode 100644 (file)
index 0000000..2a82808
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* this is a small test for pthread_getcpuclockid() and clock_gettime() */
+
+#include <time.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+static pthread_mutex_t  lock = PTHREAD_MUTEX_INITIALIZER;
+
+static void*
+thread_func( void*  arg )
+{
+    pthread_t         self = pthread_self();
+    struct timespec   ts;
+    clockid_t         clock;
+    int               e;
+
+    pthread_mutex_lock( &lock );
+
+    e = pthread_getcpuclockid( self, &clock );
+    if (e != 0) {
+        fprintf(stderr, "pthread_getcpuclockid(%08lx,) returned error %d: %s\n", self, e, strerror(e));
+        pthread_mutex_unlock( &lock );
+        return NULL;
+    }
+
+    ts.tv_sec  = 0;
+    ts.tv_nsec = 300000000 + ((int)arg)*50000000;
+    nanosleep( &ts, &ts );
+
+    clock_gettime( clock, &ts );
+    fprintf(stderr, "thread %08lx: clock_gettime() returned %g nsecs\n", self, ts.tv_sec*1e9 + ts.tv_nsec);
+
+    pthread_mutex_unlock( &lock );
+
+    return NULL;
+}
+
+#define  MAX_THREADS   16
+
+int  main( void )
+{
+    int             nn;
+    pthread_attr_t  attr;
+    pthread_t       threads[MAX_THREADS];
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+    for (nn = 0; nn < MAX_THREADS; nn++) {
+        pthread_create( &threads[nn], &attr, thread_func, (void*)nn );
+    }
+    for (nn = 0; nn < MAX_THREADS; nn++) {
+        void*  dummy;
+        pthread_join( threads[nn], &dummy );
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_pthread_join.c b/tests/bionic/libc/common/test_pthread_join.c
new file mode 100644 (file)
index 0000000..4fe2561
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static void*
+thread1_func(void* arg)
+{
+    usleep( 2000*1000 );
+    printf("thread 1 exited\n");
+    return (void*) 0x8badf00d;
+}
+
+static void*
+thread2_func(void* arg)
+{
+    pthread_t t1 = (pthread_t)arg;
+    void* result;
+
+    pthread_join(t1, &result);
+    printf("thread2 received code %08x from thread1\n", (int)result);
+    return NULL;
+}
+
+
+static void*
+thread3_func(void* arg)
+{
+    pthread_t t1 = (pthread_t)arg;
+    void* result;
+
+    pthread_join(t1, &result);
+    printf("thread3 received code %08x from thread1\n", (int)result);
+    return NULL;
+}
+
+int main( void )
+{
+    pthread_t t1, t2, t3;
+
+    pthread_create( &t1, NULL, thread1_func, NULL );
+    pthread_create( &t2, NULL, thread2_func, (void*)t1 );
+    pthread_create( &t3, NULL, thread3_func, (void*)t1 );
+
+    pthread_join(t2, NULL);
+    pthread_join(t3, NULL);
+
+    printf("OK\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_pthread_once.c b/tests/bionic/libc/common/test_pthread_once.c
new file mode 100644 (file)
index 0000000..3beda91
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define  N_THREADS  100
+
+static pthread_once_t   once = PTHREAD_ONCE_INIT;
+
+static int      global_count = 0;
+
+static void
+once_function( void )
+{
+    struct timespec ts;
+
+    global_count += 1;
+
+    ts.tv_sec = 2;
+    ts.tv_nsec = 0;
+    nanosleep (&ts, NULL);
+}
+
+static void*
+thread_function(void*  arg)
+{
+    pthread_once( &once, once_function );
+
+    if (global_count != 1) {
+        printf ("thread %ld: global == %d\n", (long int) arg, global_count);
+        exit (1);
+    }
+    return NULL;
+}
+
+int  main( void )
+{
+    pthread_t   threads[N_THREADS];
+    int         nn;
+
+    for (nn = 0; nn < N_THREADS; nn++) {
+        if (pthread_create( &threads[nn], NULL, thread_function, (void*)(long int)nn) < 0) {
+            printf("creation of thread %d failed\n", nn);
+            return 1;
+        }
+    }
+
+    for (nn = 0; nn < N_THREADS; nn++) {
+        if (pthread_join(threads[nn], NULL)) {
+            printf("joining thread %d failed\n", nn);
+            return 1;
+        }
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_semaphore.c b/tests/bionic/libc/common/test_semaphore.c
new file mode 100644 (file)
index 0000000..6792d86
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+
+/* a simple semaphore test, using three threads
+ *
+ *  a semaphore is initialized with a value of 1
+ *
+ *  Thread 1, 2 and 3 start at the same time
+ *
+ *  Thread 1 takes the semaphore, then sleeps for 2 seconds, then post the semaphore
+ *  Thread 2 sleeps for 1 second, then waits the semaphore, sleeps for 2 seconds, then post the semaphoe
+ *  Thread 3 sleeps 3 seconds, waits for the semaphore
+ */
+
+static  sem_t   semaphore;
+
+static void*
+_thread1( void* unused )
+{
+    printf( "thread 1: waiting for semaphore\n" );
+    if ( sem_wait( &semaphore ) < 0 ) {
+        printf( "thread 1: could not wait for semaphore: %s\n", strerror(errno) );
+        return NULL;
+    }
+    printf( "thread 1: got the semaphore ! sleeping for 2 seconds\n" );
+    sleep( 2 );
+    printf( "thread 1: awake !! posting semaphore\n" );
+    if ( sem_post( &semaphore ) < 0 ) {
+        printf( "thread 2: could not post semaphore: %s\n", strerror(errno) );
+    }
+    printf( "thread 1: quitting\n" );
+    return NULL;
+}
+
+static void*
+_thread2( void* unused )
+{
+    printf( "thread 2: sleeping for 1 second\n" );
+    sleep(1);
+    printf( "thread 2: awake !! waiting for semaphore\n" );
+    if ( sem_wait( &semaphore ) < 0 ) {
+        printf( "thread 2: could not wait for semaphore: %s\n", strerror(errno) );
+        return NULL;
+    }
+    printf( "thread 2: got the semaphore ! sleeping for 2 seconds\n" );
+    sleep( 2 );
+    printf( "thread 2: awake !! posting semaphore\n" );
+    if ( sem_post( &semaphore ) < 0 ) {
+        printf( "thread 2: could not post semaphore: %s\n", strerror(errno) );
+    }
+    printf( "thread 2: quitting\n" );
+    return NULL;
+}
+
+
+static void*
+_thread3( void* unused )
+{
+    printf( "thread 3: sleeping for 3 seconds\n" );
+    sleep(3);
+    printf( "thread 3: awake !! waiting for semaphore\n" );
+    if ( sem_wait( &semaphore ) < 0 ) {
+        printf( "thread 3: could not wait for semaphore: %s\n", strerror(errno) );
+        return NULL;
+    }
+    printf( "thread 3: got semaphore. quitting\n" );
+    return NULL;
+}
+
+typedef void*  (*thread_func)(void*);
+
+static const  thread_func  thread_routines[] =
+{
+    &_thread1,
+    &_thread2,
+    &_thread3
+};
+
+int  main( void )
+{
+    pthread_t   t[3];
+    int         nn;
+
+    if ( sem_init( &semaphore, 0, 1 ) < 0 ) {
+        printf( "could not initialize semaphore: %s\n", strerror(errno) );
+        return -1;
+    }
+
+    for ( nn = 0; nn < 3; nn++ ) {
+        if ( pthread_create( &t[nn], NULL, thread_routines[nn], NULL ) < 0 ) {
+            printf("could not create thread %d: %s\n", nn+1, strerror(errno) );
+            return -2;
+        }
+    }
+    sleep( 5 );
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_seteuid.c b/tests/bionic/libc/common/test_seteuid.c
new file mode 100644 (file)
index 0000000..ac330ce
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+int  main( void )
+{
+    uid_t ruid, euid;
+
+    printf( "sizeof(uid_t) = %d  sizeof(gid_t) = %d\n", sizeof(uid_t), sizeof(gid_t) );
+
+    ruid = getuid();
+    euid = geteuid();
+    printf("Start: ruid=%d euid=%d\n", ruid, euid);
+
+    if (seteuid(9999) != 0)
+       perror("seteuid(9999)");
+
+    ruid = getuid();
+    euid = geteuid();
+    printf("After set: ruid=%d euid=%d\n", ruid, euid);
+
+    if (seteuid(0) != 0)
+       perror("seteuid(0)");
+
+    ruid = getuid();
+    euid = geteuid();
+    printf("After restore: ruid=%d euid=%d\n", ruid, euid);
+
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_static_cpp_mutex.cpp b/tests/bionic/libc/common/test_static_cpp_mutex.cpp
new file mode 100644 (file)
index 0000000..33a56ef
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* this program is used to test the locking of a recursive mutex in a static C++ constructor
+ * this operation crashes on some
+ */
+#include <pthread.h>
+#include <stdio.h>
+
+class Foo {
+private:
+    pthread_mutex_t  mMutex;
+public:
+    virtual int   getValue();
+    Foo();
+};
+
+Foo::Foo()
+{
+    pthread_mutexattr_t  mattr;
+
+    pthread_mutexattr_init(&mattr);
+    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&mMutex, &mattr);
+    pthread_mutex_lock(&mMutex);
+    fprintf(stderr, "recursive lock initialized and locked\n" );
+}
+
+int Foo::getValue()
+{
+    return 0;
+}
+
+static Foo  f;
+
+int main(void)
+{
+    printf( "f.getValue() returned: %d\n", f.getValue() );
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_tm_zone.c b/tests/bionic/libc/common/test_tm_zone.c
new file mode 100644 (file)
index 0000000..63e0635
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* a small program to test the tm_zone setting in Bionic */
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int  main( void )
+{
+#ifndef TM_ZONE
+    fprintf(stderr, "TM_ZONE is not defined in <time.h> !!\n" );
+    return 1;
+#else
+    const char*  tz = getenv("TZ");
+    time_t       now = time(NULL);
+    struct tm    tm0;
+    struct tm*   tm;
+
+    if (tz) {
+        printf( "TZ set to '%s'\n", tz );
+    } else
+        printf( "TZ is not defined\n" );
+
+    tm = localtime_r( &now, &tm0 );
+    printf( "localtime_r() returns timezone abbreviation '%s'\n", tm->TM_ZONE ? tm->TM_ZONE : "<NULL POINTER>" );
+    printf( "tzname[0] is '%s'\n", tzname[0] ? tzname[0] : "<NULL POINTER>" );
+    printf( "tzname[1] is '%s'\n", tzname[1] ? tzname[1] : "<NULL POINTER>" );
+#endif
+    return 0;
+}
diff --git a/tests/bionic/libc/common/test_udp.c b/tests/bionic/libc/common/test_udp.c
new file mode 100644 (file)
index 0000000..3c9dd07
--- /dev/null
@@ -0,0 +1,121 @@
+/* this program is used to test UDP networking in Android.
+ * used to debug the emulator's networking implementation
+ */
+#define  PROGNAME      "test_udp"
+#define  DEFAULT_PORT  7000
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+
+#define BUFLEN 512
+#define NPACK  10
+
+void diep(char *s)
+{
+    perror(s);
+    exit(1);
+}
+
+static void
+usage(int  code)
+{
+    printf("usage: %s [options]\n", PROGNAME);
+    printf("options:\n");
+    printf("    -p<port>  use specific port (default %d)\n", DEFAULT_PORT);
+    printf("    -a<inet>  use specific IP address\n");
+    printf("    -s        run server (default is client)\n");
+    exit(code);
+}
+
+int main(int  argc, char**  argv)
+{
+    int   runServer = 0;
+    int   udpPort   = DEFAULT_PORT;
+    int   useLocal  = 0;
+    int   address   = htonl(INADDR_ANY);
+
+    struct sockaddr_in si_me, si_other;
+    int s, i, slen=sizeof(si_other);
+    char buf[BUFLEN];
+
+    while (argc > 1 && argv[1][0] == '-') {
+        const char*  optName = argv[1]+1;
+        argc--;
+        argv++;
+
+        switch (optName[0]) {
+            case 'p':
+                udpPort = atoi(optName+1);
+                if (udpPort < 1024 || udpPort > 65535) {
+                    fprintf(stderr, "UDP port must be between 1024 and 65535\n");
+                    exit(1);
+                }
+                break;
+
+            case 's':
+                runServer = 1;
+                break;
+
+            case 'a':
+                if (inet_aton(optName+1, &si_other.sin_addr) == 0)
+                    diep("inet_aton");
+                address = si_other.sin_addr.s_addr;
+                break;
+
+            default:
+                usage(1);
+        }
+    }
+
+    if (runServer) {
+        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
+        diep("socket");
+
+        memset((char *) &si_me, 0, sizeof(si_me));
+        si_me.sin_family      = AF_INET;
+        si_me.sin_port        = htons(udpPort);
+        si_me.sin_addr.s_addr = address;
+        if (bind(s, (struct sockaddr*)&si_me, sizeof(si_me))==-1)
+            diep("bind");
+
+        printf("UDP server listening on %s:%d\n", inet_ntoa(si_me.sin_addr), udpPort);
+        for (i=0; i<NPACK; i++) {
+        if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, (socklen_t*)&slen)==-1)
+            diep("recvfrom()");
+        printf("Received packet from %s:%d\nData: %s\n\n", 
+                inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
+        }
+
+        printf("UDP server closing\n");
+        close(s);
+    }
+    else  /* !runServer */
+    {
+        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
+            diep("socket");
+
+        memset((char *) &si_other, 0, sizeof(si_other));
+        si_other.sin_family = AF_INET;
+        si_other.sin_port = htons(udpPort);
+        si_other.sin_addr.s_addr = address;
+
+        printf("UDP client sending packets to %s:%d\n", inet_ntoa(si_other.sin_addr), udpPort);
+
+        for (i=0; i<NPACK; i++) {
+            printf("Sending packet %d\n", i);
+            sprintf(buf, "This is packet %d\n", i);
+            if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, slen)==-1)
+            diep("sendto()");
+        }
+
+        close(s);
+        printf("UDP client closing\n");
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/glibc/assert/test-assert.c b/tests/bionic/libc/glibc/assert/test-assert.c
new file mode 100644 (file)
index 0000000..26b58d4
--- /dev/null
@@ -0,0 +1,88 @@
+/* Test assert().
+ *
+ * This is hairier than you'd think, involving games with
+ * stdio and signals.
+ *
+ */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+jmp_buf rec;
+char buf[160];
+
+static void
+sigabrt (int unused)
+{
+  longjmp (rec, 1);  /* recover control */
+}
+
+#undef NDEBUG
+#include <assert.h>
+static void
+assert1 (void)
+{
+  assert (1 == 2);
+}
+
+static void
+assert2 (void)
+{
+  assert (1 == 1);
+}
+
+
+#define NDEBUG
+#include <assert.h>
+static void
+assert3 (void)
+{
+  assert (2 == 3);
+}
+
+int
+main (void)
+{
+
+  volatile int failed = 1;
+
+  fclose (stderr);
+  stderr = tmpfile ();
+  if(!stderr)
+    abort ();
+
+  signal (SIGABRT, sigabrt);
+
+  if (!setjmp (rec))
+    assert1 ();
+  else
+    failed = 0;  /* should happen */
+
+  if (!setjmp (rec))
+    assert2 ();
+  else
+    failed = 1; /* should not happen */
+
+  if (!setjmp (rec))
+    assert3 ();
+  else
+    failed = 1; /* should not happen */
+
+  rewind (stderr);
+  fgets (buf, 160, stderr);
+  if (!strstr (buf, "1 == 2"))
+    failed = 1;
+
+  fgets (buf, 160, stderr);
+  if (strstr (buf, "1 == 1"))
+    failed = 1;
+
+  fgets (buf, 160, stderr);
+  if (strstr (buf, "2 == 3"))
+    failed = 1;
+
+  return failed;
+}
diff --git a/tests/bionic/libc/other/bench_locks.c b/tests/bionic/libc/other/bench_locks.c
new file mode 100644 (file)
index 0000000..87b1c4c
--- /dev/null
@@ -0,0 +1,32 @@
+/* a small program to benchmark locking primitives with different implementations */
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+static double  now(void)
+{
+    struct timeval   tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec + tv.tv_usec/1000000.0;
+}
+
+int  main( void )
+{
+    double             t0, t1;
+    pthread_mutex_t    lock1 = PTHREAD_MUTEX_INITIALIZER;
+    int volatile       lock2 = 0;
+    long               count;
+    const long         ITERATIONS = 1000000;
+
+    /* pthread_mutex_lock */
+    t0 = now();
+    for (count = ITERATIONS; count > 0; count--) {
+        pthread_mutex_lock(&lock1);
+        pthread_mutex_unlock(&lock1);
+    }
+    t1 = now() - t0;
+    printf( "pthread_mutex_lock/unlock:  %.5g us/op\n", (t1*1000000.0)/ITERATIONS );
+
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_aligned.c b/tests/bionic/libc/other/test_aligned.c
new file mode 100644 (file)
index 0000000..8a66dd6
--- /dev/null
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <arpa/inet.h>  /* for htons() etc.. */
+
+static char  tab[8];
+
+static void
+read4( int  o, unsigned val )
+{
+    unsigned  v = htonl(val);
+    unsigned  v2;
+
+    tab[o+0] = (char)(v >> 24);
+    tab[o+1] = (char)(v >> 16);
+    tab[o+2] = (char)(v >> 8);
+    tab[o+3] = (char)(v);
+
+    printf( "read4: offset=%d value=%08x: ", o, val );
+    fflush(stdout);
+
+    v2 = *(unsigned*)(tab+o);
+
+    if (v2 != val) {
+        printf( "FAIL (%08x)\n", v2 );
+    } else {
+        printf( "ok\n" );
+    }
+}
+
+static void
+writ4( int  o, unsigned val )
+{
+    unsigned  v = htonl(val);
+    unsigned  v2;
+
+    printf( "writ4: offset=%d value=%08x: ", o, val );
+    fflush(stdout);
+
+    *(unsigned*)(tab+o) = v;
+
+    v2 = ((unsigned)tab[o+0] << 24) |
+         ((unsigned)tab[o+1] << 16) |
+         ((unsigned)tab[o+2] << 8 ) |
+         ((unsigned)tab[o+3]      );
+
+    if (v2 != val) {
+        printf( "FAIL (%08x)\n", v2 );
+    } else {
+        printf( "ok\n" );
+    }
+}
+
+static void
+read2( int  o, unsigned val )
+{
+    unsigned short v = htons(val);
+    unsigned short v2;
+
+    tab[o+0] = (char)(v >> 8);
+    tab[o+1] = (char)(v);
+
+    printf( "read2: offset=%d value=%08x: ", o, val );
+    fflush(stdout);
+
+    v2 = *(unsigned short*)(tab+o);
+
+    if (v2 != val) {
+        printf( "FAIL (%04x)\n", v2 );
+    } else {
+        printf( "ok\n" );
+    }
+}
+
+static void
+writ2( int  o, unsigned val )
+{
+    unsigned short v = htons(val);
+    unsigned short v2;
+
+    printf( "writ2: offset=%d value=%08x: ", o, val );
+    fflush(stdout);
+
+    *(unsigned short*)(tab+o) = v;
+
+    v2 = ((unsigned)tab[o+0] << 8) |
+         ((unsigned)tab[o+1]       );
+
+    if (v2 != val) {
+        printf( "FAIL (%08x)\n", v2 );
+    } else {
+        printf( "ok\n" );
+    }
+}
+
+
+
+int  main(void)
+{
+    read4( 0, 0x12345678 );
+    writ4( 0, 0x12345678 );
+    read4( 1, 0x12345678 );
+    writ4( 1, 0x12345678 );
+    read4( 2, 0x12345678 );
+    writ4( 2, 0x12345678 );
+    read4( 3, 0x12345678 );
+    writ4( 3, 0x12345678 );
+
+    read2( 0, 0x1234 );
+    writ2( 0, 0x1234 );
+    read2( 1, 0x1234 );
+    writ2( 1, 0x1234 );
+    read2( 2, 0x1234 );
+    writ2( 2, 0x1234 );
+    read2( 3, 0x1234 );
+    writ2( 3, 0x1234 );
+
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_arc4random.c b/tests/bionic/libc/other/test_arc4random.c
new file mode 100644 (file)
index 0000000..4829a2d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+   unsigned int arc4random();
+
+   int i;
+
+   for (i = 0; i < 50; i++) {
+       printf("%u\n", arc4random());
+   }
+   return 0;
+}
diff --git a/tests/bionic/libc/other/test_atomics.c b/tests/bionic/libc/other/test_atomics.c
new file mode 100644 (file)
index 0000000..0de2a93
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+
+extern int __atomic_dec(volatile int* addr);
+
+int main(int argc, const char *argv[])
+{
+    int x = 5;
+
+    while (x > -20) {
+        printf("old_x=%d\n", __atomic_dec(&x));
+        printf("x=%d\n", x);
+    }
+
+    printf ("OK\n");
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_jpeg.c b/tests/bionic/libc/other/test_jpeg.c
new file mode 100644 (file)
index 0000000..8d7ef1a
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* this small program is used to measure the performance of libjpeg decompression
+ * algorithm...
+ */
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "jpeglib.h"
+#include <setjmp.h>
+#ifdef HAVE_ANDROID_OS
+#include <hardware/qemu_tracing.h>
+#endif
+
+#define  USE_STDIO
+
+#define  CHUNK    32768
+
+typedef struct {
+    struct jpeg_source_mgr  jpeg_mgr;
+    char*                   base;
+    char*                   cursor;
+    char*                   end;
+} SourceMgrRec, *SourceMgr;
+
+static void
+_source_init_source(j_decompress_ptr cinfo)
+{
+    SourceMgr  src = (SourceMgr) cinfo->src;
+
+    src->jpeg_mgr.next_input_byte = (unsigned char*)src->base,
+    src->jpeg_mgr.bytes_in_buffer = src->end - src->base;
+}
+
+static int
+_source_fill_input_buffer(j_decompress_ptr cinfo)
+{
+    SourceMgr  src = (SourceMgr) cinfo->src;
+
+    cinfo->err->error_exit((j_common_ptr)cinfo);
+    return FALSE;
+}
+
+static void
+_source_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+    SourceMgr  src = (SourceMgr) cinfo->src;
+
+    if (src->jpeg_mgr.next_input_byte + num_bytes > (unsigned char*)src->end ) {
+        cinfo->err->error_exit((j_common_ptr)cinfo);
+    }
+
+    src->jpeg_mgr.next_input_byte += num_bytes;
+    src->jpeg_mgr.bytes_in_buffer -= num_bytes;
+}
+
+static int
+_source_resync_to_restart( j_decompress_ptr cinfo, int desired)
+{
+    SourceMgr  src = (SourceMgr) cinfo->src;
+
+    src->jpeg_mgr.next_input_byte = (unsigned char*)src->base;
+    src->jpeg_mgr.bytes_in_buffer = src->end - src->base;
+    return TRUE;
+}
+
+static void
+_source_term_source(j_decompress_ptr  cinfo)
+{
+    // nothing to do
+}
+
+static void
+_source_init( SourceMgr  src, char*  base, long  size )
+{
+    src->base   = base;
+    src->cursor = base;
+    src->end    = base + size;
+
+    src->jpeg_mgr.init_source       = _source_init_source;
+    src->jpeg_mgr.fill_input_buffer = _source_fill_input_buffer;
+    src->jpeg_mgr.skip_input_data   = _source_skip_input_data;
+    src->jpeg_mgr.resync_to_restart = _source_resync_to_restart;
+    src->jpeg_mgr.term_source       = _source_term_source;
+}
+
+
+typedef struct {
+    struct jpeg_error_mgr   jpeg_mgr;
+    jmp_buf                 jumper;
+    int volatile            error;
+
+} ErrorMgrRec, *ErrorMgr;
+
+static void _error_exit(j_common_ptr cinfo)
+{
+    ErrorMgr error = (ErrorMgr) cinfo->err;
+
+    (*error->jpeg_mgr.output_message) (cinfo);
+
+    /* Let the memory manager delete any temp files before we die */
+    longjmp(error->jumper, -1);
+}
+
+#ifdef USE_STDIO
+int decompress(FILE*  input_file, int  dct_method, int  disable_rgb)
+#else
+int decompress(char*  data, long  fsize)
+#endif
+{
+    ErrorMgrRec             errmgr;
+    SourceMgrRec            sourcemgr;
+    struct jpeg_decompress_struct  cinfo;
+    int volatile            error = 0;
+    jmp_buf                 jumper;
+    int                     isRGB;
+    char*                   pixels;
+    JSAMPLE*                temprow;
+
+    memset( &cinfo, 0, sizeof(cinfo) );
+    memset( &errmgr, 0, sizeof(errmgr) );
+    jpeg_create_decompress(&cinfo);
+    cinfo.err         = jpeg_std_error(&errmgr.jpeg_mgr);
+#if 0
+    errmgr.jpeg_mgr.error_exit = _error_exit;
+    errmgr.error      = 0;
+#endif
+
+    if (setjmp(errmgr.jumper) != 0) {
+        fprintf(stderr, "returning error from jpeglib ---\n" );
+        goto Exit;
+    }
+
+#ifdef USE_STDIO
+    /* Specify data source for decompression */
+    jpeg_stdio_src(&cinfo, input_file);
+#else
+    _source_init( &sourcemgr, data, fsize );
+    cinfo.src = &sourcemgr.jpeg_mgr;
+#endif
+
+    jpeg_read_header(&cinfo, 1);
+
+    if (3 == cinfo.num_components && JCS_RGB == cinfo.out_color_space)
+        isRGB = 1;
+    else if (1 == cinfo.num_components && JCS_GRAYSCALE == cinfo.out_color_space)
+        isRGB = 0;  // could use Index8 config if we want...
+    else {
+        fprintf( stderr, "unsupported jpeg colorspace %d with %d components\n",
+                  cinfo.jpeg_color_space, cinfo.num_components );
+        goto Exit;
+    }
+
+    cinfo.dct_method = dct_method;
+    if (disable_rgb)
+        cinfo.out_color_space = JCS_YCbCr;
+
+    jpeg_start_decompress(&cinfo);
+
+    temprow = calloc( cinfo.num_components * cinfo.output_width, sizeof(JSAMPLE) );
+
+    {
+        unsigned  y;
+        for (y = 0; y < cinfo.output_height; y++) {
+            JSAMPLE*  rowptr = temprow;
+            (void)jpeg_read_scanlines(&cinfo, &rowptr, 1);
+        }
+    }
+    jpeg_finish_decompress(&cinfo);
+
+    free( temprow );
+Exit:
+    jpeg_destroy_decompress(&cinfo);
+    return error;
+}
+
+
+#define  DEFAULT_REPEAT  10
+
+static void usage(void)
+{
+    fprintf(stderr, "usage: test_jpeg [options] filename.jpg [filename2.jpg ...]\n" );
+    fprintf(stderr, "options:  -r NN   repeat count  (default %d)\n", DEFAULT_REPEAT );
+    fprintf(stderr, "          -d N    idct method   (0=default, 1=fastest, 2=slow, 3=float)\n" );
+    fprintf(stderr, "          -C      no RGB color conversion (YCbCr instead)\n" );
+    exit(1);
+}
+
+static double
+get_time_usec( void )
+{
+#ifdef HAVE_ANDROID_OS
+    struct timespec  ts;
+
+    if ( clock_gettime( CLOCK_MONOTONIC, &ts ) < 0 )
+        fprintf(stderr, "clock_gettime: %s\n", strerror(errno) );
+
+    return ts.tv_sec*1e6 + ts.tv_nsec*1e-3;
+#else
+    struct timeval  tv;
+    if (gettimeofday( &tv, NULL ) < 0)
+        fprintf(stderr, "gettimeofday: %s\n", strerror(errno) );
+
+    return tv.tv_sec*1000000. + tv.tv_usec*1.0;
+#endif
+}
+
+
+int  main( int  argc, char**  argv )
+{
+    FILE*  f;
+    int    repeat_count      = DEFAULT_REPEAT;
+    int    dct_method        = JDCT_DEFAULT;
+    int    disable_rgb       = 0;
+    double  usec0, usec1;
+
+    if (argc < 2)
+        usage();
+
+    for ( ; argc > 1 && argv[1][0] == '-'; argc--, argv++) {
+        const char*  arg = &argv[1][1];
+        switch (arg[0]) {
+            case 'r':
+                if (arg[1] == 0) {
+                    if (argc < 3)
+                        usage();
+                    arg = argv[2];
+                    argc--;
+                    argv++;
+                } else
+                    arg += 1;
+
+                repeat_count = strtol(arg, NULL, 10);
+
+                if (repeat_count <= 0)
+                    repeat_count = 1;
+                break;
+
+            case 'C':
+                disable_rgb = 1;
+                break;
+
+            case 'd':
+                if (arg[1] == 0) {
+                    if (argc < 3)
+                        usage();
+                    arg = argv[2];
+                    argc--;
+                    argv++;
+                } else
+                    arg += 1;
+
+                dct_method = strtol(arg, NULL, 10);
+                switch (dct_method) {
+                    case 0:
+                        dct_method = JDCT_DEFAULT;
+                        break;
+                    case 1:
+                        dct_method = JDCT_IFAST;
+                        break;
+                    case 2:
+                        dct_method = JDCT_ISLOW;
+                        break;
+                    case 3:
+                        dct_method = JDCT_FLOAT;
+                        break;
+                    default:
+                        usage();
+                }
+                break;
+
+            default:
+                usage();
+        }
+    }
+
+    for ( ; argc > 1; argc--, argv++ )
+    {
+        long   fsize;
+        char*   data;
+        FILE*  f = fopen( argv[1], "rb" );
+        int    rr;
+
+        if (f == NULL) {
+            fprintf(stderr, "could not open '%s': %s\n", argv[1], strerror(errno) );
+            continue;
+        }
+
+        fseek( f, 0, SEEK_END );
+        fsize = ftell(f);
+        fseek( f, 0, SEEK_SET );
+
+        usec0 = get_time_usec();
+#ifdef HAVE_ANDROID_OS
+        qemu_start_tracing();
+#endif
+#ifdef USE_STDIO
+        for ( rr = repeat_count; rr > 0; rr-- ) {
+            fseek( f, 0, SEEK_SET );
+            decompress(f, dct_method, disable_rgb);
+        }
+        fclose( f );
+#else
+
+        data = malloc( fsize );
+        if (data == NULL) {
+            if (fsize > 0)
+                fprintf(stderr, "could not allocate %ld bytes to load '%s'\n", fsize, argv[1] );
+            fclose(f);
+            continue;
+        }
+        fread( data, 1, fsize, f );
+        fclose(f);
+
+        usec1 = get_time_usec() - usec0;
+        printf( "compressed load:     %10.2f ms (%ld bytes)\n", usec1*1e-3, fsize );
+
+        usec0 = get_time_usec();
+        for ( rr = repeat_count; rr > 0; rr -- )
+        {
+            decompress( data, fsize );
+        }
+        free( data );
+#endif
+#ifdef HAVE_ANDROID_OS
+        qemu_stop_tracing();
+#endif
+        usec1 = get_time_usec() - usec0;
+        printf( "decompression took:  %10.3f ms (%.2f KB/s, %d passes)\n", usec1/1e3, fsize*(1e6/1024)*repeat_count/usec1, repeat_count );
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_sysconf.c b/tests/bionic/libc/other/test_sysconf.c
new file mode 100644 (file)
index 0000000..717cbcb
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#define  T(_name,_cond)                                               \
+    errno = 0;                                                        \
+    printf( "testing %-*s : ", 32, #_name );                          \
+    ret   = sysconf( _name );                                         \
+    if (ret < 0 && errno != 0) {                                      \
+        printf( "error: %s\n", strerror(errno) );                     \
+    } else {                                                          \
+        if ( ret _cond )  {                                           \
+            printf( "OK  (%d)\n", ret );                              \
+        } else {                                                      \
+            printf( "ERROR: %d does not meet %s\n", ret, #_cond );    \
+        }                                                             \
+    }
+
+int  main( void )
+{
+    int  ret;
+    T(_SC_ARG_MAX, > 0);
+    T(_SC_BC_BASE_MAX, |1 );
+    T(_SC_BC_DIM_MAX, |1 );
+    T(_SC_BC_SCALE_MAX, |1 );
+    T(_SC_BC_STRING_MAX, |1 );
+    T(_SC_CHILD_MAX, >0 );
+    T(_SC_CLK_TCK, >0 );
+    T(_SC_COLL_WEIGHTS_MAX, |1 );
+    T(_SC_EXPR_NEST_MAX, |1 );
+    T(_SC_LINE_MAX, > 256 );
+    T(_SC_NGROUPS_MAX, >0 );
+    T(_SC_OPEN_MAX, >128 );
+    T(_SC_PASS_MAX, |1 );
+    T(_SC_2_C_BIND, >0 );
+    T(_SC_2_C_DEV, |1 );
+    T(_SC_2_C_VERSION, |1 );
+    T(_SC_2_CHAR_TERM, |1 );
+    T(_SC_2_FORT_DEV, |1 );
+    T(_SC_2_FORT_RUN, |1 );
+    T(_SC_2_LOCALEDEF, |1 );
+    T(_SC_2_SW_DEV, |1 );
+    T(_SC_2_UPE, |1 );
+    T(_SC_2_VERSION, |1);
+    T(_SC_JOB_CONTROL, == 1);
+    T(_SC_SAVED_IDS, == 1);
+    T(_SC_VERSION, |1);
+    T(_SC_RE_DUP_MAX, |1);
+    T(_SC_STREAM_MAX, > 0);
+    T(_SC_TZNAME_MAX, |1 );
+    T(_SC_XOPEN_CRYPT, |1 );
+    T(_SC_XOPEN_ENH_I18N, |1 );
+    T(_SC_XOPEN_SHM, |1 );
+    T(_SC_XOPEN_VERSION, |1 );
+    T(_SC_XOPEN_XCU_VERSION, |1 );
+    T(_SC_XOPEN_REALTIME, |1 );
+    T(_SC_XOPEN_REALTIME_THREADS, |1 );
+    T(_SC_XOPEN_LEGACY, |1 );
+    T(_SC_ATEXIT_MAX, >32 );
+    T(_SC_IOV_MAX, >0 );
+    T(_SC_PAGESIZE, == 4096 );
+    T(_SC_PAGE_SIZE, == 4096 );
+    T(_SC_XOPEN_UNIX, |1 );
+    T(_SC_XBS5_ILP32_OFF32, |1 );
+    T(_SC_XBS5_ILP32_OFFBIG, |1 );
+    T(_SC_XBS5_LP64_OFF64, |1 );
+    T(_SC_XBS5_LPBIG_OFFBIG, |1 );
+    T(_SC_AIO_LISTIO_MAX, |1 );
+    T(_SC_AIO_MAX, |1 );
+    T(_SC_AIO_PRIO_DELTA_MAX, |1 );
+    T(_SC_DELAYTIMER_MAX, >0 );
+    T(_SC_MQ_OPEN_MAX, |1 );
+    T(_SC_MQ_PRIO_MAX, >0 );
+    T(_SC_RTSIG_MAX, |1 );
+    T(_SC_SEM_NSEMS_MAX, |1 );
+    T(_SC_SEM_VALUE_MAX, |1 );
+    T(_SC_SIGQUEUE_MAX, >0 );
+    T(_SC_TIMER_MAX, |1 );
+    T(_SC_ASYNCHRONOUS_IO, |1 );
+    T(_SC_FSYNC, |1 );
+    T(_SC_MAPPED_FILES, |1 );
+    T(_SC_MEMLOCK, |1 );
+    T(_SC_MEMLOCK_RANGE, |1 );
+    T(_SC_MEMORY_PROTECTION, |1 );
+    T(_SC_MESSAGE_PASSING, |1 );
+    T(_SC_PRIORITIZED_IO, |1 );
+    T(_SC_PRIORITY_SCHEDULING, |1 );
+    T(_SC_REALTIME_SIGNALS, |1 );
+    T(_SC_SEMAPHORES, |1 );
+    T(_SC_SHARED_MEMORY_OBJECTS, |1 );
+    T(_SC_SYNCHRONIZED_IO, |1 );
+    T(_SC_TIMERS, |1 );
+    T(_SC_GETGR_R_SIZE_MAX, |1 );
+    T(_SC_GETPW_R_SIZE_MAX, |1 );
+    T(_SC_LOGIN_NAME_MAX, |1 );
+    T(_SC_THREAD_DESTRUCTOR_ITERATIONS, |1 );
+    T(_SC_THREAD_KEYS_MAX, > 0 );
+    T(_SC_THREAD_STACK_MIN, >= 8192 );
+    T(_SC_THREAD_THREADS_MAX, |1 );
+    T(_SC_TTY_NAME_MAX, > 0 );
+    T(_SC_THREADS, |1 );
+    T(_SC_THREAD_ATTR_STACKADDR, |1 );
+    T(_SC_THREAD_ATTR_STACKSIZE, |1 );
+    T(_SC_THREAD_PRIORITY_SCHEDULING, |1 );
+    T(_SC_THREAD_PRIO_INHERIT, |1 );
+    T(_SC_THREAD_PRIO_PROTECT, |1 );
+    T(_SC_THREAD_SAFE_FUNCTIONS, |1 );
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_system.c b/tests/bionic/libc/other/test_system.c
new file mode 100644 (file)
index 0000000..adb4c56
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+int
+main(int argc, char *argv[])
+{
+    int rv;
+
+    if (argc < 2)
+        return -1;
+
+    rv = system(argv[1]);
+    if (rv < 0) {
+        fprintf(stderr, "Error calling system(): %d\n", errno);
+        return 1;
+    }
+
+    printf("Done!\n");
+
+    if (WEXITSTATUS(rv) != 0) {
+        fprintf(stderr, "Command returned non-zero exit code: %d\n",
+                WEXITSTATUS(rv));
+        return 1;
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_thread_max.c b/tests/bionic/libc/other/test_thread_max.c
new file mode 100644 (file)
index 0000000..7aeb5c5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+static void*
+thread_func( void*  arg )
+{
+    fprintf(stderr, "thread %ld\n", (long)arg );
+    return NULL;
+}
+
+int  main( void )
+{
+    int              count;
+    pthread_attr_t   attr;
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
+    pthread_attr_setstacksize( &attr, 16*4096 );
+
+    for ( count = 0; count != ~0; count++ ) {
+        pthread_t        thread;
+        struct timespec  ts;
+
+        if (pthread_create( &thread, &attr, thread_func, (void*)(long)count ) < 0) {
+            fprintf(stderr, "could not create thread %d\n", count);
+            break;
+        }
+        ts.tv_sec  = 0;
+        ts.tv_nsec = 0.002*1e9;
+        nanosleep( &ts, &ts );
+    }
+    sleep(1);
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_timer_create.c b/tests/bionic/libc/other/test_timer_create.c
new file mode 100644 (file)
index 0000000..8995e12
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+void
+handle(sigval_t v)
+{
+    time_t  t;
+    char    p[32];
+
+    time(&t);
+    strftime(p, sizeof(p), "%T", localtime(&t));
+    printf("%s thread %d, val = %d, signal captured.\n", 
+            p,  (int)pthread_self(), v.sival_int);
+    return;
+}
+
+int
+create(int seconds, int id)
+{
+    timer_t tid;
+    struct sigevent se;
+    struct itimerspec ts, ots;
+
+    memset(&se, 0, sizeof (se));
+    se.sigev_notify = SIGEV_THREAD;
+    se.sigev_notify_function = handle;
+    se.sigev_value.sival_int = id;
+
+    if (timer_create (CLOCK_REALTIME, &se, &tid) < 0)
+    {
+        perror ("timer_creat");
+        return -1;
+    }
+    puts ("timer_create successfully.");
+    ts.it_value.tv_sec = 3;
+    ts.it_value.tv_nsec = 0;
+    ts.it_interval.tv_sec = seconds;
+    ts.it_interval.tv_nsec = 0;
+    if (timer_settime (tid, TIMER_ABSTIME, &ts, &ots) < 0)
+    {
+        perror ("timer_settime");
+        return -1;
+    }
+    return 0;
+}
+
+int
+main (void)
+{
+    if (create (3, 1) < 0) return 1;
+    if (create (5, 2) < 0) return 1;
+    for (;;)
+    {
+        sleep (10);
+    }
+    return 0;
+}
diff --git a/tests/bionic/libc/other/test_vfprintf_leak.c b/tests/bionic/libc/other/test_vfprintf_leak.c
new file mode 100644 (file)
index 0000000..4e94c51
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* this test is used to check that a memory-leak in vfprintf was fixed.
+ * the initial code leaked heap memory each time a formatted double was printed
+ */
+#include <stdio.h>
+
+extern size_t  dlmalloc_footprint();
+
+int  main(void)
+{
+    size_t   initial = dlmalloc_footprint();
+    size_t   final;
+    char     temp[64];
+    int      n;
+
+    for (n = 0; n < 10000; n++)
+        snprintf( temp, sizeof(temp), "%g", n*0.647287623 );
+
+    final   = dlmalloc_footprint();
+    /* vfprintf uses temporary heap blocks to do the formatting, so */
+    /* it's OK to have one page in there                            */
+    if (final <= 4096) {
+        printf( "OK: initial = %ld, final == %ld\n", (long)initial, (long)final );
+        return 0;
+    } else {
+        fprintf(stderr, "KO: initial == %ld, final == %ld\n", (long)initial, (long)final );
+        return 1;
+    }
+}
diff --git a/tests/bionic/libc/other/test_zlib.c b/tests/bionic/libc/other/test_zlib.c
new file mode 100644 (file)
index 0000000..3eae827
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 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.
+ *
+ * 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 OWNER 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.
+ */
+/* this small program is used to measure the performance of zlib's inflate
+ * algorithm...
+ */
+
+/* most code lifted from the public-domain http://www.zlib.net/zpipe.c */
+
+#include <zlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#define  CHUNK    32768
+
+int def(FILE *source, FILE *dest, int level)
+{
+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+    /* compress until end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+        /* run deflate() on input until output buffer not full, finish
+        compression if all of source has been read in */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+            ret = deflate(&strm, flush);    /* no bad return value */
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+        } while (strm.avail_out == 0);
+
+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+
+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+
+int inf(FILE *source)
+{
+    int ret;
+    unsigned have;
+    z_stream strm;
+    static unsigned char in[CHUNK];
+    static unsigned char out[CHUNK];
+
+    /* allocate inflate state */
+    strm.zalloc   = Z_NULL;
+    strm.zfree    = Z_NULL;
+    strm.opaque   = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in  = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+    /* decompress until deflate stream ends or end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+        /* run inflate() on input until output buffer not full */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out  = out;
+            ret = inflate(&strm, Z_NO_FLUSH);
+            switch (ret) {
+                case Z_NEED_DICT:
+                    ret = Z_DATA_ERROR;     /* and fall through */
+                case Z_DATA_ERROR:
+                case Z_MEM_ERROR:
+                    (void)inflateEnd(&strm);
+                    return ret;
+            }
+        } while (strm.avail_out == 0);
+
+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+#define  DEFAULT_REPEAT  10
+#define  DEFAULT_LEVEL   9
+
+static void usage(void)
+{
+    fprintf(stderr, "usage: test_zlib [options] filename [filename2 ...]\n" );
+    fprintf(stderr, "options:  -r NN   repeat count  (default %d)\n", DEFAULT_REPEAT );
+    fprintf(stderr, "          -N      set compression level (default %d)\n", DEFAULT_LEVEL );
+    exit(1);
+}
+
+static double
+get_time_usec( void )
+{
+#ifdef HAVE_ANDROID_OS
+    struct timespec  ts;
+
+    if ( clock_gettime( CLOCK_MONOTONIC, &ts ) < 0 )
+        fprintf(stderr, "clock_gettime: %s\n", strerror(errno) );
+
+    return ts.tv_sec*1e6 + ts.tv_nsec*1e-3;
+#else
+    struct timeval  tv;
+    if (gettimeofday( &tv, NULL ) < 0)
+        fprintf(stderr, "gettimeofday: %s\n", strerror(errno) );
+
+    return tv.tv_sec*1000000. + tv.tv_usec*1.0;
+#endif
+}
+
+int  main( int  argc, char**  argv )
+{
+    FILE*  f;
+    char   tempfile[256];
+    int    repeat_count      = DEFAULT_REPEAT;
+    int    compression_level = DEFAULT_LEVEL;
+    double  usec0, usec1;
+
+    if (argc < 2)
+        usage();
+
+    for ( ; argc > 1 && argv[1][0] == '-'; argc--, argv++) {
+        const char*  arg = &argv[1][1];
+        switch (arg[0]) {
+            case 'r':
+                if (arg[1] == 0) {
+                    if (argc < 3)
+                        usage();
+                    arg = argv[2];
+                    argc--;
+                    argv++;
+                } else
+                    arg += 1;
+
+                repeat_count = strtol(arg, NULL, 10);
+
+                if (repeat_count <= 0)
+                    repeat_count = 1;
+                break;
+
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                compression_level = arg[0] - '0';
+                break;
+
+            default:
+                usage();
+        }
+    }
+
+    sprintf(tempfile, "/tmp/ztest.%d", getpid() );
+
+    for ( ; argc > 1; argc--, argv++ )
+    {
+        /* first, compress the file into a temporary storage */
+        FILE*  f   = fopen(argv[1], "rb");
+        FILE*  out = NULL;
+        long   fsize;
+        int    ret, rr;
+
+        if (f == NULL) {
+            fprintf(stderr, "could not open '%s': %s\n", argv[1], strerror(errno) );
+            continue;
+        }
+
+        printf( "testing %s\n", argv[1] );
+        fseek( f, 0, SEEK_END );
+        fsize = ftell(f);
+        fseek( f, 0, SEEK_SET );
+
+        out = fopen( tempfile, "wb" );
+        if (out == NULL) {
+            fprintf(stderr, "could not create '%s': %s\n", tempfile, strerror(errno));
+            fclose(f);
+            continue;
+        }
+
+        usec0 = get_time_usec();
+
+        ret = def( f, out, compression_level );
+
+        usec1 = get_time_usec() - usec0;
+        printf( "compression took:   %10.3f ms  (%.2f KB/s)\n", usec1/1e3, fsize*(1e6/1024)/usec1 );
+
+        fclose( out );
+        fclose(f);
+
+        usec0 = get_time_usec();
+        f    = fopen( tempfile, "rb" );
+
+        for ( rr = repeat_count; rr > 0; rr -- )
+        {
+            fseek( f, 0, SEEK_SET );
+            inf(f);
+        }
+        fclose( f );
+        usec1 = get_time_usec() - usec0;
+        printf( "decompression took: %10.3f ms (%.2f KB/s, %d passes)\n", usec1/1e3, fsize*(1e6/1024)*repeat_count/usec1, repeat_count );
+    }
+
+    unlink(tempfile);
+    return 0;
+}
index 88e3cd8..0b258b1 100644 (file)
@@ -22,3 +22,11 @@ LOCAL_MODULE_TAGS := tests eng
 LOCAL_SRC_FILES := cpueater.c
 include $(BUILD_EXECUTABLE)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := daemonize
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := tests eng
+LOCAL_SRC_FILES := daemonize.c
+LOCAL_SHARED_LIBRARIES := libhardware
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/cpueater/daemonize.c b/tests/cpueater/daemonize.c
new file mode 100644 (file)
index 0000000..8d07a1c
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+
+#include "hardware/power.h"
+
+
+main(int argc, char **argv)
+{
+  int pid, fd, mode;
+  unsigned int delay = 0;
+  int status = 0;
+  char *file = 0;
+  char lockid[32];
+
+  if (argc < 2) { 
+    printf("Usage: %s [-f logfile] [-a] [-d delay] <program>\n", argv[0]);
+    exit(1);
+  }
+  close(0); open("/dev/null", 0);
+  close(1);
+
+  mode = O_TRUNC;
+
+  while(**++argv == '-') {
+    while(*++*argv) {
+      switch(**argv) {
+        case 'f':
+          if(*++*argv)
+            file = *argv;
+          else
+            file = *++argv;
+          goto next_arg;
+        case 'd':
+          if(*++*argv)
+            delay = atoi(*argv);
+          else
+            delay = atoi(*++argv);
+          goto next_arg;
+        case 'a':
+          mode = O_APPEND;
+          break;
+      }
+    }
+next_arg: ;
+  }
+
+  if (file) {
+      if(open(file, O_WRONLY|mode|O_CREAT, 0666) < 0) {
+        perror(file);
+        exit(1);
+      }
+  }
+  else {
+      if(open("/dev/null", O_WRONLY) < 0) {
+        perror("/dev/null");
+        exit(1);
+      }
+  }
+
+  switch(pid = fork()) {
+    case -1:
+      perror(argv[0]);
+      exit(1);
+      break;
+    case 0:
+      fflush(stdout);
+      close(2); dup(1); /* join stdout and stderr */
+      chdir("/");
+      umask(0);
+      setpgrp();
+      setsid();
+      for (fd = 3; fd < 256; fd++) {
+          close(fd);
+      }
+      if(delay) {
+          snprintf(lockid, 32, "daemonize%d", (int) getpid());
+          acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid);
+      }
+
+      switch(pid = fork()) {
+        case -1:
+          break;
+        case 0:
+          if(delay) {
+              sleep(delay);
+          }
+          execv(argv[0], argv);
+          execvp(argv[0], argv);
+          perror(argv[0]);
+          break;
+        default:
+          if(delay) {
+              waitpid(pid, &status, 0);
+              release_wake_lock(lockid);
+          }
+          _exit(0);
+      }
+      _exit(1);
+      break;
+    default:
+      exit(0);
+      break;
+  }
+}
+
+/* vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab */
diff --git a/tests/framebuffer/Android.mk b/tests/framebuffer/Android.mk
new file mode 100644 (file)
index 0000000..d6a8537
--- /dev/null
@@ -0,0 +1,33 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+       refresh.c
+
+LOCAL_SHARED_LIBRARIES := \
+       libcutils
+
+LOCAL_MODULE:= test-fb-refresh
+
+LOCAL_MODULE_TAGS := tests
+
+ifeq ($(TARGET_SIMULATOR),true)
+  ifeq ($(HOST_OS),linux)
+    # need this for clock_gettime()
+    LOCAL_LDLIBS += -lrt
+  endif
+endif
+
+include $(BUILD_EXECUTABLE)
+
+##
+
+ifneq ($(TARGET_SIMULATOR),true)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := fb_test.c
+LOCAL_MODULE = test-fb-simple
+LOCAL_MODULE_TAGS := tests
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_STATIC_LIBRARIES := libc
+include $(BUILD_EXECUTABLE)
+endif # sim
diff --git a/tests/framebuffer/fb_test.c b/tests/framebuffer/fb_test.c
new file mode 100644 (file)
index 0000000..6fdbf3b
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <linux/fb.h>
+#include <linux/kd.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "minui.h"
+
+typedef struct {
+    GGLSurface texture;
+    unsigned cwidth;
+    unsigned cheight;
+    unsigned ascent;
+} GRFont;
+
+static GGLContext *gr_context = 0;
+static GGLSurface gr_framebuffer[2];
+static unsigned gr_active_fb = 0;
+
+static int gr_fb_fd = -1;
+static int gr_vt_fd = -1;
+
+static struct fb_var_screeninfo vi;
+struct fb_fix_screeninfo fi;
+struct timespec tv, tv2;
+
+static void dumpinfo(struct fb_fix_screeninfo *fi,
+                     struct fb_var_screeninfo *vi);
+
+static int get_framebuffer(GGLSurface *fb)
+{
+    int fd;
+    void *bits;
+
+    fd = open("/dev/graphics/fb0", O_RDWR);
+    if(fd < 0) {
+        perror("cannot open fb0");
+        return -1;
+    }
+
+    if(ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
+        perror("failed to get fb0 info");
+        return -1;
+    }
+
+    if(ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
+        perror("failed to get fb0 info");
+        return -1;
+    }
+
+    dumpinfo(&fi, &vi);
+
+    bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    if(bits == MAP_FAILED) {
+        perror("failed to mmap framebuffer");
+        return -1;
+    }
+
+    fb->version = sizeof(*fb);
+    fb->width = vi.xres;
+    fb->height = vi.yres;
+    fb->stride = fi.line_length / (vi.bits_per_pixel >> 3);
+    fb->data = bits;
+    fb->format = GGL_PIXEL_FORMAT_RGB_565;
+
+    fb++;
+
+    fb->version = sizeof(*fb);
+    fb->width = vi.xres;
+    fb->height = vi.yres;
+    fb->stride = fi.line_length / (vi.bits_per_pixel >> 3);
+    fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2);
+    fb->format = GGL_PIXEL_FORMAT_RGB_565;
+
+    return fd;
+}
+
+static void set_active_framebuffer(unsigned n)
+{
+    if(n > 1) return;
+    vi.yres_virtual = vi.yres * 2;
+    vi.yoffset = n * vi.yres;
+    if(ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
+        fprintf(stderr,"active fb swap failed!\n");
+    }
+}
+
+static void dumpinfo(struct fb_fix_screeninfo *fi, struct fb_var_screeninfo *vi)
+{
+    fprintf(stderr,"vi.xres = %d\n", vi->xres);
+    fprintf(stderr,"vi.yres = %d\n", vi->yres);
+    fprintf(stderr,"vi.xresv = %d\n", vi->xres_virtual);
+    fprintf(stderr,"vi.yresv = %d\n", vi->yres_virtual);
+    fprintf(stderr,"vi.xoff = %d\n", vi->xoffset);
+    fprintf(stderr,"vi.yoff = %d\n", vi->yoffset);
+    fprintf(stderr, "vi.bits_per_pixel = %d\n", vi->bits_per_pixel);
+
+    fprintf(stderr, "fi.line_length = %d\n", fi->line_length);
+
+}
+
+int gr_init(void)
+{
+    int fd;
+
+
+    fd = open("/dev/tty0", O_RDWR | O_SYNC);
+    if(fd < 0) return -1;
+
+    if(ioctl(fd, KDSETMODE, (void*) KD_GRAPHICS)) {
+        close(fd);
+        return -1;
+    }
+
+    gr_fb_fd = get_framebuffer(gr_framebuffer);
+
+    if(gr_fb_fd < 0) {
+        ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+        close(fd);
+        return -1;
+    }
+
+    gr_vt_fd = fd;
+
+        /* start with 0 as front (displayed) and 1 as back (drawing) */
+    gr_active_fb = 0;
+    set_active_framebuffer(0);
+
+    return 0;
+}
+
+void gr_exit(void)
+{
+    close(gr_fb_fd);
+    gr_fb_fd = -1;
+
+    ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
+    close(gr_vt_fd);
+    gr_vt_fd = -1;
+}
+
+int gr_fb_width(void)
+{
+    return gr_framebuffer[0].width;
+}
+
+int gr_fb_height(void)
+{
+    return gr_framebuffer[0].height;
+}
+
+uint16_t red = 0xf800;
+uint16_t green = 0x07e0;
+uint16_t blue = 0x001f;
+
+void draw_grid(int w, int h, uint16_t* loc) {
+  int i, j;
+  int v;
+  int stride = fi.line_length / (vi.bits_per_pixel >> 3);
+
+  for (j = 0; j < h/2; j++) {
+    for (i = 0; i < w/2; i++)
+      loc[i + j*(stride)] = red;
+    for (; i < w; i++)
+      loc[i + j*(stride)] = green;
+  }
+  for (; j < h; j++) {
+    for (i = 0; i < w/2; i++)
+      loc[i + j*(stride)] = blue;
+    for (; i < w; i++)
+      loc[i + j*(stride)] = 0xffff;
+  }
+
+}
+
+void clear_screen(int w, int h, uint16_t* loc)
+{
+    int i,j;
+    int stride = fi.line_length / (vi.bits_per_pixel >> 3);
+
+  for (j = 0; j < h; j++)
+    for (i = 0; i < w; i++)
+      loc[i + j*(stride)] = 0x0000;
+}
+
+
+int main(int argc, char **argv) {
+  int w;
+  int h;
+  gr_init();
+  w = vi.xres;
+  h = vi.yres;
+  clear_screen(w, h, (uint16_t *)gr_framebuffer[0].data);
+
+  if (argc > 2) {
+    w = atoi(argv[1]);
+    h = atoi(argv[2]);
+  }
+
+  draw_grid(w, h, (uint16_t *)gr_framebuffer[0].data);
+  printf("%lld\n", (tv2.tv_sec*1000000000LL + tv2.tv_nsec) - (tv.tv_sec*1000000000LL + tv.tv_nsec));
+  set_active_framebuffer(1);
+  set_active_framebuffer(0);
+
+  return 0;
+}
diff --git a/tests/framebuffer/minui.h b/tests/framebuffer/minui.h
new file mode 100644 (file)
index 0000000..4efc971
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MINUI_H_
+#define _MINUI_H_
+
+int gr_init(void);
+void gr_exit(void);
+
+int gr_fb_width(void);
+int gr_fb_height(void);
+void gr_flip(void);
+
+void gr_color(unsigned char r, unsigned char g, unsigned char b);
+void gr_fill(int x, int y, int w, int h);
+int gr_text(int x, int y, const char *s);
+int gr_measure(const char *s);
+
+
+typedef struct event event;
+
+struct event
+{
+    unsigned type;
+    unsigned code;
+    unsigned value;
+};
+    
+int ev_init(void);
+void ev_exit(void);
+
+int ev_get(event *ev, unsigned dont_wait);
+
+#define TYPE_KEY 1
+
+#define KEY_UP      103
+#define KEY_DOWN    108
+#define KEY_LEFT    105
+#define KEY_RIGHT   106
+#define KEY_CENTER  232
+#define KEY_ENTER   28
+
+#endif
diff --git a/tests/framebuffer/refresh.c b/tests/framebuffer/refresh.c
new file mode 100644 (file)
index 0000000..43dc7cf
--- /dev/null
@@ -0,0 +1,169 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+
+#include <linux/fb.h>
+
+int64_t systemTime()
+{
+    struct timespec t;
+    t.tv_sec = t.tv_nsec = 0;
+    clock_gettime(CLOCK_MONOTONIC, &t);
+    return (int64_t)(t.tv_sec)*1000000000LL + t.tv_nsec;
+}
+
+int main(int argc, char** argv)
+{
+    char const * const device_template[] = {
+            "/dev/graphics/fb%u",
+            "/dev/fb%u",
+            0 };
+    int fd = -1;
+    int i=0;
+    int j=0;
+    char name[64];
+    while ((fd==-1) && device_template[i]) {
+        snprintf(name, 64, device_template[i], 0);
+        fd = open(name, O_RDWR, 0);
+        i++;
+    }
+    if (fd < 0)
+        return -errno;
+        
+    struct fb_fix_screeninfo finfo;
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+    
+    struct fb_var_screeninfo info;
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+    
+    info.reserved[0] = 0;
+    info.reserved[1] = 0;
+    info.reserved[2] = 0;
+    info.xoffset = 0;
+    info.yoffset = 0;
+    info.bits_per_pixel = 16;
+    info.activate = FB_ACTIVATE_NOW;
+    
+    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+        printf("FBIOPUT_VSCREENINFO failed (%d x %d)\n",
+                info.xres_virtual, info.yres_virtual);
+        return 0;
+    }
+        
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;    
+    
+    int refreshRate = 1000000000000000LLU / 
+            (
+          (uint64_t)( info.upper_margin + info.lower_margin + info.yres ) 
+                  * ( info.left_margin  + info.right_margin + info.xres )
+                  * info.pixclock
+            );
+    
+    float xdpi = (info.xres * 25.4f) / info.width; 
+    float ydpi = (info.yres * 25.4f) / info.height;
+    float fps  = refreshRate / 1000.0f; 
+    
+    printf( "using (fd=%d)\n"
+            "id           = %s\n"
+            "xres         = %d px\n"
+            "yres         = %d px\n"
+            "xres_virtual = %d px\n"
+            "yres_virtual = %d px\n"
+            "bpp          = %d\n"
+            "r            = %2u:%u\n"
+            "g            = %2u:%u\n"
+            "b            = %2u:%u\n",
+                fd,
+                finfo.id,
+                info.xres,
+                info.yres,
+                info.xres_virtual,
+                info.yres_virtual,
+                info.bits_per_pixel,
+                info.red.offset, info.red.length,
+                info.green.offset, info.green.length,
+                info.blue.offset, info.blue.length
+        );
+
+    printf( "width        = %d mm (%f dpi)\n"
+            "height       = %d mm (%f dpi)\n"
+            "refresh rate = %.2f Hz\n",
+                info.width,  xdpi,
+                info.height, ydpi,
+                fps
+        );
+    
+    printf("upper_margin=%d, lower_margin=%d, left_margin=%d, right_margin=%d, pixclock=%d, finfo.smem_len=%d\n",
+            info.upper_margin, info.lower_margin, info.left_margin, info.right_margin, info.pixclock, finfo.smem_len);
+
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+    
+    if (finfo.smem_len <= 0)
+        return -errno;
+    
+    /*
+     * Open and map the display.
+     */
+    
+    uint16_t* buffer  = (uint16_t*) mmap(
+            0, finfo.smem_len,
+            PROT_READ | PROT_WRITE,
+            MAP_SHARED,
+            fd, 0);
+    
+    if (buffer == MAP_FAILED)
+        return -errno;
+    
+    // at least for now, always clear the fb
+    memset(buffer, 0, finfo.smem_len);
+    memset(buffer, 0xff, 320*(info.yres_virtual/2)*2);
+
+    int l,t,w,h;
+    l=0;
+    t=0;
+    w=320;
+    h=480;
+    info.reserved[0] = 0x54445055; // "UPDT";
+    info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
+    info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
+
+    int err;
+    int c = 0;
+    int64_t time = systemTime();
+    while (1) {
+        
+        info.activate = FB_ACTIVATE_VBL;
+        info.yoffset = 0;
+        ioctl(fd, FBIOPUT_VSCREENINFO, &info);
+
+        info.activate = FB_ACTIVATE_VBL;
+        info.yoffset = info.yres_virtual/2;
+        err = ioctl(fd, FBIOPUT_VSCREENINFO, &info);
+
+        c+=2;
+        if (c==60*2) {
+            int64_t now = systemTime();
+            time = now - time;
+            printf("refresh rate = %f Hz\n", (c*1000000000.0 / (double)time));
+            c = 0;
+            time = now;
+        }
+    }
+    return 0;
+}
index 460f2e4..fe253d7 100644 (file)
 /data/anr/... 000 662 root system log log
 /data/app/ 771 771 system system system system
 /data/app/... 644 664 system system system system
-/data/dalvik-cache/ 750 751 root root root root
+/data/app-private/ 700 771 system system system system
+/data/dalvik-cache/ 750 771 root system root system
 /data/dalvik-cache/... 400 744 root 19999 root 19999
 /data/data 701 771 system system system system
 /data/data/... 000 775 system 19999 system 19999
-/data/testinfo/ 770 771 root system root system
-/data/testinfo/* 000 664 root system root system
-/data/tombstones/ 755 755 system system system system
-/data/tombstones/* 000 600 system 19999 system 19999
+/data/local/ 771 771 shell shell shell shell
+/data/local/tmp/ 771 1771 shell shell shell shell
 /data/lost+found/ 700 770 root root root root
 /data/misc/ 1711 1771 root system root misc
 /data/misc/akmd_set.txt 600 640 root compass compass compass
 /data/misc/rild* 600 660 root radio root radio
-/data/misc/hcid/ 770 770 bluetooth bluetooth bluetooth bluetooth
+/data/misc/dhcp/ 700 770 root dhcp dhcp dhcp
+/data/misc/dhcp/... 000 660 root dhcp dhcp dhcp
+/data/misc/hcid/ 700 770 root bluetooth bluetooth bluetooth
+/data/misc/hcid/... 600 770 root bluetooth bluetooth bluetooth
 /data/misc/wifi/ 000 1771 system wifi system wifi
 /data/misc/wifi/... 000 770 root wifi root wifi
-/data/local/ 771 771 shell shell shell shell
-/data/local/tmp/ 771 1771 shell shell shell shell
-/data/app_private/ 700 771 system system system system
-/data/system/... 000 770 system system system system
-/dev/ 1777 1777 root root root root
-/dev/alarm 660 660 root system root system
+/data/property/ 700 770 root root root root
+/data/property/... 600 660 root root root root
+/data/system/ 000 775 system system system system
+/data/system/... 000 774 system system system system
+/data/testinfo/ 770 771 root system root system
+/data/testinfo/* 000 664 root system root system
+/data/tombstones/ 755 755 system system system system
+/data/tombstones/* 000 600 system 19999 system 19999
+/dev/ 755 755 root root root root
+/dev/alarm 600 664 root radio root radio
 /dev/ashmem 666 666 root root root root
-/dev/android_adb 600 600 root root root root
+/dev/android_adb 600 660 root adb root adb
+/dev/android_adb_enable 600 660 root adb root adb
 /dev/android_ums 640 640 mount mount mount mount
 /dev/binder 666 666 root root root root
 /dev/console 600 600 root root root root
 /dev/cpu_dma_latency 600 660 root system root system
 /dev/mem 600 600 root root root root
 /dev/msm_mp3 600 660 root system root audio
+/dev/msm_pcm_ctl 660 660 system system audio audio
 /dev/msm_pcm_in 660 660 system system audio audio
 /dev/msm_pcm_out 660 660 system system audio audio
 /dev/msm_perf 600 600 root root root root
 /dev/null 666 666 root root root root
-/dev/pmem_adsp 660 660 system system audio audio
 /dev/pmem 660 660 system system graphics graphics
+/dev/pmem_adsp 660 660 system system audio audio
+/dev/pmem_camera 600 660 root system root camera
 /dev/ppp 600 600 root root root root
 /dev/psaux 600 600 root root root root
 /dev/ptmx 666 666 root root root root
 /dev/oncrpc/ 755 755 root root root root
 /dev/oncrpc/... 000 660 root camera root camera
 /dev/pts/ 755 755 root root root root
-/dev/pts/* 600 600 root system root system
+/dev/pts/* 600 600 root shell root shell
 /dev/mtd/ 750 775 root root root root
+/dev/mtd/mtd0 460 460 radio radio diag diag
 /dev/mtd/* 600 600 root root root root
 /dev/socket/ 750 755 root system root system
+/dev/socket/bluetooth 600 660 root bluetooth bluetooth bluetooth
 /dev/socket/dbus 660 660 root bluetooth bluetooth bluetooth
+/dev/socket/dbus_bluetooth 600 660 root bluetooth bluetooth bluetooth
 /dev/socket/installd 600 660 system system system system
 /dev/socket/mountd 660 660 root mount root mount
 /dev/socket/property_service 666 666 root system root system
-/dev/socket/rild 660 660 root radio radio radio
+/dev/socket/rild 660 660 root radio root radio
+/dev/socket/rild-debug 660 660 root radio root radio
 /dev/socket/usbd 660 660 root mount mount mount
+/dev/socket/wpa_* 600 660 root wifi wifi wifi
 /dev/socket/zygote 666 666 root root root root
 /etc 777 777 root root root root
 /proc/ 555 555 root root root root
 /system/* 000 664 root system root system
 /system/app/ 755 755 root root root root
 /system/app/... 600 644 root root root root
-/system/bin/... 000 755 root system root system
-/system/xbin/... 000 755 root system root system
+/system/bin/... 000 755 root shell root shell
+/system/bin/netcfg 000 2750 root root inet inet
+/system/bin/ping 000 2755 root root net_raw net_raw
 /system/etc/ 755 755 root root root root
-/system/etc/... 000 664 root system root audio
+/system/etc/... 000 664 root bluetooth root audio
 /system/etc/firmware/ 700 755 root root root root
-/system/etc/init.goldfish.sh 500 550 root root root root
-/system/etc/init.gprs-pppd 500 550 root root root root
+/system/etc/init.goldfish.sh 500 550 root root root shell
+/system/etc/init.gprs-pppd 500 550 root root root shell
 /system/etc/init.testmenu 500 550 root root root root
-/system/etc/perm_checker.conf 000 777 root system root system
+/system/etc/perm_checker.conf 000 777 root shell root shell
 /system/etc/ppp/ 755 775 root system root system
 /system/etc/ppp/chap-secrets 600 660 root system root system
 /system/etc/ppp/ip-down 500 550 root system root system
 /system/sounds/ 755 755 root root root root
 /system/sounds/... 644 644 root root root root
 /system/usr/... 400 755 root root root root
-/sqlite_stmt_journals 1777 1777 root root root root
+/sqlite_stmt_journals/ 1777 1777 root root root root