Merge "Create world readable, system writeable /data/resource-cache."
diff --git a/adb/sockets.c b/adb/sockets.c
index aa4d5fc..f0357d6 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -221,10 +221,12 @@
if(s->peer) {
s->peer->peer = 0;
// tweak to avoid deadlock
- if (s->peer->close == local_socket_close)
+ if (s->peer->close == local_socket_close) {
local_socket_close_locked(s->peer);
- else
+ } else {
s->peer->close(s->peer);
+ }
+ s->peer = 0;
}
/* If we are already closing, or if there are no
@@ -782,6 +784,7 @@
if(s->peer) {
s->peer->peer = 0;
s->peer->close(s->peer);
+ s->peer = 0;
}
free(s);
}
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index d642566..28ba80d 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -87,6 +87,16 @@
#define VENDOR_ID_PHILIPS 0x0471
// Texas Instruments's USB Vendor ID
#define VENDOR_ID_TI 0x0451
+// Funai's USB Vendor ID
+#define VENDOR_ID_FUNAI 0x0F1C
+// Gigabyte's USB Vendor ID
+#define VENDOR_ID_GIGABYTE 0x0414
+// IRiver's USB Vendor ID
+#define VENDOR_ID_IRIVER 0x2420
+// Compal's USB Vendor ID
+#define VENDOR_ID_COMPAL 0x1219
+// T & A Mobile Phones' USB Vendor ID
+#define VENDOR_ID_T_AND_A 0x1BBB
/** built-in vendor list */
@@ -117,6 +127,11 @@
VENDOR_ID_ASUS,
VENDOR_ID_PHILIPS,
VENDOR_ID_TI,
+ VENDOR_ID_FUNAI,
+ VENDOR_ID_GIGABYTE,
+ VENDOR_ID_IRIVER,
+ VENDOR_ID_COMPAL,
+ VENDOR_ID_T_AND_A,
};
#define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
diff --git a/adb/usb_vendors.h b/adb/usb_vendors.h
index 43790b9..cee23a1 100644
--- a/adb/usb_vendors.h
+++ b/adb/usb_vendors.h
@@ -22,4 +22,4 @@
void usb_vendors_init(void);
-#endif
\ No newline at end of file
+#endif
diff --git a/debuggerd/x86/unwind.c b/debuggerd/x86/unwind.c
index 8f84e01..0a7f04c 100644
--- a/debuggerd/x86/unwind.c
+++ b/debuggerd/x86/unwind.c
@@ -24,7 +24,6 @@
//ebp==0, it indicates that the stack is poped to the bottom or there is no stack at all.
while (ebp) {
- _LOG(tfd, !at_fault, "#0%d ",stack_level);
mi = pc_to_mapinfo(map, eip, &rel_pc);
/* See if we can determine what symbol this stack frame resides in */
@@ -32,9 +31,11 @@
sym = symbol_table_lookup(mi->symbols, rel_pc);
}
if (sym) {
- _LOG(tfd, !at_fault, " eip: %08x %s (%s)\n", eip, mi ? mi->name : "", sym->name);
+ _LOG(tfd, !at_fault, " #%02d eip: %08x %s (%s)\n",
+ stack_level, eip, mi ? mi->name : "", sym->name);
} else {
- _LOG(tfd, !at_fault, " eip: %08x %s\n", eip, mi ? mi->name : "");
+ _LOG(tfd, !at_fault, " #%02d eip: %08x %s\n",
+ stack_level, eip, mi ? mi->name : "");
}
stack_level++;
@@ -49,7 +50,6 @@
if (ebp)
_LOG(tfd, !at_fault, "stack: \n");
while (ebp) {
- _LOG(tfd, !at_fault, "#0%d \n",stack_level);
stack_ptr = cur_sp;
while((int)(ebp - stack_ptr) >= 0) {
stack_content = ptrace(PTRACE_PEEKTEXT, pid, (void*)stack_ptr, NULL);
@@ -60,10 +60,11 @@
sym = symbol_table_lookup(mi->symbols, rel_pc);
}
if (sym) {
- _LOG(tfd, !at_fault, " %08x %08x %s (%s)\n",
- stack_ptr, stack_content, mi ? mi->name : "", sym->name);
+ _LOG(tfd, !at_fault, " #%02d %08x %08x %s (%s)\n",
+ stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name);
} else {
- _LOG(tfd, !at_fault, " %08x %08x %s\n", stack_ptr, stack_content, mi ? mi->name : "");
+ _LOG(tfd, !at_fault, " #%02d %08x %08x %s\n",
+ stack_level, stack_ptr, stack_content, mi ? mi->name : "");
}
stack_ptr = stack_ptr + 4;
diff --git a/include/cutils/str_parms.h b/include/cutils/str_parms.h
new file mode 100644
index 0000000..247c996
--- /dev/null
+++ b/include/cutils/str_parms.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 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 __CUTILS_STR_PARMS_H
+#define __CUTILS_STR_PARMS_H
+
+#include <stdint.h>
+
+struct str_parms;
+
+struct str_parms *str_parms_create(void);
+struct str_parms *str_parms_create_str(const char *_string);
+void str_parms_destroy(struct str_parms *str_parms);
+
+void str_parms_del(struct str_parms *str_parms, const char *key);
+
+int str_parms_add_str(struct str_parms *str_parms, const char *key,
+ const char *value);
+int str_parms_add_int(struct str_parms *str_parms, const char *key, int value);
+
+int str_parms_add_float(struct str_parms *str_parms, const char *key,
+ float value);
+
+int str_parms_get_str(struct str_parms *str_parms, const char *key,
+ char *out_val, int len);
+int str_parms_get_int(struct str_parms *str_parms, const char *key,
+ int *out_val);
+int str_parms_get_float(struct str_parms *str_parms, const char *key,
+ float *out_val);
+
+char *str_parms_to_str(struct str_parms *str_parms);
+
+/* debug */
+void str_parms_dump(struct str_parms *str_parms);
+
+#endif /* __CUTILS_STR_PARMS_H */
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 8b739e9..84cccd9 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -46,7 +46,8 @@
properties.c \
threads.c \
sched_policy.c \
- iosched_policy.c
+ iosched_policy.c \
+ str_parms.c
commonHostSources := \
ashmem-host.c
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
new file mode 100644
index 0000000..dfa1f73
--- /dev/null
+++ b/libcutils/str_parms.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "str_params"
+//#define LOG_NDEBUG 0
+
+#define _GNU_SOURCE 1
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cutils/hashmap.h>
+#include <cutils/log.h>
+#include <cutils/memory.h>
+
+#include <cutils/str_parms.h>
+
+struct str_parms {
+ Hashmap *map;
+};
+
+
+static bool str_eq(void *key_a, void *key_b)
+{
+ return !strcmp((const char *)key_a, (const char *)key_b);
+}
+
+/* use djb hash unless we find it inadequate */
+static int str_hash_fn(void *str)
+{
+ uint32_t hash = 5381;
+ char *p;
+
+ for (p = str; p && *p; p++)
+ hash = ((hash << 5) + hash) + *p;
+ return (int)hash;
+}
+
+struct str_parms *str_parms_create(void)
+{
+ struct str_parms *str_parms;
+
+ str_parms = calloc(1, sizeof(struct str_parms));
+ if (!str_parms)
+ return NULL;
+
+ str_parms->map = hashmapCreate(5, str_hash_fn, str_eq);
+ if (!str_parms->map)
+ goto err;
+
+ return str_parms;
+
+err:
+ free(str_parms);
+ return NULL;
+}
+
+static bool remove_pair(void *key, void *value, void *context)
+{
+ struct str_parms *str_parms = context;
+
+ hashmapRemove(str_parms->map, key);
+ free(key);
+ free(value);
+ return true;
+}
+
+void str_parms_destroy(struct str_parms *str_parms)
+{
+ hashmapForEach(str_parms->map, remove_pair, str_parms);
+ hashmapFree(str_parms->map);
+ free(str_parms);
+}
+
+struct str_parms *str_parms_create_str(const char *_string)
+{
+ struct str_parms *str_parms;
+ char *str;
+ char *kvpair;
+ char *tmpstr;
+ int items = 0;
+
+ str_parms = str_parms_create();
+ if (!str_parms)
+ goto err_create_str_parms;
+
+ str = strdup(_string);
+ if (!str)
+ goto err_strdup;
+
+ LOGV("%s: source string == '%s'\n", __func__, _string);
+
+ kvpair = strtok_r(str, ";", &tmpstr);
+ while (kvpair && *kvpair) {
+ char *eq = strchr(kvpair, '='); /* would love strchrnul */
+ char *value;
+ char *key;
+ void *old_val;
+
+ if (eq == kvpair)
+ goto next_pair;
+
+ if (eq) {
+ key = strndup(kvpair, eq - kvpair);
+ if (*(++eq))
+ value = strdup(eq);
+ else
+ value = strdup("");
+ } else {
+ key = strdup(kvpair);
+ value = strdup("");
+ }
+
+ /* if we replaced a value, free it */
+ old_val = hashmapPut(str_parms->map, key, value);
+ if (old_val)
+ free(old_val);
+
+ items++;
+next_pair:
+ kvpair = strtok_r(NULL, ";", &tmpstr);
+ }
+
+ if (!items)
+ LOGV("%s: no items found in string\n", __func__);
+
+ free(str);
+
+ return str_parms;
+
+err_strdup:
+ str_parms_destroy(str_parms);
+err_create_str_parms:
+ return NULL;
+}
+
+void str_parms_del(struct str_parms *str_parms, const char *key)
+{
+ hashmapRemove(str_parms->map, (void *)key);
+}
+
+int str_parms_add_str(struct str_parms *str_parms, const char *key,
+ const char *value)
+{
+ void *old_val;
+ char *tmp;
+
+ tmp = strdup(value);
+ old_val = hashmapPut(str_parms->map, (void *)key, tmp);
+
+ if (old_val) {
+ free(old_val);
+ } else if (errno == ENOMEM) {
+ free(tmp);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int str_parms_add_int(struct str_parms *str_parms, const char *key, int value)
+{
+ char val_str[12];
+ int ret;
+
+ ret = snprintf(val_str, sizeof(val_str), "%d", value);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = str_parms_add_str(str_parms, key, val_str);
+ return ret;
+}
+
+int str_parms_add_float(struct str_parms *str_parms, const char *key,
+ float value)
+{
+ char val_str[23];
+ int ret;
+
+ ret = snprintf(val_str, sizeof(val_str), "%.10f", value);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = str_parms_add_str(str_parms, key, val_str);
+ return ret;
+}
+
+int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
+ int len)
+{
+ char *value;
+
+ value = hashmapGet(str_parms->map, (void *)key);
+ if (value)
+ return strlcpy(val, value, len);
+
+ return -ENOENT;
+}
+
+int str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)
+{
+ char *value;
+ char *end;
+
+ value = hashmapGet(str_parms->map, (void *)key);
+ if (!value)
+ return -ENOENT;
+
+ *val = (int)strtol(value, &end, 0);
+ if (*value != '\0' && *end == '\0')
+ return 0;
+
+ return -EINVAL;
+}
+
+int str_parms_get_float(struct str_parms *str_parms, const char *key,
+ float *val)
+{
+ float out;
+ char *value;
+ char *end;
+
+ value = hashmapGet(str_parms->map, (void *)key);
+ if (!value)
+ return -ENOENT;
+
+ out = strtof(value, &end);
+ if (*value != '\0' && *end == '\0')
+ return 0;
+
+ return -EINVAL;
+}
+
+static bool combine_strings(void *key, void *value, void *context)
+{
+ char **old_str = context;
+ char *new_str;
+ int ret;
+
+ ret = asprintf(&new_str, "%s%s%s=%s",
+ *old_str ? *old_str : "",
+ *old_str ? ";" : "",
+ (char *)key,
+ (char *)value);
+ if (*old_str)
+ free(*old_str);
+
+ if (ret >= 0) {
+ *old_str = new_str;
+ return true;
+ }
+
+ *old_str = NULL;
+ return false;
+}
+
+char *str_parms_to_str(struct str_parms *str_parms)
+{
+ char *str = NULL;
+
+ if (hashmapSize(str_parms->map) > 0)
+ hashmapForEach(str_parms->map, combine_strings, &str);
+ else
+ str = strdup("");
+ return str;
+}
+
+static bool dump_entry(void *key, void *value, void *context)
+{
+ LOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value);
+ return true;
+}
+
+void str_parms_dump(struct str_parms *str_parms)
+{
+ hashmapForEach(str_parms->map, dump_entry, str_parms);
+}
+
+#ifdef TEST_STR_PARMS
+static void test_str_parms_str(const char *str)
+{
+ struct str_parms *str_parms;
+ char *out_str;
+ int ret;
+
+ str_parms = str_parms_create_str(str);
+ str_parms_dump(str_parms);
+ out_str = str_parms_to_str(str_parms);
+ str_parms_destroy(str_parms);
+ LOGI("%s: '%s' stringified is '%s'", __func__, str, out_str);
+ free(out_str);
+}
+
+int main(void)
+{
+ struct str_parms *str_parms;
+
+ test_str_parms_str("");
+ test_str_parms_str(";");
+ test_str_parms_str("=");
+ test_str_parms_str("=;");
+ test_str_parms_str("=bar");
+ test_str_parms_str("=bar;");
+ test_str_parms_str("foo=");
+ test_str_parms_str("foo=;");
+ test_str_parms_str("foo=bar");
+ test_str_parms_str("foo=bar;");
+ test_str_parms_str("foo=bar;baz");
+ test_str_parms_str("foo=bar;baz=");
+ test_str_parms_str("foo=bar;baz=bat");
+ test_str_parms_str("foo=bar;baz=bat;");
+
+ return 0;
+}
+#endif
diff --git a/run-as/package.c b/run-as/package.c
index 46f8239..ca08436 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -44,7 +44,7 @@
#define PACKAGES_LIST_FILE "/data/system/packages.list"
/* This should be large enough to hold the content of the package database file */
-#define PACKAGES_LIST_BUFFER_SIZE 8192
+#define PACKAGES_LIST_BUFFER_SIZE 65536
/* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen'
* This function always zero-terminate the destination buffer unless
diff --git a/toolbox/ls.c b/toolbox/ls.c
index 962bf47..59ba35e 100644
--- a/toolbox/ls.c
+++ b/toolbox/ls.c
@@ -144,6 +144,7 @@
#define LIST_RECURSIVE (1 << 2)
#define LIST_DIRECTORIES (1 << 3)
#define LIST_SIZE (1 << 4)
+#define LIST_CLASSIFY (1 << 6)
// fwd
static int listpath(const char *name, int flags);
@@ -253,7 +254,27 @@
}
/* blocks are 512 bytes, we want output to be KB */
- printf("%lld %s\n", s.st_blocks / 2, filename);
+ if ((flags & LIST_SIZE) != 0) {
+ printf("%lld ", s.st_blocks / 2);
+ }
+
+ if ((flags & LIST_CLASSIFY) != 0) {
+ char filetype = mode2kind(s.st_mode);
+ if (filetype != 'l') {
+ printf("%c ", filetype);
+ } else {
+ struct stat link_dest;
+ if (!stat(path, &link_dest)) {
+ printf("l%c ", mode2kind(link_dest.st_mode));
+ } else {
+ fprintf(stderr, "stat '%s' failed: %s\n", path, strerror(errno));
+ printf("l? ");
+ }
+ }
+ }
+
+ printf("%s\n", filename);
+
return 0;
}
@@ -330,7 +351,7 @@
static int listfile(const char *dirname, const char *filename, int flags)
{
- if ((flags & (LIST_LONG | LIST_SIZE)) == 0) {
+ if ((flags & (LIST_LONG | LIST_SIZE | LIST_CLASSIFY)) == 0) {
printf("%s\n", filename);
return 0;
}
@@ -480,6 +501,7 @@
case 'R': flags |= LIST_RECURSIVE; break;
case 'd': flags |= LIST_DIRECTORIES; break;
case 'a': flags |= LIST_ALL; break;
+ case 'F': flags |= LIST_CLASSIFY; break;
default:
fprintf(stderr, "%s: Unknown option '-%c'. Aborting.\n", "ls", arg[0]);
exit(1);