Merge "libprocinfo: provide MapInfo structure for reading maps."
diff --git a/adb/client/console.cpp b/adb/client/console.cpp
index 9563eac..4e8a3f8 100644
--- a/adb/client/console.cpp
+++ b/adb/client/console.cpp
@@ -135,6 +135,7 @@
// preventing the emulator from reading the command that adb has sent.
// https://code.google.com/p/android/issues/detail?id=21021
int result;
+ std::string emulator_output;
do {
char buf[BUFSIZ];
result = adb_read(fd, buf, sizeof(buf));
@@ -146,8 +147,37 @@
// appended above, and that causes the emulator to close the socket
// which should cause zero bytes (orderly/graceful shutdown) to be
// returned.
+ if (result > 0) emulator_output.append(buf, result);
} while (result > 0);
+ // Note: the following messages are expected to be quite stable from emulator.
+ //
+ // Emulator console will send the following message upon connection:
+ //
+ // Android Console: Authentication required
+ // Android Console: type 'auth <auth_token>' to authenticate
+ // Android Console: you can find your <auth_token> in
+ // '/<path-to-home>/.emulator_console_auth_token'
+ // OK\r\n
+ //
+ // and the following after authentication:
+ // Android Console: type 'help' for a list of commands
+ // OK\r\n
+ //
+ // So try search and skip first two "OK\r\n", print the rest.
+ //
+ const std::string delims = "OK\r\n";
+ size_t found = 0;
+ for (int i = 0; i < 2; ++i) {
+ const size_t result = emulator_output.find(delims, found);
+ if (result == std::string::npos) {
+ break;
+ } else {
+ found = result + delims.size();
+ }
+ }
+
+ printf("%s", emulator_output.c_str() + found);
adb_close(fd);
return 0;
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index 9c35560..fc5c1ce 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -61,6 +61,7 @@
bool StartsWithIgnoreCase(const std::string& s, const char* prefix);
bool StartsWith(const std::string& s, const std::string& prefix);
bool StartsWithIgnoreCase(const std::string& s, const std::string& prefix);
+bool StartsWith(const std::string& s, char prefix);
// Tests whether 's' ends with 'suffix'.
// TODO: string_view
@@ -68,6 +69,7 @@
bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
bool EndsWith(const std::string& s, const std::string& suffix);
bool EndsWithIgnoreCase(const std::string& s, const std::string& suffix);
+bool EndsWith(const std::string& s, char suffix);
// Tests whether 'lhs' equals 'rhs', ignoring case.
bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs);
diff --git a/base/strings.cpp b/base/strings.cpp
index a8bb2a9..2d6eef0 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -95,6 +95,10 @@
return strncmp(s.c_str(), prefix.c_str(), prefix.size()) == 0;
}
+bool StartsWith(const std::string& s, char prefix) {
+ return *s.c_str() == prefix; // Use c_str() to guarantee there is at least a '\0'.
+}
+
bool StartsWithIgnoreCase(const std::string& s, const char* prefix) {
return strncasecmp(s.c_str(), prefix, strlen(prefix)) == 0;
}
@@ -121,6 +125,10 @@
return EndsWith(s, suffix.c_str(), suffix.size(), true);
}
+bool EndsWith(const std::string& s, char suffix) {
+ return EndsWith(s, &suffix, 1, true);
+}
+
bool EndsWithIgnoreCase(const std::string& s, const char* suffix) {
return EndsWith(s, suffix, strlen(suffix), false);
}
diff --git a/base/strings_test.cpp b/base/strings_test.cpp
index b8639ea..9d74094 100644
--- a/base/strings_test.cpp
+++ b/base/strings_test.cpp
@@ -198,6 +198,12 @@
ASSERT_FALSE(android::base::StartsWithIgnoreCase("foobar", "BAR"));
}
+TEST(strings, StartsWith_char) {
+ ASSERT_FALSE(android::base::StartsWith("", 'f'));
+ ASSERT_TRUE(android::base::StartsWith("foo", 'f'));
+ ASSERT_FALSE(android::base::StartsWith("foo", 'o'));
+}
+
TEST(strings, EndsWith_empty) {
ASSERT_FALSE(android::base::EndsWith("", "foo"));
ASSERT_TRUE(android::base::EndsWith("", ""));
@@ -273,6 +279,12 @@
ASSERT_FALSE(android::base::EndsWithIgnoreCase("GoOdByE", std::string{"lo"}));
}
+TEST(strings, EndsWith_char) {
+ ASSERT_FALSE(android::base::EndsWith("", 'o'));
+ ASSERT_TRUE(android::base::EndsWith("foo", 'o'));
+ ASSERT_FALSE(android::base::EndsWith("foo", "f"));
+}
+
TEST(strings, EqualsIgnoreCase) {
ASSERT_TRUE(android::base::EqualsIgnoreCase("foo", "FOO"));
ASSERT_TRUE(android::base::EqualsIgnoreCase("FOO", "foo"));
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index ed7423b..15c0265 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -250,11 +250,12 @@
}
uint64_t expected = pack_thread_fd(-1, -1);
- if (!trace_output.compare_exchange_strong(expected,
- pack_thread_fd(tid, pipe_write.release()))) {
+ int sent_fd = pipe_write.release();
+ if (!trace_output.compare_exchange_strong(expected, pack_thread_fd(tid, sent_fd))) {
auto [tid, fd] = unpack_thread_fd(expected);
async_safe_format_log(ANDROID_LOG_ERROR, "libc",
"thread %d is already outputting to fd %d?", tid, fd);
+ close(sent_fd);
return false;
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 79957f6..2ac638a 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -61,10 +61,18 @@
return false;
}
+bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>&) {
+ return false;
+}
+
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab*) {
return {};
}
+std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<const fstab_rec*>&) {
+ return {};
+}
+
bool fs_mgr_overlayfs_setup(const char*, const char*, bool* change) {
if (change) *change = false;
return false;
@@ -764,6 +772,13 @@
return ret;
}
+bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>& fsrecs) {
+ std::vector<fstab_rec> recs;
+ for (const auto& rec : fsrecs) recs.push_back(*rec);
+ fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
+ return fs_mgr_overlayfs_mount_all(&fstab);
+}
+
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), kScratchMountPoint)) {
return {};
@@ -778,6 +793,14 @@
return {};
}
+std::vector<std::string> fs_mgr_overlayfs_required_devices(
+ const std::vector<const fstab_rec*>& fsrecs) {
+ std::vector<fstab_rec> recs;
+ for (const auto& rec : fsrecs) recs.push_back(*rec);
+ fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
+ return fs_mgr_overlayfs_required_devices(&fstab);
+}
+
// Returns false if setup not permitted, errno set to last error.
// If something is altered, set *change.
bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change) {
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 550dd18..9182532 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -22,7 +22,10 @@
#include <vector>
bool fs_mgr_overlayfs_mount_all(fstab* fstab);
+bool fs_mgr_overlayfs_mount_all(const std::vector<const fstab_rec*>& fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab);
+std::vector<std::string> fs_mgr_overlayfs_required_devices(
+ const std::vector<const fstab_rec*>& fstab);
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
bool* change = nullptr);
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
diff --git a/liblog/pmsg_reader.c b/liblog/pmsg_reader.c
index c3ed8a2..bf0e4fe 100644
--- a/liblog/pmsg_reader.c
+++ b/liblog/pmsg_reader.c
@@ -269,6 +269,14 @@
}
}
+static void* realloc_or_free(void* ptr, size_t new_size) {
+ void* result = realloc(ptr, new_size);
+ if (!result) {
+ free(ptr);
+ }
+ return result;
+}
+
LIBLOG_ABI_PRIVATE ssize_t
__android_log_pmsg_file_read(log_id_t logId, char prio, const char* prefix,
__android_log_pmsg_file_read_fn fn, void* arg) {
@@ -541,7 +549,7 @@
/* Missing sequence numbers */
while (sequence < content->entry.nsec) {
/* plus space for enforced nul */
- buf = realloc(buf, len + sizeof(char) + sizeof(char));
+ buf = realloc_or_free(buf, len + sizeof(char) + sizeof(char));
if (!buf) {
break;
}
@@ -556,7 +564,7 @@
continue;
}
/* plus space for enforced nul */
- buf = realloc(buf, len + add_len + sizeof(char));
+ buf = realloc_or_free(buf, len + add_len + sizeof(char));
if (!buf) {
ret = -ENOMEM;
list_remove(content_node);