Merge "Change setsebool syntax to be consistent with other init built-ins."
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index d9aa09c..b53bc44 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -117,7 +117,34 @@
or even any one of the local services described below.
+<host-prefix>:forward:norebind:<local>;<remote>
+ Same as <host-prefix>:forward:<local>;<remote> except that it will
+ fail it there is already a forward connection from <local>.
+ Used to implement 'adb forward --no-rebind <local> <remote>'
+
+<host-prefix>:killforward:<local>
+ Remove any existing forward local connection from <local>.
+ This is used to implement 'adb forward --remove <local>'
+
+<host-prefix>:killforward-all
+ Remove all forward network connections.
+ This is used to implement 'adb forward --remove-all'.
+
+<host-prefix>:list-forward
+ List all existing forward connections from this server.
+ This returns something that looks like the following:
+
+ <hex4>: The length of the payload, as 4 hexadecimal chars.
+ <payload>: A series of lines of the following format:
+
+ <serial> " " <local> " " <remote> "\n"
+
+ Where <serial> is a device serial number.
+ <local> is the host-specific endpoint (e.g. tcp:9000).
+ <remote> is the device-specific endpoint.
+
+ Used to implement 'adb forward --list'.
LOCAL SERVICES:
diff --git a/adb/adb.c b/adb/adb.c
index 07bfbe5..b3283de 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -722,24 +722,90 @@
return -1;
}
-static int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
+// Write a single line describing a listener to a user-provided buffer.
+// Appends a trailing zero, even in case of truncation, but the function
+// returns the full line length.
+// If |buffer| is NULL, does not write but returns required size.
+static int format_listener(alistener* l, char* buffer, size_t buffer_len) {
+ // Format is simply:
+ //
+ // <device-serial> " " <local-name> " " <remote-name> "\n"
+ //
+ int local_len = strlen(l->local_name);
+ int connect_len = strlen(l->connect_to);
+ int serial_len = strlen(l->transport->serial);
+
+ if (buffer != NULL) {
+ snprintf(buffer, buffer_len, "%s %s %s\n",
+ l->transport->serial, l->local_name, l->connect_to);
+ }
+ // NOTE: snprintf() on Windows returns -1 in case of truncation, so
+ // return the computed line length instead.
+ return local_len + connect_len + serial_len + 3;
+}
+
+// Write the list of current listeners (network redirections) into a
+// user-provided buffer. Appends a trailing zero, even in case of
+// trunctaion, but return the full size in bytes.
+// If |buffer| is NULL, does not write but returns required size.
+static int format_listeners(char* buf, size_t buflen)
+{
+ alistener* l;
+ int result = 0;
+ for (l = listener_list.next; l != &listener_list; l = l->next) {
+ // Ignore special listeners like those for *smartsocket*
+ if (l->connect_to[0] == '*')
+ continue;
+ int len = format_listener(l, buf, buflen);
+ // Ensure there is space for the trailing zero.
+ result += len;
+ if (buf != NULL) {
+ buf += len;
+ buflen -= len;
+ if (buflen <= 0)
+ break;
+ }
+ }
+ return result;
+}
+
+static int remove_listener(const char *local_name, atransport* transport)
{
alistener *l;
for (l = listener_list.next; l != &listener_list; l = l->next) {
- if (!strcmp(local_name, l->local_name) &&
- !strcmp(connect_to, l->connect_to) &&
- l->transport && l->transport == transport) {
-
- listener_disconnect(l, transport);
+ if (!strcmp(local_name, l->local_name)) {
+ listener_disconnect(l, l->transport);
return 0;
}
}
-
return -1;
}
-static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
+static void remove_all_listeners(void)
+{
+ alistener *l, *l_next;
+ for (l = listener_list.next; l != &listener_list; l = l_next) {
+ l_next = l->next;
+ // Never remove smart sockets.
+ if (l->connect_to[0] == '*')
+ continue;
+ listener_disconnect(l, l->transport);
+ }
+}
+
+// error/status codes for install_listener.
+typedef enum {
+ INSTALL_STATUS_OK = 0,
+ INSTALL_STATUS_INTERNAL_ERROR = -1,
+ INSTALL_STATUS_CANNOT_BIND = -2,
+ INSTALL_STATUS_CANNOT_REBIND = -3,
+} install_status_t;
+
+static install_status_t install_listener(const char *local_name,
+ const char *connect_to,
+ atransport* transport,
+ int no_rebind)
{
alistener *l;
@@ -751,12 +817,17 @@
/* can't repurpose a smartsocket */
if(l->connect_to[0] == '*') {
- return -1;
+ return INSTALL_STATUS_INTERNAL_ERROR;
+ }
+
+ /* can't repurpose a listener if 'no_rebind' is true */
+ if (no_rebind) {
+ return INSTALL_STATUS_CANNOT_REBIND;
}
cto = strdup(connect_to);
if(cto == 0) {
- return -1;
+ return INSTALL_STATUS_INTERNAL_ERROR;
}
//printf("rebinding '%s' to '%s'\n", local_name, connect_to);
@@ -767,7 +838,7 @@
l->transport = transport;
add_transport_disconnect(l->transport, &l->disconnect);
}
- return 0;
+ return INSTALL_STATUS_OK;
}
}
@@ -804,11 +875,11 @@
l->disconnect.func = listener_disconnect;
add_transport_disconnect(transport, &l->disconnect);
}
- return 0;
+ return INSTALL_STATUS_OK;
nomem:
fatal("cannot allocate listener");
- return 0;
+ return INSTALL_STATUS_INTERNAL_ERROR;
}
#ifdef HAVE_WIN32_PROC
@@ -1113,7 +1184,7 @@
char local_name[30];
build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL)) {
+ if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
exit(1);
}
#else
@@ -1180,7 +1251,7 @@
} else {
char local_name[30];
build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL)) {
+ if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
exit(1);
}
}
@@ -1474,24 +1545,63 @@
}
#endif // ADB_HOST
- if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
+ if(!strcmp(service,"list-forward")) {
+ // Create the list of forward redirections.
+ char header[9];
+ int buffer_size = format_listeners(NULL, 0);
+ // Add one byte for the trailing zero.
+ char* buffer = malloc(buffer_size+1);
+ (void) format_listeners(buffer, buffer_size+1);
+ snprintf(header, sizeof header, "OKAY%04x", buffer_size);
+ writex(reply_fd, header, 8);
+ writex(reply_fd, buffer, buffer_size);
+ free(buffer);
+ return 0;
+ }
+
+ if (!strcmp(service,"killforward-all")) {
+ remove_all_listeners();
+ adb_write(reply_fd, "OKAYOKAY", 8);
+ return 0;
+ }
+
+ if(!strncmp(service,"forward:",8) ||
+ !strncmp(service,"killforward:",12)) {
char *local, *remote, *err;
int r;
atransport *transport;
int createForward = strncmp(service,"kill",4);
+ int no_rebind = 0;
- local = service + (createForward ? 8 : 12);
- remote = strchr(local,';');
- if(remote == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
- return 0;
+ local = strchr(service, ':') + 1;
+
+ // Handle forward:norebind:<local>... here
+ if (createForward && !strncmp(local, "norebind:", 9)) {
+ no_rebind = 1;
+ local = strchr(local, ':') + 1;
}
- *remote++ = 0;
- if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
- sendfailmsg(reply_fd, "malformed forward spec");
- return 0;
+ remote = strchr(local,';');
+
+ if (createForward) {
+ // Check forward: parameter format: '<local>;<remote>'
+ if(remote == 0) {
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 0;
+ }
+
+ *remote++ = 0;
+ if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 0;
+ }
+ } else {
+ // Check killforward: parameter format: '<local>'
+ if (local[0] == 0) {
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 0;
+ }
}
transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
@@ -1501,9 +1611,9 @@
}
if (createForward) {
- r = install_listener(local, remote, transport);
+ r = install_listener(local, remote, transport, no_rebind);
} else {
- r = remove_listener(local, remote, transport);
+ r = remove_listener(local, transport);
}
if(r == 0) {
/* 1st OKAY is connect, 2nd OKAY is status */
@@ -1512,7 +1622,18 @@
}
if (createForward) {
- sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
+ const char* message;
+ switch (r) {
+ case INSTALL_STATUS_CANNOT_BIND:
+ message = "cannot bind to socket";
+ break;
+ case INSTALL_STATUS_CANNOT_REBIND:
+ message = "cannot rebind existing socket";
+ break;
+ default:
+ message = "internal error";
+ }
+ sendfailmsg(reply_fd, message);
} else {
sendfailmsg(reply_fd, "cannot remove listener");
}
diff --git a/adb/commandline.c b/adb/commandline.c
index 24cbb5a..a4c2f40 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -112,6 +112,9 @@
" adb shell <command> - run remote shell command\n"
" adb emu <command> - run emulator console command\n"
" adb logcat [ <filter-spec> ] - View device log\n"
+ " adb forward --list - list all forward socket connections.\n"
+ " the format is a list of lines with the following format:\n"
+ " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
" adb forward <local> <remote> - forward socket connections\n"
" forward specs are one of: \n"
" tcp:<port>\n"
@@ -120,6 +123,11 @@
" localfilesystem:<unix domain socket name>\n"
" dev:<character device name>\n"
" jdwp:<process pid> (remote only)\n"
+ " adb forward --no-rebind <local> <remote>\n"
+ " - same as 'adb forward <local> <remote>' but fails\n"
+ " if <local> is already forwarded\n"
+ " adb forward --remove <local> - remove a specific forward socket connection\n"
+ " adb forward --remove-all - remove all forward socket connections\n"
" adb jdwp - list PIDs of processes hosting a JDWP transport\n"
" adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n"
" - push this package file to the device and install it\n"
@@ -1223,16 +1231,85 @@
}
if(!strcmp(argv[0], "forward")) {
- if(argc != 3) return usage();
- if (serial) {
- snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
- } else if (ttype == kTransportUsb) {
- snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
- } else if (ttype == kTransportLocal) {
- snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
- } else {
- snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
+ char host_prefix[64];
+ char remove = 0;
+ char remove_all = 0;
+ char list = 0;
+ char no_rebind = 0;
+
+ // Parse options here.
+ while (argc > 1 && argv[1][0] == '-') {
+ if (!strcmp(argv[1], "--list"))
+ list = 1;
+ else if (!strcmp(argv[1], "--remove"))
+ remove = 1;
+ else if (!strcmp(argv[1], "--remove-all"))
+ remove_all = 1;
+ else if (!strcmp(argv[1], "--no-rebind"))
+ no_rebind = 1;
+ else {
+ return usage();
+ }
+ argc--;
+ argv++;
}
+
+ // Ensure we can only use one option at a time.
+ if (list + remove + remove_all + no_rebind > 1) {
+ return usage();
+ }
+
+ // Determine the <host-prefix> for this command.
+ if (serial) {
+ snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
+ serial);
+ } else if (ttype == kTransportUsb) {
+ snprintf(host_prefix, sizeof host_prefix, "host-usb");
+ } else if (ttype == kTransportLocal) {
+ snprintf(host_prefix, sizeof host_prefix, "host-local");
+ } else {
+ snprintf(host_prefix, sizeof host_prefix, "host");
+ }
+
+ // Implement forward --list
+ if (list) {
+ if (argc != 1)
+ return usage();
+ snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);
+ char* forwards = adb_query(buf);
+ if (forwards == NULL) {
+ fprintf(stderr, "error: %s\n", adb_error());
+ return 1;
+ }
+ printf("%s", forwards);
+ free(forwards);
+ return 0;
+ }
+
+ // Implement forward --remove-all
+ else if (remove_all) {
+ if (argc != 1)
+ return usage();
+ snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);
+ }
+
+ // Implement forward --remove <local>
+ else if (remove) {
+ if (argc != 2)
+ return usage();
+ snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);
+ }
+ // Or implement one of:
+ // forward <local> <remote>
+ // forward --no-rebind <local> <remote>
+ else
+ {
+ if (argc != 3)
+ return usage();
+ const char* command = no_rebind ? "forward:norebind:" : "forward";
+ snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
+ }
+
if(adb_command(buf)) {
fprintf(stderr,"error: %s\n", adb_error());
return 1;
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index 00652e9..74eaa49 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -20,6 +20,7 @@
void crash1(void);
void crashnostack(void);
void maybeabort(void);
+int do_action(const char* arg);
static void debuggerd_connect()
{
@@ -74,24 +75,46 @@
return 0;
}
-int main(int argc, char **argv)
+static void* thread_callback(void* raw_arg)
{
+ return (void*) do_action((const char*) raw_arg);
+}
+
+int do_action_on_thread(const char* arg)
+{
+ pthread_t t;
+ pthread_create(&t, NULL, thread_callback, (void*) arg);
+ void* result = NULL;
+ pthread_join(t, &result);
+ return (int) result;
+}
+
+int do_action(const char* arg)
+{
+ if(!strncmp(arg, "thread-", strlen("thread-"))) {
+ return do_action_on_thread(arg + strlen("thread-"));
+ }
+
+ if(!strcmp(arg,"nostack")) crashnostack();
+ if(!strcmp(arg,"ctest")) return ctest();
+ if(!strcmp(arg,"exit")) exit(1);
+ if(!strcmp(arg,"abort")) maybeabort();
+
pthread_t thr;
pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&thr, &attr, test_thread, 0);
+ while(1) sleep(1);
+}
- fprintf(stderr,"crasher: " __TIME__ "!@\n");
+int main(int argc, char **argv)
+{
+ fprintf(stderr,"crasher: built at " __TIME__ "!@\n");
fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid());
if(argc > 1) {
- if(!strcmp(argv[1],"nostack")) crashnostack();
- if(!strcmp(argv[1],"ctest")) return ctest();
- if(!strcmp(argv[1],"exit")) exit(1);
- if(!strcmp(argv[1],"abort")) maybeabort();
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_create(&thr, &attr, test_thread, 0);
- while(1) sleep(1);
+ return do_action(argv[1]);
} else {
crash1();
// *((int*) 0) = 42;
diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.c
index 5f2db43..98016c3 100644
--- a/debuggerd/tombstone.c
+++ b/debuggerd/tombstone.c
@@ -84,6 +84,7 @@
static const char *get_sigcode(int signo, int code)
{
+ // Try the signal-specific codes...
switch (signo) {
case SIGILL:
switch (code) {
@@ -122,7 +123,31 @@
case SEGV_ACCERR: return "SEGV_ACCERR";
}
break;
+ case SIGTRAP:
+ switch (code) {
+ case TRAP_BRKPT: return "TRAP_BRKPT";
+ case TRAP_TRACE: return "TRAP_TRACE";
+ }
+ break;
}
+ // Then the other codes...
+ switch (code) {
+ case SI_USER: return "SI_USER";
+#if defined(SI_KERNEL)
+ case SI_KERNEL: return "SI_KERNEL";
+#endif
+ case SI_QUEUE: return "SI_QUEUE";
+ case SI_TIMER: return "SI_TIMER";
+ case SI_MESGQ: return "SI_MESGQ";
+ case SI_ASYNCIO: return "SI_ASYNCIO";
+#if defined(SI_SIGIO)
+ case SI_SIGIO: return "SI_SIGIO";
+#endif
+#if defined(SI_TKILL)
+ case SI_TKILL: return "SI_TKILL";
+#endif
+ }
+ // Then give up...
return "?";
}
diff --git a/include/cutils/atomic-arm.h b/include/cutils/atomic-arm.h
index 16fe512..795afd3 100644
--- a/include/cutils/atomic-arm.h
+++ b/include/cutils/atomic-arm.h
@@ -20,72 +20,78 @@
#include <stdint.h>
#include <machine/cpu-features.h>
-extern inline void android_compiler_barrier(void)
+#ifndef ANDROID_ATOMIC_INLINE
+#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline))
+#endif
+
+extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void)
{
__asm__ __volatile__ ("" : : : "memory");
}
#if ANDROID_SMP == 0
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
android_compiler_barrier();
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_compiler_barrier();
}
#elif defined(__ARM_HAVE_DMB)
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
__asm__ __volatile__ ("dmb" : : : "memory");
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
__asm__ __volatile__ ("dmb st" : : : "memory");
}
#elif defined(__ARM_HAVE_LDREX_STREX)
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_memory_barrier();
}
#else
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
typedef void (kuser_memory_barrier)(void);
(*(kuser_memory_barrier *)0xffff0fa0)();
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_memory_barrier();
}
#endif
-extern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
{
int32_t value = *ptr;
android_memory_barrier();
return value;
}
-extern inline int32_t android_atomic_release_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int32_t android_atomic_release_load(volatile const int32_t *ptr)
{
android_memory_barrier();
return *ptr;
}
-extern inline void android_atomic_acquire_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
{
*ptr = value;
android_memory_barrier();
}
-extern inline void android_atomic_release_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_release_store(int32_t value, volatile int32_t *ptr)
{
android_memory_barrier();
*ptr = value;
@@ -95,8 +101,8 @@
extern int android_atomic_cas(int32_t old_value, int32_t new_value,
volatile int32_t *ptr);
#elif defined(__ARM_HAVE_LDREX_STREX)
-extern inline int android_atomic_cas(int32_t old_value, int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
{
int32_t prev, status;
do {
@@ -111,8 +117,8 @@
return prev != old_value;
}
#else
-extern inline int android_atomic_cas(int32_t old_value, int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
{
typedef int (kuser_cmpxchg)(int32_t, int32_t, volatile int32_t *);
int32_t prev, status;
@@ -127,18 +133,20 @@
}
#endif
-extern inline int android_atomic_acquire_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_acquire_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
int status = android_atomic_cas(old_value, new_value, ptr);
android_memory_barrier();
return status;
}
-extern inline int android_atomic_release_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_release_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
android_memory_barrier();
return android_atomic_cas(old_value, new_value, ptr);
@@ -149,8 +157,8 @@
extern int32_t android_atomic_add(int32_t increment,
volatile int32_t *ptr);
#elif defined(__ARM_HAVE_LDREX_STREX)
-extern inline int32_t android_atomic_add(int32_t increment,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_add(int32_t increment, volatile int32_t *ptr)
{
int32_t prev, tmp, status;
android_memory_barrier();
@@ -166,8 +174,8 @@
return prev;
}
#else
-extern inline int32_t android_atomic_add(int32_t increment,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_add(int32_t increment, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
@@ -179,12 +187,12 @@
}
#endif
-extern inline int32_t android_atomic_inc(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t android_atomic_inc(volatile int32_t *addr)
{
return android_atomic_add(1, addr);
}
-extern inline int32_t android_atomic_dec(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t android_atomic_dec(volatile int32_t *addr)
{
return android_atomic_add(-1, addr);
}
@@ -192,7 +200,8 @@
#if defined(__thumb__)
extern int32_t android_atomic_and(int32_t value, volatile int32_t *ptr);
#elif defined(__ARM_HAVE_LDREX_STREX)
-extern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_and(int32_t value, volatile int32_t *ptr)
{
int32_t prev, tmp, status;
android_memory_barrier();
@@ -208,7 +217,8 @@
return prev;
}
#else
-extern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_and(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
@@ -223,7 +233,8 @@
#if defined(__thumb__)
extern int32_t android_atomic_or(int32_t value, volatile int32_t *ptr);
#elif defined(__ARM_HAVE_LDREX_STREX)
-extern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_or(int32_t value, volatile int32_t *ptr)
{
int32_t prev, tmp, status;
android_memory_barrier();
@@ -239,7 +250,8 @@
return prev;
}
#else
-extern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_or(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
diff --git a/include/cutils/atomic-mips.h b/include/cutils/atomic-mips.h
index 49144a3..f9d3e25 100644
--- a/include/cutils/atomic-mips.h
+++ b/include/cutils/atomic-mips.h
@@ -19,60 +19,66 @@
#include <stdint.h>
-extern inline void android_compiler_barrier(void)
+#ifndef ANDROID_ATOMIC_INLINE
+#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline))
+#endif
+
+extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void)
{
__asm__ __volatile__ ("" : : : "memory");
}
#if ANDROID_SMP == 0
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
android_compiler_barrier();
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_compiler_barrier();
}
#else
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
__asm__ __volatile__ ("sync" : : : "memory");
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
__asm__ __volatile__ ("sync" : : : "memory");
}
#endif
-extern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_acquire_load(volatile const int32_t *ptr)
{
int32_t value = *ptr;
android_memory_barrier();
return value;
}
-extern inline int32_t android_atomic_release_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_release_load(volatile const int32_t *ptr)
{
android_memory_barrier();
return *ptr;
}
-extern inline void android_atomic_acquire_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
{
*ptr = value;
android_memory_barrier();
}
-extern inline void android_atomic_release_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_release_store(int32_t value, volatile int32_t *ptr)
{
android_memory_barrier();
*ptr = value;
}
-extern inline int android_atomic_cas(int32_t old_value, int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
{
int32_t prev, status;
do {
@@ -90,26 +96,28 @@
return prev != old_value;
}
-extern inline int android_atomic_acquire_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_acquire_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
int status = android_atomic_cas(old_value, new_value, ptr);
android_memory_barrier();
return status;
}
-extern inline int android_atomic_release_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_release_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
android_memory_barrier();
return android_atomic_cas(old_value, new_value, ptr);
}
-extern inline int32_t android_atomic_swap(int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_swap(int32_t new_value, volatile int32_t *ptr)
{
int32_t prev, status;
do {
@@ -125,8 +133,8 @@
return prev;
}
-extern inline int32_t android_atomic_add(int32_t increment,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_add(int32_t increment, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
@@ -142,17 +150,20 @@
return prev;
}
-extern inline int32_t android_atomic_inc(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_inc(volatile int32_t *addr)
{
return android_atomic_add(1, addr);
}
-extern inline int32_t android_atomic_dec(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_dec(volatile int32_t *addr)
{
return android_atomic_add(-1, addr);
}
-extern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_and(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
@@ -168,7 +179,8 @@
return prev;
}
-extern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_or(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
android_memory_barrier();
diff --git a/include/cutils/atomic-x86.h b/include/cutils/atomic-x86.h
index 438012e..9480f57 100644
--- a/include/cutils/atomic-x86.h
+++ b/include/cutils/atomic-x86.h
@@ -19,60 +19,66 @@
#include <stdint.h>
-extern inline void android_compiler_barrier(void)
+#ifndef ANDROID_ATOMIC_INLINE
+#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline))
+#endif
+
+extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void)
{
__asm__ __volatile__ ("" : : : "memory");
}
#if ANDROID_SMP == 0
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
android_compiler_barrier();
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_compiler_barrier();
}
#else
-extern inline void android_memory_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
{
__asm__ __volatile__ ("mfence" : : : "memory");
}
-extern inline void android_memory_store_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
{
android_compiler_barrier();
}
#endif
-extern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_acquire_load(volatile const int32_t *ptr)
{
int32_t value = *ptr;
android_compiler_barrier();
return value;
}
-extern inline int32_t android_atomic_release_load(volatile const int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_release_load(volatile const int32_t *ptr)
{
android_memory_barrier();
return *ptr;
}
-extern inline void android_atomic_acquire_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
{
*ptr = value;
android_memory_barrier();
}
-extern inline void android_atomic_release_store(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE void
+android_atomic_release_store(int32_t value, volatile int32_t *ptr)
{
android_compiler_barrier();
*ptr = value;
}
-extern inline int android_atomic_cas(int32_t old_value, int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
{
int32_t prev;
__asm__ __volatile__ ("lock; cmpxchgl %1, %2"
@@ -82,24 +88,26 @@
return prev != old_value;
}
-extern inline int android_atomic_acquire_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_acquire_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
/* Loads are not reordered with other loads. */
return android_atomic_cas(old_value, new_value, ptr);
}
-extern inline int android_atomic_release_cas(int32_t old_value,
- int32_t new_value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int
+android_atomic_release_cas(int32_t old_value,
+ int32_t new_value,
+ volatile int32_t *ptr)
{
/* Stores are not reordered with other stores. */
return android_atomic_cas(old_value, new_value, ptr);
}
-extern inline int32_t android_atomic_add(int32_t increment,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_add(int32_t increment, volatile int32_t *ptr)
{
__asm__ __volatile__ ("lock; xaddl %0, %1"
: "+r" (increment), "+m" (*ptr)
@@ -108,18 +116,20 @@
return increment;
}
-extern inline int32_t android_atomic_inc(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_inc(volatile int32_t *addr)
{
return android_atomic_add(1, addr);
}
-extern inline int32_t android_atomic_dec(volatile int32_t *addr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_dec(volatile int32_t *addr)
{
return android_atomic_add(-1, addr);
}
-extern inline int32_t android_atomic_and(int32_t value,
- volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_and(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
do {
@@ -129,7 +139,8 @@
return prev;
}
-extern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE int32_t
+android_atomic_or(int32_t value, volatile int32_t *ptr)
{
int32_t prev, status;
do {
diff --git a/include/cutils/log.h b/include/cutils/log.h
index 878952e..8b045c7 100644
--- a/include/cutils/log.h
+++ b/include/cutils/log.h
@@ -279,7 +279,88 @@
: (void)0 )
#endif
-
+// ---------------------------------------------------------------------
+
+/*
+ * Simplified macro to send a verbose radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGV
+#if LOG_NDEBUG
+#define RLOGV(...) ((void)0)
+#else
+#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#endif
+#endif
+
+#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
+
+#ifndef RLOGV_IF
+#if LOG_NDEBUG
+#define RLOGV_IF(cond, ...) ((void)0)
+#else
+#define RLOGV_IF(cond, ...) \
+ ( (CONDITION(cond)) \
+ ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
+ : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGD
+#define RLOGD(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGD_IF
+#define RLOGD_IF(cond, ...) \
+ ( (CONDITION(cond)) \
+ ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
+ : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGI
+#define RLOGI(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGI_IF
+#define RLOGI_IF(cond, ...) \
+ ( (CONDITION(cond)) \
+ ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
+ : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGW
+#define RLOGW(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGW_IF
+#define RLOGW_IF(cond, ...) \
+ ( (CONDITION(cond)) \
+ ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+ : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGE
+#define RLOGE(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGE_IF
+#define RLOGE_IF(cond, ...) \
+ ( (CONDITION(cond)) \
+ ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
+ : (void)0 )
+#endif
+
// ---------------------------------------------------------------------
diff --git a/include/sysutils/FrameworkListener.h b/include/sysutils/FrameworkListener.h
index 756bacf..f1a4b43 100644
--- a/include/sysutils/FrameworkListener.h
+++ b/include/sysutils/FrameworkListener.h
@@ -23,10 +23,11 @@
class FrameworkListener : public SocketListener {
public:
- static const int CMD_ARGS_MAX = 16;
+ static const int CMD_ARGS_MAX = 26;
/* 1 out of errorRate will be dropped */
int errorRate;
+
private:
int mCommandCount;
bool mWithSeq;
diff --git a/include/usbhost/usbhost.h b/include/usbhost/usbhost.h
index 9a6b59c..1d67c12 100644
--- a/include/usbhost/usbhost.h
+++ b/include/usbhost/usbhost.h
@@ -72,6 +72,19 @@
/* Call this to cleanup the USB host library. */
void usb_host_cleanup(struct usb_host_context *context);
+/* Call this to get the inotify file descriptor. */
+int usb_host_get_fd(struct usb_host_context *context);
+
+/* Call this to initialize the usb host context. */
+int usb_host_load(struct usb_host_context *context,
+ usb_device_added_cb added_cb,
+ usb_device_removed_cb removed_cb,
+ usb_discovery_done_cb discovery_done_cb,
+ void *client_data);
+
+/* Call this to read and handle occuring usb event. */
+int usb_host_read_event(struct usb_host_context *context);
+
/* Call this to monitor the USB bus for new and removed devices.
* This is intended to be called from a dedicated thread,
* as it will not return until one of the callbacks returns true.
diff --git a/libcorkscrew/arch-arm/ptrace-arm.c b/libcorkscrew/arch-arm/ptrace-arm.c
index 868230c..78a9ea9 100644
--- a/libcorkscrew/arch-arm/ptrace-arm.c
+++ b/libcorkscrew/arch-arm/ptrace-arm.c
@@ -29,12 +29,15 @@
static void load_exidx_header(pid_t pid, map_info_t* mi,
uintptr_t* out_exidx_start, size_t* out_exidx_size) {
uint32_t elf_phoff;
- uint32_t elf_phentsize_phnum;
+ uint32_t elf_phentsize_ehsize;
+ uint32_t elf_shentsize_phnum;
if (try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff)
+ && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_ehsize),
+ &elf_phentsize_ehsize)
&& try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum),
- &elf_phentsize_phnum)) {
- uint32_t elf_phentsize = elf_phentsize_phnum >> 16;
- uint32_t elf_phnum = elf_phentsize_phnum & 0xffff;
+ &elf_shentsize_phnum)) {
+ uint32_t elf_phentsize = elf_phentsize_ehsize >> 16;
+ uint32_t elf_phnum = elf_shentsize_phnum & 0xffff;
for (uint32_t i = 0; i < elf_phnum; i++) {
uintptr_t elf_phdr = mi->start + elf_phoff + i * elf_phentsize;
uint32_t elf_phdr_type;
diff --git a/libcutils/atomic.c b/libcutils/atomic.c
index f6cd8b0..1484ef8 100644
--- a/libcutils/atomic.c
+++ b/libcutils/atomic.c
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-#define inline
+#define ANDROID_ATOMIC_INLINE
#include <cutils/atomic-inline.h>
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index b91de52..d812abc 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -134,6 +134,7 @@
{
struct iovec vec[3];
log_id_t log_id = LOG_ID_MAIN;
+ char tmp_tag[32];
if (!tag)
tag = "";
@@ -147,8 +148,12 @@
!strcmp(tag, "STK") ||
!strcmp(tag, "CDMA") ||
!strcmp(tag, "PHONE") ||
- !strcmp(tag, "SMS"))
+ !strcmp(tag, "SMS")) {
log_id = LOG_ID_RADIO;
+ // Inform third party apps/ril/radio.. to use Rlog or RLOG
+ snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
+ tag = tmp_tag;
+ }
vec[0].iov_base = (unsigned char *) &prio;
vec[0].iov_len = 1;
@@ -163,12 +168,14 @@
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
{
struct iovec vec[3];
+ char tmp_tag[32];
if (!tag)
tag = "";
/* XXX: This needs to go! */
- if (!strcmp(tag, "HTC_RIL") ||
+ if ((bufID != LOG_ID_RADIO) &&
+ (!strcmp(tag, "HTC_RIL") ||
!strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
!strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
!strcmp(tag, "AT") ||
@@ -176,8 +183,12 @@
!strcmp(tag, "STK") ||
!strcmp(tag, "CDMA") ||
!strcmp(tag, "PHONE") ||
- !strcmp(tag, "SMS"))
+ !strcmp(tag, "SMS"))) {
bufID = LOG_ID_RADIO;
+ // Inform third party apps/ril/radio.. to use Rlog or RLOG
+ snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
+ tag = tmp_tag;
+ }
vec[0].iov_base = (unsigned char *) &prio;
vec[0].iov_len = 1;
diff --git a/libsuspend/autosuspend.c b/libsuspend/autosuspend.c
index 7d1d973..eb1f66e 100644
--- a/libsuspend/autosuspend.c
+++ b/libsuspend/autosuspend.c
@@ -33,8 +33,6 @@
return 0;
}
- autosuspend_inited = true;
-
autosuspend_ops = autosuspend_earlysuspend_init();
if (autosuspend_ops) {
goto out;
@@ -56,6 +54,8 @@
}
out:
+ autosuspend_inited = true;
+
ALOGV("autosuspend initialized\n");
return 0;
}
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 6731cf1..02a401d 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -25,6 +25,8 @@
#include <sysutils/FrameworkCommand.h>
#include <sysutils/SocketClient.h>
+static const int CMD_BUF_SIZE = 1024;
+
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
SocketListener(socketName, true, withSeq) {
init(socketName, withSeq);
@@ -43,7 +45,7 @@
}
bool FrameworkListener::onDataAvailable(SocketClient *c) {
- char buffer[255];
+ char buffer[CMD_BUF_SIZE];
int len;
len = TEMP_FAILURE_RETRY(read(c->getSocket(), buffer, sizeof(buffer)));
@@ -52,6 +54,8 @@
return false;
} else if (!len)
return false;
+ if(buffer[len-1] != '\0')
+ SLOGW("String is not zero-terminated");
int offset = 0;
int i;
@@ -63,6 +67,7 @@
offset = i + 1;
}
}
+
return true;
}
@@ -74,7 +79,7 @@
FrameworkCommandCollection::iterator i;
int argc = 0;
char *argv[FrameworkListener::CMD_ARGS_MAX];
- char tmp[255];
+ char tmp[CMD_BUF_SIZE];
char *p = data;
char *q = tmp;
char *qlimit = tmp + sizeof(tmp) - 1;
@@ -180,7 +185,6 @@
goto out;
}
}
-
cli->sendMsg(500, "Command not recognized", false);
out:
int j;
diff --git a/libusbhost/Android.mk b/libusbhost/Android.mk
index 52b4ead..9565cc5 100644
--- a/libusbhost/Android.mk
+++ b/libusbhost/Android.mk
@@ -44,3 +44,13 @@
LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_SHARED_LIBRARY)
+
+# Static library for target
+# ========================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libusbhost
+LOCAL_SRC_FILES := usbhost.c
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index c059b89..167fa60 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <stddef.h>
#include <sys/ioctl.h>
#include <sys/types.h>
@@ -50,16 +51,23 @@
#include "usbhost/usbhost.h"
#define DEV_DIR "/dev"
-#define USB_FS_DIR "/dev/bus/usb"
-#define USB_FS_ID_SCANNER "/dev/bus/usb/%d/%d"
-#define USB_FS_ID_FORMAT "/dev/bus/usb/%03d/%03d"
+#define USB_FS_DIR DEV_DIR "/bus/usb"
+#define USB_FS_ID_SCANNER USB_FS_DIR "/%d/%d"
+#define USB_FS_ID_FORMAT USB_FS_DIR "/%03d/%03d"
// From drivers/usb/core/devio.c
// I don't know why this isn't in a kernel header
#define MAX_USBFS_BUFFER_SIZE 16384
+#define MAX_USBFS_WD_COUNT 10
+
struct usb_host_context {
- int fd;
+ int fd;
+ usb_device_added_cb cb_added;
+ usb_device_removed_cb cb_removed;
+ void *data;
+ int wds[MAX_USBFS_WD_COUNT];
+ int wdd;
};
struct usb_device {
@@ -116,10 +124,10 @@
while ((de = readdir(busdir)) != 0 && !done) {
if(badname(de->d_name)) continue;
- snprintf(busname, sizeof(busname), "%s/%s", USB_FS_DIR, de->d_name);
+ snprintf(busname, sizeof(busname), USB_FS_DIR "/%s", de->d_name);
done = find_existing_devices_bus(busname, added_cb,
client_data);
- }
+ } //end of busdir while
closedir(busdir);
return done;
@@ -137,7 +145,7 @@
/* watch existing subdirectories of USB_FS_DIR */
for (i = 1; i < wd_count; i++) {
- snprintf(path, sizeof(path), "%s/%03d", USB_FS_DIR, i);
+ snprintf(path, sizeof(path), USB_FS_DIR "/%03d", i);
ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
if (ret >= 0)
wds[i] = ret;
@@ -166,93 +174,126 @@
free(context);
}
-void usb_host_run(struct usb_host_context *context,
+int usb_host_get_fd(struct usb_host_context *context)
+{
+ return context->fd;
+} /* usb_host_get_fd() */
+
+int usb_host_load(struct usb_host_context *context,
usb_device_added_cb added_cb,
usb_device_removed_cb removed_cb,
usb_discovery_done_cb discovery_done_cb,
void *client_data)
{
- struct inotify_event* event;
- char event_buf[512];
- char path[100];
- int i, ret, done = 0;
- int wd, wdd, wds[10];
- int wd_count = sizeof(wds) / sizeof(wds[0]);
+ int done = 0;
+ int i;
+
+ context->cb_added = added_cb;
+ context->cb_removed = removed_cb;
+ context->data = client_data;
D("Created device discovery thread\n");
/* watch for files added and deleted within USB_FS_DIR */
- for (i = 0; i < wd_count; i++)
- wds[i] = -1;
+ for (i = 0; i < MAX_USBFS_WD_COUNT; i++)
+ context->wds[i] = -1;
/* watch the root for new subdirectories */
- wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE);
- if (wdd < 0) {
+ context->wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE);
+ if (context->wdd < 0) {
fprintf(stderr, "inotify_add_watch failed\n");
if (discovery_done_cb)
discovery_done_cb(client_data);
- return;
+ return done;
}
- watch_existing_subdirs(context, wds, wd_count);
+ watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
/* check for existing devices first, after we have inotify set up */
done = find_existing_devices(added_cb, client_data);
if (discovery_done_cb)
done |= discovery_done_cb(client_data);
- while (!done) {
- ret = read(context->fd, event_buf, sizeof(event_buf));
- if (ret >= (int)sizeof(struct inotify_event)) {
- event = (struct inotify_event *)event_buf;
- wd = event->wd;
- if (wd == wdd) {
- if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
- watch_existing_subdirs(context, wds, wd_count);
- done = find_existing_devices(added_cb, client_data);
- } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
- for (i = 0; i < wd_count; i++) {
- if (wds[i] >= 0) {
- inotify_rm_watch(context->fd, wds[i]);
- wds[i] = -1;
- }
+ return done;
+} /* usb_host_load() */
+
+int usb_host_read_event(struct usb_host_context *context)
+{
+ struct inotify_event* event;
+ char event_buf[512];
+ char path[100];
+ int i, ret, done = 0;
+ int j, event_size;
+ int wd;
+
+ ret = read(context->fd, event_buf, sizeof(event_buf));
+ if (ret >= (int)sizeof(struct inotify_event)) {
+ event = (struct inotify_event *)event_buf;
+ wd = event->wd;
+ if (wd == context->wdd) {
+ if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
+ watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
+ done = find_existing_devices(context->cb_added, context->data);
+ } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
+ for (i = 0; i < MAX_USBFS_WD_COUNT; i++) {
+ if (context->wds[i] >= 0) {
+ inotify_rm_watch(context->fd, context->wds[i]);
+ context->wds[i] = -1;
}
}
- } else if (wd == wds[0]) {
- i = atoi(event->name);
- snprintf(path, sizeof(path), "%s/%s", USB_FS_DIR, event->name);
- D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
- "new" : "gone", path, i);
- if (i > 0 && i < wd_count) {
- if (event->mask & IN_CREATE) {
- ret = inotify_add_watch(context->fd, path,
- IN_CREATE | IN_DELETE);
- if (ret >= 0)
- wds[i] = ret;
- done = find_existing_devices_bus(path, added_cb,
- client_data);
- } else if (event->mask & IN_DELETE) {
- inotify_rm_watch(context->fd, wds[i]);
- wds[i] = -1;
- }
+ }
+ } else if (wd == context->wds[0]) {
+ i = atoi(event->name);
+ snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name);
+ D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
+ "new" : "gone", path, i);
+ if (i > 0 && i < MAX_USBFS_WD_COUNT) {
+ if (event->mask & IN_CREATE) {
+ ret = inotify_add_watch(context->fd, path,
+ IN_CREATE | IN_DELETE);
+ if (ret >= 0)
+ context->wds[i] = ret;
+ done = find_existing_devices_bus(path, context->cb_added,
+ context->data);
+ } else if (event->mask & IN_DELETE) {
+ inotify_rm_watch(context->fd, context->wds[i]);
+ context->wds[i] = -1;
}
- } else {
- for (i = 1; i < wd_count && !done; i++) {
- if (wd == wds[i]) {
- snprintf(path, sizeof(path), "%s/%03d/%s", USB_FS_DIR, i, event->name);
- if (event->mask == IN_CREATE) {
- D("new device %s\n", path);
- done = added_cb(path, client_data);
- } else if (event->mask == IN_DELETE) {
- D("gone device %s\n", path);
- done = removed_cb(path, client_data);
- }
+ }
+ } else {
+ for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) {
+ if (wd == context->wds[i]) {
+ snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name);
+ if (event->mask == IN_CREATE) {
+ D("new device %s\n", path);
+ done = context->cb_added(path, context->data);
+ } else if (event->mask == IN_DELETE) {
+ D("gone device %s\n", path);
+ done = context->cb_removed(path, context->data);
}
}
}
}
}
-}
+
+ return done;
+} /* usb_host_read_event() */
+
+void usb_host_run(struct usb_host_context *context,
+ usb_device_added_cb added_cb,
+ usb_device_removed_cb removed_cb,
+ usb_discovery_done_cb discovery_done_cb,
+ void *client_data)
+{
+ int done;
+
+ done = usb_host_load(context, added_cb, removed_cb, discovery_done_cb, client_data);
+
+ while (!done) {
+
+ done = usb_host_read_event(context);
+ }
+} /* usb_host_run() */
struct usb_device *usb_device_open(const char *dev_name)
{
@@ -606,7 +647,6 @@
{
struct usbdevfs_urb *urb = NULL;
struct usb_request *req = NULL;
- int res;
while (1) {
int res = ioctl(dev->fd, USBDEVFS_REAPURB, &urb);
diff --git a/toolbox/df.c b/toolbox/df.c
index 63940a1..9cd0743 100644
--- a/toolbox/df.c
+++ b/toolbox/df.c
@@ -9,16 +9,22 @@
static void printsize(long long n)
{
char unit = 'K';
- n /= 1024;
- if (n > 1024) {
+ long long t;
+
+ n *= 10;
+
+ if (n > 1024*1024*10) {
n /= 1024;
unit = 'M';
}
- if (n > 1024) {
+
+ if (n > 1024*1024*10) {
n /= 1024;
unit = 'G';
}
- printf("%4lld%c", n, unit);
+
+ t = (n + 512) / 1024;
+ printf("%4lld.%1lld%c", t/10, t%10, unit);
}
static void df(char *s, int always) {
@@ -41,7 +47,7 @@
}
int df_main(int argc, char *argv[]) {
- printf("Filesystem Size Used Free Blksize\n");
+ printf("Filesystem Size Used Free Blksize\n");
if (argc == 1) {
char s[2000];
FILE *f = fopen("/proc/mounts", "r");