Merge "adb: Mask SIGTTIN so that I/O works when backgrounded."
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 07e1d73..27c985c 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -35,7 +35,7 @@
LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_STATIC_LIBRARIES := libbatteryservice libbinder libminui libpng libz libutils libstdc++ libcutils liblog libm libc
+LOCAL_STATIC_LIBRARIES := libbatteryservice libbinder libminui libpng libz libutils libcutils liblog libm libc
ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true)
LOCAL_STATIC_LIBRARIES += libsuspend
diff --git a/logd/Android.mk b/logd/Android.mk
index f1ea29f..feca8d5 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -4,6 +4,8 @@
LOCAL_MODULE:= logd
+LOCAL_INIT_RC := logd.rc
+
LOCAL_SRC_FILES := \
main.cpp \
LogCommand.cpp \
diff --git a/packagelistparser/Android.mk b/packagelistparser/Android.mk
new file mode 100644
index 0000000..802a3cb
--- /dev/null
+++ b/packagelistparser/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+#########################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libpackagelistparser
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := packagelistparser.c
+LOCAL_COPY_HEADERS_TO := packagelistparser
+LOCAL_COPY_HEADERS := packagelistparser.h
+LOCAL_SHARED_LIBRARIES := liblog
+
+LOCAL_CLANG := true
+LOCAL_SANITIZE := integer
+
+include $(BUILD_SHARED_LIBRARY)
+
+#########################
+include $(CLEAR_VARS)
+
+
+LOCAL_MODULE := libpackagelistparser
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := packagelistparser.c
+LOCAL_COPY_HEADERS_TO := packagelistparser
+LOCAL_COPY_HEADERS := packagelistparser.h
+LOCAL_STATIC_LIBRARIES := liblog
+
+LOCAL_CLANG := true
+LOCAL_SANITIZE := integer
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/packagelistparser/packagelistparser.c b/packagelistparser/packagelistparser.c
new file mode 100644
index 0000000..3e2539c
--- /dev/null
+++ b/packagelistparser/packagelistparser.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2015, Intel Corporation
+ * Copyright (C) 2015 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.
+ *
+ * Written by William Roberts <william.c.roberts@intel.com>
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/limits.h>
+
+#define LOG_TAG "packagelistparser"
+#include <utils/Log.h>
+
+#include "packagelistparser.h"
+
+#define CLOGE(fmt, ...) \
+ do {\
+ IF_ALOGE() {\
+ ALOGE(fmt, ##__VA_ARGS__);\
+ }\
+ } while(0)
+
+static size_t get_gid_cnt(const char *gids)
+{
+ size_t cnt;
+
+ if (*gids == '\0') {
+ return 0;
+ }
+
+ if (!strcmp(gids, "none")) {
+ return 0;
+ }
+
+ for (cnt = 1; gids[cnt]; gids[cnt] == ',' ? cnt++ : *gids++)
+ ;
+
+ return cnt;
+}
+
+static bool parse_gids(char *gids, gid_t *gid_list, size_t *cnt)
+{
+ gid_t gid;
+ char* token;
+ char *endptr;
+ size_t cmp = 0;
+
+ while ((token = strsep(&gids, ",\r\n"))) {
+
+ if (cmp > *cnt) {
+ return false;
+ }
+
+ gid = strtoul(token, &endptr, 10);
+ if (*endptr != '\0') {
+ return false;
+ }
+
+ /*
+ * if unsigned long is greater than size of gid_t,
+ * prevent a truncation based roll-over
+ */
+ if (gid > GID_MAX) {
+ CLOGE("A gid in field \"gid list\" greater than GID_MAX");
+ return false;
+ }
+
+ gid_list[cmp++] = gid;
+ }
+ return true;
+}
+
+extern bool packagelist_parse(pfn_on_package callback, void *userdata)
+{
+
+ FILE *fp;
+ char *cur;
+ char *next;
+ char *endptr;
+ unsigned long tmp;
+ ssize_t bytesread;
+
+ bool rc = false;
+ char *buf = NULL;
+ size_t buflen = 0;
+ unsigned long lineno = 1;
+ const char *errmsg = NULL;
+ struct pkg_info *pkg_info = NULL;
+
+ fp = fopen(PACKAGES_LIST_FILE, "re");
+ if (!fp) {
+ CLOGE("Could not open: \"%s\", error: \"%s\"\n", PACKAGES_LIST_FILE,
+ strerror(errno));
+ return false;
+ }
+
+ while ((bytesread = getline(&buf, &buflen, fp)) > 0) {
+
+ pkg_info = calloc(1, sizeof(*pkg_info));
+ if (!pkg_info) {
+ goto err;
+ }
+
+ next = buf;
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for \"package name\"";
+ goto err;
+ }
+
+ pkg_info->name = strdup(cur);
+ if (!pkg_info->name) {
+ goto err;
+ }
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for field \"uid\"";
+ goto err;
+ }
+
+ tmp = strtoul(cur, &endptr, 10);
+ if (*endptr != '\0') {
+ errmsg = "Could not convert field \"uid\" to integer value";
+ goto err;
+ }
+
+ /*
+ * if unsigned long is greater than size of uid_t,
+ * prevent a truncation based roll-over
+ */
+ if (tmp > UID_MAX) {
+ errmsg = "Field \"uid\" greater than UID_MAX";
+ goto err;
+ }
+
+ pkg_info->uid = (uid_t) tmp;
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for field \"debuggable\"";
+ goto err;
+ }
+
+ tmp = strtoul(cur, &endptr, 10);
+ if (*endptr != '\0') {
+ errmsg = "Could not convert field \"debuggable\" to integer value";
+ goto err;
+ }
+
+ /* should be a valid boolean of 1 or 0 */
+ if (!(tmp == 0 || tmp == 1)) {
+ errmsg = "Field \"debuggable\" is not 0 or 1 boolean value";
+ goto err;
+ }
+
+ pkg_info->debuggable = (bool) tmp;
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for field \"data dir\"";
+ goto err;
+ }
+
+ pkg_info->data_dir = strdup(cur);
+ if (!pkg_info->data_dir) {
+ goto err;
+ }
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for field \"seinfo\"";
+ goto err;
+ }
+
+ pkg_info->seinfo = strdup(cur);
+ if (!pkg_info->seinfo) {
+ goto err;
+ }
+
+ cur = strsep(&next, " \t\r\n");
+ if (!cur) {
+ errmsg = "Could not get next token for field \"gid(s)\"";
+ goto err;
+ }
+
+ /*
+ * Parse the gid list, could be in the form of none, single gid or list:
+ * none
+ * gid
+ * gid, gid ...
+ */
+ pkg_info->gids.cnt = get_gid_cnt(cur);
+ if (pkg_info->gids.cnt > 0) {
+
+ pkg_info->gids.gids = calloc(pkg_info->gids.cnt, sizeof(gid_t));
+ if (!pkg_info->gids.gids) {
+ goto err;
+ }
+
+ rc = parse_gids(cur, pkg_info->gids.gids, &pkg_info->gids.cnt);
+ if (!rc) {
+ errmsg = "Could not parse field \"gid list\"";
+ goto err;
+ }
+ }
+
+ rc = callback(pkg_info, userdata);
+ if (rc == false) {
+ /*
+ * We do not log this as this can be intentional from
+ * callback to abort processing. We go to out to not
+ * free the pkg_info
+ */
+ rc = true;
+ goto out;
+ }
+ lineno++;
+ }
+
+ rc = true;
+
+out:
+ free(buf);
+ fclose(fp);
+ return rc;
+
+err:
+ if (errmsg) {
+ CLOGE("Error Parsing \"%s\" on line: %lu for reason: %s",
+ PACKAGES_LIST_FILE, lineno, errmsg);
+ }
+ rc = false;
+ packagelist_free(pkg_info);
+ goto out;
+}
+
+void packagelist_free(pkg_info *info)
+{
+ if (info) {
+ free(info->name);
+ free(info->data_dir);
+ free(info->seinfo);
+ free(info->gids.gids);
+ free(info);
+ }
+}
diff --git a/packagelistparser/packagelistparser.h b/packagelistparser/packagelistparser.h
new file mode 100644
index 0000000..d602c26
--- /dev/null
+++ b/packagelistparser/packagelistparser.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015, Intel Corporation
+ * Copyright (C) 2015 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.
+ *
+ * Written by William Roberts <william.c.roberts@intel.com>
+ *
+ * This is a parser library for parsing the packages.list file generated
+ * by PackageManager service.
+ *
+ * This simple parser is sensitive to format changes in
+ * frameworks/base/services/core/java/com/android/server/pm/Settings.java
+ * A dependency note has been added to that file to correct
+ * this parser.
+ */
+
+#ifndef PACKAGELISTPARSER_H_
+#define PACKAGELISTPARSER_H_
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/** The file containing the list of installed packages on the system */
+#define PACKAGES_LIST_FILE "/data/system/packages.list"
+
+typedef struct pkg_info pkg_info;
+typedef struct gid_list gid_list;
+
+struct gid_list {
+ size_t cnt;
+ gid_t *gids;
+};
+
+struct pkg_info {
+ char *name;
+ uid_t uid;
+ bool debuggable;
+ char *data_dir;
+ char *seinfo;
+ gid_list gids;
+ void *private_data;
+};
+
+/**
+ * Callback function to be used by packagelist_parse() routine.
+ * @param info
+ * The parsed package information
+ * @param userdata
+ * The supplied userdata pointer to packagelist_parse()
+ * @return
+ * true to keep processing, false to stop.
+ */
+typedef bool (*pfn_on_package)(pkg_info *info, void *userdata);
+
+/**
+ * Parses the file specified by PACKAGES_LIST_FILE and invokes the callback on
+ * each entry found. Once the callback is invoked, ownership of the pkg_info pointer
+ * is passed to the callback routine, thus they are required to perform any cleanup
+ * desired.
+ * @param callback
+ * The callback function called on each parsed line of the packages list.
+ * @param userdata
+ * An optional userdata supplied pointer to pass to the callback function.
+ * @return
+ * true on success false on failure.
+ */
+extern bool packagelist_parse(pfn_on_package callback, void *userdata);
+
+/**
+ * Frees a pkg_info structure.
+ * @param info
+ * The struct to free
+ */
+extern void packagelist_free(pkg_info *info);
+
+__END_DECLS
+
+#endif /* PACKAGELISTPARSER_H_ */
diff --git a/rootdir/asan.options b/rootdir/asan.options
index 2f12341..43896a1 100644
--- a/rootdir/asan.options
+++ b/rootdir/asan.options
@@ -1 +1,5 @@
-allow_user_segv_handler=1:detect_odr_violation=0:alloc_dealloc_mismatch=0:allocator_may_return_null=1
+allow_user_segv_handler=1
+detect_odr_violation=0
+alloc_dealloc_mismatch=0
+allocator_may_return_null=1
+detect_container_overflow=0
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 579d26e..52716e9 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -31,7 +31,6 @@
dd \
OUR_TOOLS := \
- df \
getevent \
iftop \
ioctl \
diff --git a/toolbox/df.c b/toolbox/df.c
deleted file mode 100644
index 9cd0743..0000000
--- a/toolbox/df.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/statfs.h>
-
-static int ok = EXIT_SUCCESS;
-
-static void printsize(long long n)
-{
- char unit = 'K';
- long long t;
-
- n *= 10;
-
- if (n > 1024*1024*10) {
- n /= 1024;
- unit = 'M';
- }
-
- if (n > 1024*1024*10) {
- n /= 1024;
- unit = 'G';
- }
-
- t = (n + 512) / 1024;
- printf("%4lld.%1lld%c", t/10, t%10, unit);
-}
-
-static void df(char *s, int always) {
- struct statfs st;
-
- if (statfs(s, &st) < 0) {
- fprintf(stderr, "%s: %s\n", s, strerror(errno));
- ok = EXIT_FAILURE;
- } else {
- if (st.f_blocks == 0 && !always)
- return;
- printf("%-20s ", s);
- printsize((long long)st.f_blocks * (long long)st.f_bsize);
- printf(" ");
- printsize((long long)(st.f_blocks - (long long)st.f_bfree) * st.f_bsize);
- printf(" ");
- printsize((long long)st.f_bfree * (long long)st.f_bsize);
- printf(" %d\n", (int) st.f_bsize);
- }
-}
-
-int df_main(int argc, char *argv[]) {
- printf("Filesystem Size Used Free Blksize\n");
- if (argc == 1) {
- char s[2000];
- FILE *f = fopen("/proc/mounts", "r");
-
- while (fgets(s, 2000, f)) {
- char *c, *e = s;
-
- for (c = s; *c; c++) {
- if (*c == ' ') {
- e = c + 1;
- break;
- }
- }
-
- for (c = e; *c; c++) {
- if (*c == ' ') {
- *c = '\0';
- break;
- }
- }
-
- df(e, 0);
- }
-
- fclose(f);
- } else {
- int i;
-
- for (i = 1; i < argc; i++) {
- df(argv[i], 1);
- }
- }
-
- exit(ok);
-}