Merge changes Iac33dbaa,I18fcd37d into mnc-dev
* changes:
pass in correct buffer to print_id
stop including rootdir build.prop
diff --git a/adb/Android.mk b/adb/Android.mk
index 9b6e147..1613a88 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -11,6 +11,13 @@
adb_host_clang := true
endif
+adb_version := $(shell git -C $(LOCAL_PATH) rev-parse --short=12 HEAD 2>/dev/null)-android
+
+ADB_COMMON_CFLAGS := \
+ -Wall -Werror \
+ -Wno-unused-parameter \
+ -DADB_REVISION='"$(adb_version)"' \
+
# libadb
# =========================================================
@@ -37,8 +44,7 @@
transport_test.cpp \
LIBADB_CFLAGS := \
- -Wall -Werror \
- -Wno-unused-parameter \
+ $(ADB_COMMON_CFLAGS) \
-Wno-missing-field-initializers \
-fvisibility=hidden \
@@ -124,6 +130,21 @@
include $(BUILD_HOST_NATIVE_TEST)
+# adb device tracker (used by ddms) test tool
+# =========================================================
+
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_CLANG := $(adb_host_clang)
+LOCAL_MODULE := adb_device_tracker_test
+LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
+LOCAL_SRC_FILES := test_track_devices.cpp
+LOCAL_SHARED_LIBRARIES := liblog libbase
+LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils
+LOCAL_LDLIBS += -lrt -ldl -lpthread
+include $(BUILD_HOST_EXECUTABLE)
+endif
+
# adb host tool
# =========================================================
include $(CLEAR_VARS)
@@ -154,8 +175,7 @@
file_sync_client.cpp \
LOCAL_CFLAGS += \
- -Wall -Werror \
- -Wno-unused-parameter \
+ $(ADB_COMMON_CFLAGS) \
-D_GNU_SOURCE \
-DADB_HOST=1 \
@@ -207,10 +227,9 @@
set_verity_enable_state_service.cpp \
LOCAL_CFLAGS := \
+ $(ADB_COMMON_CFLAGS) \
-DADB_HOST=0 \
-D_GNU_SOURCE \
- -Wall -Werror \
- -Wno-unused-parameter \
-Wno-deprecated-declarations \
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e526914..8a7b9c9 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -48,9 +48,7 @@
#include <sys/mount.h>
#endif
-#if ADB_TRACE
ADB_MUTEX_DEFINE( D_lock );
-#endif
int HOST = 0;
@@ -91,10 +89,8 @@
char timestamp[PATH_MAX];
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "/data/adb/adb-%s-%d", timestamp, getpid());
-
- int fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
+ std::string path = android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, getpid());
+ int fd = unix_open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
if (fd == -1) {
return;
}
@@ -322,28 +318,6 @@
#endif
}
-#if !ADB_HOST
-static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
- char header[5];
- if (msglen > 0xffff)
- msglen = 0xffff;
- snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
- WriteFdExactly(fd, header, 4);
- WriteFdExactly(fd, msg, msglen);
-}
-#endif
-
-#if ADB_HOST
-static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
- char header[9];
- if (msglen > 0xffff)
- msglen = 0xffff;
- snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
- WriteFdExactly(fd, header, 8);
- WriteFdExactly(fd, msg, msglen);
-}
-#endif // ADB_HOST
-
void send_connect(atransport *t)
{
D("Calling send_connect \n");
@@ -356,32 +330,6 @@
send_packet(cp, t);
}
-#if ADB_HOST
-static const char* connection_state_name(atransport *t)
-{
- if (t == NULL) {
- return "unknown";
- }
-
- switch(t->connection_state) {
- case CS_BOOTLOADER:
- return "bootloader";
- case CS_DEVICE:
- return "device";
- case CS_RECOVERY:
- return "recovery";
- case CS_SIDELOAD:
- return "sideload";
- case CS_OFFLINE:
- return "offline";
- case CS_UNAUTHORIZED:
- return "unauthorized";
- default:
- return "unknown";
- }
-}
-#endif // ADB_HOST
-
// qual_overwrite is used to overwrite a qualifier string. dst is a
// pointer to a char pointer. It is assumed that if *dst is non-NULL, it
// was malloc'ed and needs to freed. *dst will be set to a dup of src.
@@ -752,20 +700,11 @@
{
if (!strcmp(service, "list-forward")) {
// Create the list of forward redirections.
- int buffer_size = format_listeners(NULL, 0);
- // Add one byte for the trailing zero.
- char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
- if (buffer == nullptr) {
- sendfailmsg(reply_fd, "not enough memory");
- return 1;
- }
- (void) format_listeners(buffer, buffer_size + 1);
+ std::string listeners = format_listeners();
#if ADB_HOST
- send_msg_with_okay(reply_fd, buffer, buffer_size);
-#else
- send_msg_with_header(reply_fd, buffer, buffer_size);
+ SendOkay(reply_fd);
#endif
- free(buffer);
+ SendProtocolString(reply_fd, listeners);
return 1;
}
@@ -773,9 +712,9 @@
remove_all_listeners();
#if ADB_HOST
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
#endif
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
return 1;
}
@@ -800,19 +739,19 @@
if (createForward) {
// Check forward: parameter format: '<local>;<remote>'
if(remote == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
*remote++ = 0;
if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
} else {
// Check killforward: parameter format: '<local>'
if (local[0] == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
+ SendFail(reply_fd, "malformed forward spec");
return 1;
}
}
@@ -820,7 +759,7 @@
std::string error_msg;
transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
if (!transport) {
- sendfailmsg(reply_fd, error_msg.c_str());
+ SendFail(reply_fd, error_msg);
return 1;
}
@@ -833,9 +772,9 @@
if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
- WriteFdExactly(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
#endif
- WriteFdExactly(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
return 1;
}
@@ -851,7 +790,7 @@
break;
case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
}
- sendfailmsg(reply_fd, message.c_str());
+ SendFail(reply_fd, message);
return 1;
}
return 0;
@@ -862,7 +801,7 @@
if(!strcmp(service, "kill")) {
fprintf(stderr,"adb server killed by remote request\n");
fflush(stdout);
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
usb_cleanup();
exit(0);
}
@@ -892,25 +831,25 @@
if (transport) {
s->transport = transport;
- adb_write(reply_fd, "OKAY", 4);
+ SendOkay(reply_fd);
} else {
- sendfailmsg(reply_fd, error_msg.c_str());
+ SendFail(reply_fd, error_msg);
}
return 1;
}
// return a list of all connected devices
if (!strncmp(service, "devices", 7)) {
- char buffer[4096];
- int use_long = !strcmp(service+7, "-l");
- if (use_long || service[7] == 0) {
- memset(buffer, 0, sizeof(buffer));
- D("Getting device list \n");
- list_transports(buffer, sizeof(buffer), use_long);
- D("Wrote device list \n");
- send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+ bool long_listing = (strcmp(service+7, "-l") == 0);
+ if (long_listing || service[7] == 0) {
+ D("Getting device list...\n");
+ std::string device_list = list_transports(long_listing);
+ D("Sending device list...\n");
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, device_list);
return 0;
}
+ return 1;
}
// remove TCP transport
@@ -937,15 +876,15 @@
}
}
- send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, buffer);
return 0;
}
// returns our value for ADB_SERVER_VERSION
if (!strcmp(service, "version")) {
- char version[12];
- snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
- send_msg_with_okay(reply_fd, version, strlen(version));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
return 0;
}
@@ -955,7 +894,8 @@
if (transport && transport->serial) {
out = transport->serial;
}
- send_msg_with_okay(reply_fd, out, strlen(out));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, out);
return 0;
}
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
@@ -964,7 +904,8 @@
if (transport && transport->devpath) {
out = transport->devpath;
}
- send_msg_with_okay(reply_fd, out, strlen(out));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, out);
return 0;
}
// indicates a new emulator instance has started
@@ -977,8 +918,8 @@
if(!strncmp(service,"get-state",strlen("get-state"))) {
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
- const char *state = connection_state_name(transport);
- send_msg_with_okay(reply_fd, state, strlen(state));
+ SendOkay(reply_fd);
+ SendProtocolString(reply_fd, transport->connection_state_name());
return 0;
}
#endif // ADB_HOST
diff --git a/adb/adb.h b/adb/adb.h
index b8c6156..fd9d0e6 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -209,6 +209,8 @@
unsigned char token[TOKEN_SIZE];
fdevent auth_fde;
unsigned failed_auth_attempts;
+
+ const char* connection_state_name() const;
};
@@ -369,7 +371,6 @@
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
#endif
-int sendfailmsg(int fd, const char *reason);
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
void handle_online(atransport *t);
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 62f79fa..7bb8e4a 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -48,7 +48,6 @@
static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
char buf[5];
-
if (!ReadFdExactly(fd, buf, 4)) {
*error = perror_str("protocol fault (couldn't read status length)");
return false;
@@ -56,7 +55,7 @@
buf[4] = 0;
unsigned long len = strtoul(buf, 0, 16);
- s->resize(len + 1, '\0'); // Ensure NUL-termination.
+ s->resize(len, '\0');
if (!ReadFdExactly(fd, &(*s)[0], len)) {
*error = perror_str("protocol fault (couldn't read status message)");
return false;
@@ -136,9 +135,7 @@
service += transport_type;
}
- char tmp[5];
- snprintf(tmp, sizeof(tmp), "%04zx", service.size());
- if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) {
+ if (!SendProtocolString(fd, service)) {
*error = perror_str("write failure during connection");
adb_close(fd);
return -1;
@@ -156,7 +153,6 @@
bool adb_status(int fd, std::string* error) {
char buf[5];
-
if (!ReadFdExactly(fd, buf, 4)) {
*error = perror_str("protocol fault (couldn't read status)");
return false;
@@ -199,9 +195,7 @@
return -1;
}
- char tmp[5];
- snprintf(tmp, sizeof(tmp), "%04zx", service.size());
- if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
+ if(!SendProtocolString(fd, service)) {
*error = perror_str("write failure during connection");
adb_close(fd);
return -1;
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index d89f304..5ae6ec3 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -16,20 +16,37 @@
#define TRACE_TAG TRACE_RWX
-#include "sysdeps.h"
#include "adb_io.h"
#include <unistd.h>
+#include <base/stringprintf.h>
+
#include "adb_trace.h"
-#include "transport.h"
+#include "adb_utils.h"
+#include "sysdeps.h"
+
+bool SendProtocolString(int fd, const std::string& s) {
+ int length = s.size();
+ if (length > 0xffff) {
+ length = 0xffff;
+ }
+
+ return WriteFdFmt(fd, "%04x", length) && WriteFdExactly(fd, s);
+}
+
+bool SendOkay(int fd) {
+ return WriteFdExactly(fd, "OKAY", 4);
+}
+
+bool SendFail(int fd, const std::string& reason) {
+ return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
+}
bool ReadFdExactly(int fd, void* buf, size_t len) {
char* p = reinterpret_cast<char*>(buf);
-#if ADB_TRACE
size_t len0 = len;
-#endif
D("readx: fd=%d wanted=%zu\n", fd, len);
while (len > 0) {
@@ -47,12 +64,10 @@
}
}
-#if ADB_TRACE
D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
if (ADB_TRACING) {
dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
}
-#endif
return true;
}
@@ -61,12 +76,10 @@
const char* p = reinterpret_cast<const char*>(buf);
int r;
-#if ADB_TRACE
D("writex: fd=%d len=%d: ", fd, (int)len);
if (ADB_TRACING) {
dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
}
-#endif
while (len > 0) {
r = adb_write(fd, p, len);
@@ -90,6 +103,21 @@
return true;
}
-bool WriteStringFully(int fd, const char* str) {
+bool WriteFdExactly(int fd, const char* str) {
return WriteFdExactly(fd, str, strlen(str));
}
+
+bool WriteFdExactly(int fd, const std::string& str) {
+ return WriteFdExactly(fd, str.c_str(), str.size());
+}
+
+bool WriteFdFmt(int fd, const char* fmt, ...) {
+ std::string str;
+
+ va_list ap;
+ va_start(ap, fmt);
+ android::base::StringAppendV(&str, fmt, ap);
+ va_end(ap);
+
+ return WriteFdExactly(fd, str);
+}
diff --git a/adb/adb_io.h b/adb/adb_io.h
index 8d237ce..8d50a6d 100644
--- a/adb/adb_io.h
+++ b/adb/adb_io.h
@@ -17,9 +17,19 @@
#ifndef ADB_IO_H
#define ADB_IO_H
-#include <stdbool.h>
#include <sys/types.h>
+#include <string>
+
+// Sends the protocol "OKAY" message.
+bool SendOkay(int fd);
+
+// Sends the protocol "FAIL" message, with the given failure reason.
+bool SendFail(int fd, const std::string& reason);
+
+// Writes a protocol-format string; a four hex digit length followed by the string data.
+bool SendProtocolString(int fd, const std::string& s);
+
/*
* Reads exactly len bytes from fd into buf.
*
@@ -37,9 +47,13 @@
* completed. If the other end of the fd (such as in a socket, pipe, or fifo),
* is closed, errno will be set to 0.
*/
-bool WriteFdExactly(int fd, const void *buf, size_t len);
+bool WriteFdExactly(int fd, const void* buf, size_t len);
-/* Same as WriteFdExactly, but with an implicit len = strlen(buf). */
-bool WriteStringFully(int fd, const char* str);
+// Same as above, but for strings.
+bool WriteFdExactly(int fd, const char* s);
+bool WriteFdExactly(int fd, const std::string& s);
+
+// Same as above, but formats the string to send.
+bool WriteFdFmt(int fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
#endif /* ADB_IO_H */
diff --git a/adb/adb_io_test.cpp b/adb/adb_io_test.cpp
index da340b2..8fd5cbf 100644
--- a/adb/adb_io_test.cpp
+++ b/adb/adb_io_test.cpp
@@ -139,16 +139,29 @@
ASSERT_EQ(ENOSPC, errno);
}
-TEST(io, WriteStringFully) {
+TEST(io, WriteFdExactly_string) {
const char str[] = "Foobar";
TemporaryFile tf;
ASSERT_NE(-1, tf.fd);
// Test writing a partial string to the file.
- ASSERT_TRUE(WriteStringFully(tf.fd, str)) << strerror(errno);
+ ASSERT_TRUE(WriteFdExactly(tf.fd, str)) << strerror(errno);
ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
std::string s;
ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
EXPECT_STREQ(str, s.c_str());
}
+
+TEST(io, WriteFdFmt) {
+ TemporaryFile tf;
+ ASSERT_NE(-1, tf.fd);
+
+ // Test writing a partial string to the file.
+ ASSERT_TRUE(WriteFdFmt(tf.fd, "Foo%s%d", "bar", 123)) << strerror(errno);
+ ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
+
+ std::string s;
+ ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s));
+ EXPECT_STREQ("Foobar123", s.c_str());
+}
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index a1a5ddb..3fc4719 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <base/stringprintf.h>
+
#include "sysdeps.h"
#include "transport.h"
@@ -143,49 +145,17 @@
return -1;
}
-// 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.
-int format_listeners(char* buf, size_t buflen)
-{
- alistener* l;
- int result = 0;
- for (l = listener_list.next; l != &listener_list; l = l->next) {
+// Write the list of current listeners (network redirections) into a string.
+std::string format_listeners() {
+ std::string result;
+ for (alistener* 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;
+ if (l->connect_to[0] == '*') {
+ continue;
}
+ // <device-serial> " " <local-name> " " <remote-name> "\n"
+ android::base::StringAppendF(&result, "%s %s %s\n",
+ l->transport->serial, l->local_name, l->connect_to);
}
return result;
}
@@ -215,13 +185,13 @@
}
}
-install_status_t install_listener(const char *local_name,
+install_status_t install_listener(const std::string& local_name,
const char *connect_to,
atransport* transport,
int no_rebind)
{
for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
- if (strcmp(local_name, l->local_name) == 0) {
+ if (local_name == l->local_name) {
char* cto;
/* can't repurpose a smartsocket */
@@ -256,7 +226,7 @@
goto nomem;
}
- listener->local_name = strdup(local_name);
+ listener->local_name = strdup(local_name.c_str());
if (listener->local_name == nullptr) {
goto nomem;
}
@@ -266,9 +236,9 @@
goto nomem;
}
- listener->fd = local_name_to_fd(local_name);
+ listener->fd = local_name_to_fd(listener->local_name);
if (listener->fd < 0) {
- printf("cannot bind '%s': %s\n", local_name, strerror(errno));
+ printf("cannot bind '%s': %s\n", listener->local_name, strerror(errno));
free(listener->local_name);
free(listener->connect_to);
free(listener);
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
index f55fdee..67168ae 100644
--- a/adb/adb_listeners.h
+++ b/adb/adb_listeners.h
@@ -19,6 +19,8 @@
#include "adb.h"
+#include <string>
+
// error/status codes for install_listener.
enum install_status_t {
INSTALL_STATUS_OK = 0,
@@ -34,12 +36,12 @@
void listener_event_func(int _fd, unsigned ev, void *_l);
void ss_listener_event_func(int _fd, unsigned ev, void *_l);
-install_status_t install_listener(const char *local_name,
- const char *connect_to,
+install_status_t install_listener(const std::string& local_name,
+ const char* connect_to,
atransport* transport,
int no_rebind);
-int format_listeners(char* buf, size_t buflen);
+std::string format_listeners();
install_status_t remove_listener(const char* local_name, atransport* transport);
void remove_all_listeners(void);
diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
index 5acaf80..3f88d13 100644
--- a/adb/adb_main.cpp
+++ b/adb/adb_main.cpp
@@ -28,6 +28,8 @@
#include "adb_listeners.h"
#include "transport.h"
+#include <base/stringprintf.h>
+
#if !ADB_HOST
#include <getopt.h>
#include <sys/prctl.h>
@@ -157,16 +159,6 @@
}
#endif /* ADB_HOST */
-/* Constructs a local name of form tcp:port.
- * target_str points to the target string, it's content will be overwritten.
- * target_size is the capacity of the target string.
- * server_port is the port number to use for the local name.
- */
-void build_local_name(char* target_str, size_t target_size, int server_port)
-{
- snprintf(target_str, target_size, "tcp:%d", server_port);
-}
-
void start_logging(void)
{
#if defined(_WIN32)
@@ -238,9 +230,8 @@
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
adb_auth_init();
- char local_name[30];
- build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
+ std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
+ if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
exit(1);
}
#else
@@ -295,15 +286,14 @@
D("Local port disabled\n");
} else {
- char local_name[30];
if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) {
// b/12587913: fix setcon to allow const pointers
if (setcon((char *)root_seclabel) < 0) {
exit(1);
}
}
- build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
+ std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
+ if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
exit(1);
}
}
@@ -368,29 +358,25 @@
}
#endif
+// TODO(danalbert): Split this file up into adb_main.cpp and adbd_main.cpp.
int main(int argc, char **argv) {
#if ADB_HOST
+ // adb client/server
adb_sysdeps_init();
-#else
- close_stdin();
-#endif
adb_trace_init();
-
-#if ADB_HOST
D("Handling commandline()\n");
return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
#else
- /* If adbd runs inside the emulator this will enable adb tracing via
- * adb-debug qemud service in the emulator. */
- adb_qemu_trace_init();
+ // adbd
while (true) {
- int c;
- int option_index = 0;
static struct option opts[] = {
- {"root_seclabel", required_argument, 0, 's' },
- {"device_banner", required_argument, 0, 'b' }
+ {"root_seclabel", required_argument, nullptr, 's'},
+ {"device_banner", required_argument, nullptr, 'b'},
+ {"version", no_argument, nullptr, 'v'},
};
- c = getopt_long(argc, argv, "", opts, &option_index);
+
+ int option_index = 0;
+ int c = getopt_long(argc, argv, "", opts, &option_index);
if (c == -1)
break;
switch (c) {
@@ -400,11 +386,24 @@
case 'b':
adb_device_banner = optarg;
break;
+ case 'v':
+ printf("Android Debug Bridge Daemon version %d.%d.%d %s\n",
+ ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
+ ADB_REVISION);
+ return 0;
default:
break;
}
}
+ close_stdin();
+
+ adb_trace_init();
+
+ /* If adbd runs inside the emulator this will enable adb tracing via
+ * adb-debug qemud service in the emulator. */
+ adb_qemu_trace_init();
+
D("Handling main()\n");
return adb_main(0, DEFAULT_ADB_PORT);
#endif
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
index 32b6ae4..63d4151 100644
--- a/adb/adb_trace.h
+++ b/adb/adb_trace.h
@@ -23,9 +23,6 @@
#include <stdio.h>
#endif
-/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */
-#define ADB_TRACE 1
-
/* IMPORTANT: if you change the following list, don't
* forget to update the corresponding 'tags' table in
* the adb_trace_init() function implemented in adb.c
@@ -45,8 +42,6 @@
TRACE_FDEVENT,
} ;
-#if ADB_TRACE
-
#if !ADB_HOST
/*
* When running inside the emulator, guest's adbd can connect to 'adb-debug'
@@ -97,19 +92,6 @@
errno = save_errno; \
} \
} while (0)
-# define DD(...) \
- do { \
- int save_errno = errno; \
- adb_mutex_lock(&D_lock); \
- fprintf(stderr, "%16s: %5d:%5lu | ", \
- __FUNCTION__, \
- getpid(), adb_thread_id()); \
- errno = save_errno; \
- fprintf(stderr, __VA_ARGS__ ); \
- fflush(stderr); \
- adb_mutex_unlock(&D_lock); \
- errno = save_errno; \
- } while (0)
#else
# define D(...) \
do { \
@@ -129,19 +111,6 @@
__VA_ARGS__ ); \
} \
} while (0)
-# define DD(...) \
- do { \
- __android_log_print( \
- ANDROID_LOG_INFO, \
- __FUNCTION__, \
- __VA_ARGS__ ); \
- } while (0)
#endif /* ADB_HOST */
-#else
-# define D(...) ((void)0)
-# define DR(...) ((void)0)
-# define DD(...) ((void)0)
-# define ADB_TRACING 0
-#endif /* ADB_TRACE */
#endif /* __ADB_TRACE_H */
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index f10c143..0ce5ece 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define TRACE_TAG TRACE_ADB
+
#include "adb_utils.h"
#include <stdlib.h>
@@ -21,6 +23,11 @@
#include <sys/types.h>
#include <unistd.h>
+#include <algorithm>
+
+#include <base/stringprintf.h>
+
+#include "adb_trace.h"
#include "sysdeps.h"
bool getcwd(std::string* s) {
@@ -50,3 +57,25 @@
result.push_back('\'');
return result;
}
+
+void dump_hex(const void* data, size_t byte_count) {
+ byte_count = std::min(byte_count, size_t(16));
+
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
+
+ std::string line;
+ for (size_t i = 0; i < byte_count; ++i) {
+ android::base::StringAppendF(&line, "%02x", p[i]);
+ }
+ line.push_back(' ');
+
+ for (size_t i = 0; i < byte_count; ++i) {
+ int c = p[i];
+ if (c < 32 || c > 127) {
+ c = '.';
+ }
+ line.push_back(c);
+ }
+
+ DR("%s\n", line.c_str());
+}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 4b64afa..84f7d0c 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -24,4 +24,6 @@
std::string escape_arg(const std::string& s);
+void dump_hex(const void* ptr, size_t byte_count);
+
#endif
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 4941689..1d71975 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -47,14 +47,9 @@
#include "adb_utils.h"
#include "file_sync_service.h"
-static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...);
-
-static int install_app(transport_type transport, const char* serial, int argc,
- const char** argv);
-static int install_multiple_app(transport_type transport, const char* serial, int argc,
- const char** argv);
-static int uninstall_app(transport_type transport, const char* serial, int argc,
- const char** argv);
+static int install_app(transport_type t, const char* serial, int argc, const char** argv);
+static int install_multiple_app(transport_type t, const char* serial, int argc, const char** argv);
+static int uninstall_app(transport_type t, const char* serial, int argc, const char** argv);
static std::string gProductOutPath;
extern int gListenAll;
@@ -71,8 +66,8 @@
}
static void version(FILE* out) {
- fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
- ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
+ fprintf(out, "Android Debug Bridge version %d.%d.%d %s\n", ADB_VERSION_MAJOR,
+ ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_REVISION);
}
static void help() {
@@ -490,17 +485,8 @@
printf("\n");
}
- // TODO: should this be adb_status?
- char buf[5];
- if(!ReadFdExactly(fd, buf, 4)){
- fprintf(stderr,"* error reading response *\n");
- adb_close(fd);
- return -1;
- }
- if(memcmp(buf, "OKAY", 4)) {
- buf[4] = 0;
- fprintf(stderr,"* error response '%s' *\n", buf);
- adb_close(fd);
+ if (!adb_status(fd, &error)) {
+ fprintf(stderr,"* error response '%s' *\n", error.c_str());
return -1;
}
@@ -687,7 +673,31 @@
#endif /* !defined(_WIN32) */
}
-static int send_shell_command(transport_type transport, const char* serial,
+static bool wait_for_device(const char* service, transport_type t, const char* serial) {
+ // Was the caller vague about what they'd like us to wait for?
+ // If so, check they weren't more specific in their choice of transport type.
+ if (strcmp(service, "wait-for-device") == 0) {
+ if (t == kTransportUsb) {
+ service = "wait-for-usb";
+ } else if (t == kTransportLocal) {
+ service = "wait-for-local";
+ } else {
+ service = "wait-for-any";
+ }
+ }
+
+ std::string cmd = format_host_command(service, t, serial);
+ std::string error;
+ if (adb_command(cmd, &error)) {
+ D("failure: %s *\n", error.c_str());
+ fprintf(stderr,"error: %s\n", error.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+static int send_shell_command(transport_type transport_type, const char* serial,
const std::string& command) {
int fd;
while (true) {
@@ -698,7 +708,7 @@
}
fprintf(stderr,"- waiting for device -\n");
adb_sleep_ms(1000);
- do_cmd(transport, serial, "wait-for-device", 0);
+ wait_for_device("wait-for-device", transport_type, serial);
}
read_and_dump(fd);
@@ -938,9 +948,7 @@
return 0;
}
-int adb_commandline(int argc, const char **argv)
-{
- char buf[4096];
+int adb_commandline(int argc, const char **argv) {
int no_daemon = 0;
int is_daemon = 0;
int is_server = 0;
@@ -1081,27 +1089,13 @@
/* handle wait-for-* prefix */
if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
const char* service = argv[0];
- if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
- if (ttype == kTransportUsb) {
- service = "wait-for-usb";
- } else if (ttype == kTransportLocal) {
- service = "wait-for-local";
- } else {
- service = "wait-for-any";
- }
- }
- std::string cmd = format_host_command(service, ttype, serial);
- std::string error;
- if (adb_command(cmd, &error)) {
- D("failure: %s *\n", error.c_str());
- fprintf(stderr,"error: %s\n", error.c_str());
+ if (!wait_for_device(service, ttype, serial)) {
return 1;
}
- /* Allow a command to be run after wait-for-device,
- * e.g. 'adb wait-for-device shell'.
- */
+ // Allow a command to be run after wait-for-device,
+ // e.g. 'adb wait-for-device shell'.
if (argc == 1) {
return 0;
}
@@ -1168,11 +1162,12 @@
}
std::string cmd = "shell:";
- cmd += argv[1];
- argc -= 2;
- argv += 2;
+ --argc;
+ ++argv;
while (argc-- > 0) {
- cmd += " " + escape_arg(*argv++);
+ // We don't escape here, just like ssh(1). http://b/20564385.
+ cmd += *argv++;
+ if (*argv) cmd += " ";
}
while (true) {
@@ -1194,7 +1189,7 @@
if (persist) {
fprintf(stderr,"\n- waiting for device -\n");
adb_sleep_ms(1000);
- do_cmd(ttype, serial, "wait-for-device", 0);
+ wait_for_device("wait-for-device", ttype, serial);
} else {
if (h) {
printf("\x1b[0m");
@@ -1270,11 +1265,11 @@
}
else if (!strcmp(argv[0], "bugreport")) {
if (argc != 1) return usage();
- do_cmd(ttype, serial, "shell", "bugreport", 0);
- return 0;
+ return send_shell_command(ttype, serial, "shell:bugreport");
}
/* adb_command() wrapper commands */
else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
+ std::string cmd;
char host_prefix[64];
char reverse = (char) !strcmp(argv[0], "reverse");
char remove = 0;
@@ -1332,31 +1327,27 @@
// Implement forward --remove-all
else if (remove_all) {
- if (argc != 1)
- return usage();
- snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);
+ if (argc != 1) return usage();
+ cmd = android::base::StringPrintf("%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]);
+ if (argc != 2) return usage();
+ cmd = android::base::StringPrintf("%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]);
+ else {
+ if (argc != 3) return usage();
+ const char* command = no_rebind ? "forward:norebind" : "forward";
+ cmd = android::base::StringPrintf("%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
}
std::string error;
- if (adb_command(buf, &error)) {
- fprintf(stderr,"error: %s\n", error.c_str());
+ if (adb_command(cmd, &error)) {
+ fprintf(stderr, "error: %s\n", error.c_str());
return 1;
}
return 0;
@@ -1494,42 +1485,6 @@
return 1;
}
-#define MAX_ARGV_LENGTH 16
-static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...)
-{
- const char *argv[MAX_ARGV_LENGTH];
- int argc;
- va_list ap;
-
- va_start(ap, cmd);
- argc = 0;
-
- if (serial) {
- argv[argc++] = "-s";
- argv[argc++] = serial;
- } else if (ttype == kTransportUsb) {
- argv[argc++] = "-d";
- } else if (ttype == kTransportLocal) {
- argv[argc++] = "-e";
- }
-
- argv[argc++] = cmd;
- while(argc < MAX_ARGV_LENGTH &&
- (argv[argc] = va_arg(ap, char*)) != 0) argc++;
- assert(argc < MAX_ARGV_LENGTH);
- va_end(ap);
-
-#if 0
- int n;
- fprintf(stderr,"argc = %d\n",argc);
- for(n = 0; n < argc; n++) {
- fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
- }
-#endif
-
- return adb_commandline(argc, argv);
-}
-
static int pm_command(transport_type transport, const char* serial,
int argc, const char** argv)
{
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 1eaee73..87702b0 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -90,9 +90,7 @@
return true;
}
if (remount(partition, ro)) {
- char buf[200];
- snprintf(buf, sizeof(buf), "remount of %s failed: %s\n", partition, strerror(errno));
- WriteStringFully(fd, buf);
+ WriteFdFmt(fd, "remount of %s failed: %s\n", partition, strerror(errno));
return false;
}
return true;
@@ -102,7 +100,7 @@
char prop_buf[PROPERTY_VALUE_MAX];
if (getuid() != 0) {
- WriteStringFully(fd, "Not running as root. Try \"adb root\" first.\n");
+ WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");
adb_close(fd);
return;
}
@@ -121,19 +119,16 @@
if (system_verified || vendor_verified) {
// Allow remount but warn of likely bad effects
bool both = system_verified && vendor_verified;
- char buffer[200];
- snprintf(buffer, sizeof(buffer),
- "dm_verity is enabled on the %s%s%s partition%s.\n",
- system_verified ? "system" : "",
- both ? " and " : "",
- vendor_verified ? "vendor" : "",
- both ? "s" : "");
- WriteStringFully(fd, buffer);
- snprintf(buffer, sizeof(buffer),
- "Use \"adb disable-verity\" to disable verity.\n"
- "If you do not, remount may succeed, however, you will still "
- "not be able to write to these volumes.\n");
- WriteStringFully(fd, buffer);
+ WriteFdFmt(fd,
+ "dm_verity is enabled on the %s%s%s partition%s.\n",
+ system_verified ? "system" : "",
+ both ? " and " : "",
+ vendor_verified ? "vendor" : "",
+ both ? "s" : "");
+ WriteFdExactly(fd,
+ "Use \"adb disable-verity\" to disable verity.\n"
+ "If you do not, remount may succeed, however, you will still "
+ "not be able to write to these volumes.\n");
}
bool success = true;
@@ -141,7 +136,7 @@
success &= remount_partition(fd, "/vendor", &vendor_ro);
success &= remount_partition(fd, "/oem", &oem_ro);
- WriteStringFully(fd, success ? "remount succeeded\n" : "remount failed\n");
+ WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
adb_close(fd);
}
diff --git a/adb/services.cpp b/adb/services.cpp
index e6c84a4..1847447 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -31,10 +31,11 @@
#include <unistd.h>
#endif
+#include <base/file.h>
#include <base/stringprintf.h>
+#include <base/strings.h>
#if !ADB_HOST
-#include "base/file.h"
#include "cutils/android_reboot.h"
#include "cutils/properties.h"
#endif
@@ -62,74 +63,54 @@
#if !ADB_HOST
-void restart_root_service(int fd, void *cookie)
-{
- char buf[100];
- char value[PROPERTY_VALUE_MAX];
-
+void restart_root_service(int fd, void *cookie) {
if (getuid() == 0) {
- snprintf(buf, sizeof(buf), "adbd is already running as root\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "adbd is already running as root\n");
adb_close(fd);
} else {
+ char value[PROPERTY_VALUE_MAX];
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") != 0) {
- snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
adb_close(fd);
return;
}
property_set("service.adb.root", "1");
- snprintf(buf, sizeof(buf), "restarting adbd as root\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "restarting adbd as root\n");
adb_close(fd);
}
}
-void restart_unroot_service(int fd, void *cookie)
-{
- char buf[100];
-
+void restart_unroot_service(int fd, void *cookie) {
if (getuid() != 0) {
- snprintf(buf, sizeof(buf), "adbd not running as root\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "adbd not running as root\n");
adb_close(fd);
} else {
property_set("service.adb.root", "0");
- snprintf(buf, sizeof(buf), "restarting adbd as non root\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "restarting adbd as non root\n");
adb_close(fd);
}
}
-void restart_tcp_service(int fd, void *cookie)
-{
- char buf[100];
- char value[PROPERTY_VALUE_MAX];
+void restart_tcp_service(int fd, void *cookie) {
int port = (int) (uintptr_t) cookie;
-
if (port <= 0) {
- snprintf(buf, sizeof(buf), "invalid port\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdFmt(fd, "invalid port %d\n", port);
adb_close(fd);
return;
}
+ char value[PROPERTY_VALUE_MAX];
snprintf(value, sizeof(value), "%d", port);
property_set("service.adb.tcp.port", value);
- snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port);
adb_close(fd);
}
-void restart_usb_service(int fd, void *cookie)
-{
- char buf[100];
-
+void restart_usb_service(int fd, void *cookie) {
property_set("service.adb.tcp.port", "0");
- snprintf(buf, sizeof(buf), "restarting in USB mode\n");
- WriteFdExactly(fd, buf, strlen(buf));
+ WriteFdExactly(fd, "restarting in USB mode\n");
adb_close(fd);
}
@@ -142,13 +123,11 @@
reboot_arg = "sideload";
}
- char buf[100];
// It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
// in the command file.
if (strcmp(reboot_arg, "sideload") == 0) {
if (getuid() != 0) {
- snprintf(buf, sizeof(buf), "'adb root' is required for 'adb reboot sideload'.\n");
- WriteStringFully(fd, buf);
+ WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
return false;
}
@@ -174,15 +153,13 @@
char property_val[PROPERTY_VALUE_MAX];
int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
if (ret >= static_cast<int>(sizeof(property_val))) {
- snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
- WriteStringFully(fd, buf);
+ WriteFdFmt(fd, "reboot string too long: %d\n", ret);
return false;
}
ret = property_set(ANDROID_RB_PROPERTY, property_val);
if (ret < 0) {
- snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
- WriteStringFully(fd, buf);
+ WriteFdFmt(fd, "reboot failed: %d\n", ret);
return false;
}
@@ -208,7 +185,7 @@
const char* command = reinterpret_cast<const char*>(arg);
if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
- sendfailmsg(fd, "not a reverse forwarding command");
+ SendFail(fd, "not a reverse forwarding command");
}
free(arg);
adb_close(fd);
@@ -551,9 +528,9 @@
std::string error_msg = "unknown error";
atransport* t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &error_msg);
if (t != 0) {
- WriteFdExactly(fd, "OKAY", 4);
+ SendOkay(fd);
} else {
- sendfailmsg(fd, error_msg.c_str());
+ SendFail(fd, error_msg);
}
if (sinfo->serial)
@@ -563,35 +540,31 @@
D("wait_for_state is done\n");
}
-static void connect_device(char* host, char* buffer, int buffer_size)
-{
- int port, fd;
- char* portstr = strchr(host, ':');
- char hostbuf[100];
- char serial[100];
- int ret;
-
- strncpy(hostbuf, host, sizeof(hostbuf) - 1);
- if (portstr) {
- if (portstr - host >= (ptrdiff_t)sizeof(hostbuf)) {
- snprintf(buffer, buffer_size, "bad host name %s", host);
- return;
- }
- // zero terminate the host at the point we found the colon
- hostbuf[portstr - host] = 0;
- if (sscanf(portstr + 1, "%d", &port) != 1) {
- snprintf(buffer, buffer_size, "bad port number %s", portstr);
- return;
- }
- } else {
- port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
+static void connect_device(const std::string& host, std::string* response) {
+ if (host.empty()) {
+ *response = "empty host name";
+ return;
}
- snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
+ std::vector<std::string> pieces = android::base::Split(host, ":");
+ const std::string& hostname = pieces[0];
- fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10);
+ int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
+ if (pieces.size() > 1) {
+ if (sscanf(pieces[1].c_str(), "%d", &port) != 1) {
+ *response = android::base::StringPrintf("bad port number %s", pieces[1].c_str());
+ return;
+ }
+ }
+
+ // This may look like we're putting 'host' back together,
+ // but we're actually inserting the default port if necessary.
+ std::string serial = android::base::StringPrintf("%s:%d", hostname.c_str(), port);
+
+ int fd = socket_network_client_timeout(hostname.c_str(), port, SOCK_STREAM, 10);
if (fd < 0) {
- snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
+ *response = android::base::StringPrintf("unable to connect to %s:%d",
+ hostname.c_str(), port);
return;
}
@@ -599,85 +572,74 @@
close_on_exec(fd);
disable_tcp_nagle(fd);
- ret = register_socket_transport(fd, serial, port, 0);
+ int ret = register_socket_transport(fd, serial.c_str(), port, 0);
if (ret < 0) {
adb_close(fd);
- snprintf(buffer, buffer_size, "already connected to %s", serial);
+ *response = android::base::StringPrintf("already connected to %s", serial.c_str());
} else {
- snprintf(buffer, buffer_size, "connected to %s", serial);
+ *response = android::base::StringPrintf("connected to %s", serial.c_str());
}
}
-void connect_emulator(char* port_spec, char* buffer, int buffer_size)
-{
- char* port_separator = strchr(port_spec, ',');
- if (!port_separator) {
- snprintf(buffer, buffer_size,
- "unable to parse '%s' as <console port>,<adb port>",
- port_spec);
+void connect_emulator(const std::string& port_spec, std::string* response) {
+ std::vector<std::string> pieces = android::base::Split(port_spec, ",");
+ if (pieces.size() != 2) {
+ *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>",
+ port_spec.c_str());
return;
}
- // Zero-terminate console port and make port_separator point to 2nd port.
- *port_separator++ = 0;
- int console_port = strtol(port_spec, NULL, 0);
- int adb_port = strtol(port_separator, NULL, 0);
- if (!(console_port > 0 && adb_port > 0)) {
- *(port_separator - 1) = ',';
- snprintf(buffer, buffer_size,
- "Invalid port numbers: Expected positive numbers, got '%s'",
- port_spec);
+ int console_port = strtol(pieces[0].c_str(), NULL, 0);
+ int adb_port = strtol(pieces[1].c_str(), NULL, 0);
+ if (console_port <= 0 || adb_port <= 0) {
+ *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str());
return;
}
- /* Check if the emulator is already known.
- * Note: There's a small but harmless race condition here: An emulator not
- * present just yet could be registered by another invocation right
- * after doing this check here. However, local_connect protects
- * against double-registration too. From here, a better error message
- * can be produced. In the case of the race condition, the very specific
- * error message won't be shown, but the data doesn't get corrupted. */
+ // Check if the emulator is already known.
+ // Note: There's a small but harmless race condition here: An emulator not
+ // present just yet could be registered by another invocation right
+ // after doing this check here. However, local_connect protects
+ // against double-registration too. From here, a better error message
+ // can be produced. In the case of the race condition, the very specific
+ // error message won't be shown, but the data doesn't get corrupted.
atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
- if (known_emulator != NULL) {
- snprintf(buffer, buffer_size,
- "Emulator on port %d already registered.", adb_port);
+ if (known_emulator != nullptr) {
+ *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port);
return;
}
- /* Check if more emulators can be registered. Similar unproblematic
- * race condition as above. */
+ // Check if more emulators can be registered. Similar unproblematic
+ // race condition as above.
int candidate_slot = get_available_local_transport_index();
if (candidate_slot < 0) {
- snprintf(buffer, buffer_size, "Cannot accept more emulators.");
+ *response = "Cannot accept more emulators";
return;
}
- /* Preconditions met, try to connect to the emulator. */
+ // Preconditions met, try to connect to the emulator.
if (!local_connect_arbitrary_ports(console_port, adb_port)) {
- snprintf(buffer, buffer_size,
- "Connected to emulator on ports %d,%d", console_port, adb_port);
+ *response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
+ console_port, adb_port);
} else {
- snprintf(buffer, buffer_size,
- "Could not connect to emulator on ports %d,%d",
- console_port, adb_port);
+ *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d",
+ console_port, adb_port);
}
}
static void connect_service(int fd, void* cookie)
{
- char buf[4096];
- char resp[4096];
char *host = reinterpret_cast<char*>(cookie);
+ std::string response;
if (!strncmp(host, "emu:", 4)) {
- connect_emulator(host + 4, buf, sizeof(buf));
+ connect_emulator(host + 4, &response);
} else {
- connect_device(host, buf, sizeof(buf));
+ connect_device(host, &response);
}
// Send response for emulator and device
- snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf);
- WriteFdExactly(fd, resp, strlen(resp));
+ SendProtocolString(fd, response);
adb_close(fd);
}
#endif
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index b75ed4c..cc42bc0 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -21,13 +21,13 @@
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
-#include <stdbool.h>
#include <stdio.h>
#include <sys/stat.h>
#include "cutils/properties.h"
#include "adb.h"
+#include "adb_io.h"
#include "ext4_sb.h"
#include "fs_mgr.h"
#include "remount_service.h"
@@ -41,18 +41,6 @@
static const bool kAllowDisableVerity = false;
#endif
-__attribute__((__format__(printf, 2, 3))) __nonnull((2))
-static void write_console(int fd, const char* format, ...)
-{
- char buffer[256];
- va_list args;
- va_start (args, format);
- vsnprintf (buffer, sizeof(buffer), format, args);
- va_end (args);
-
- adb_write(fd, buffer, strnlen(buffer, sizeof(buffer)));
-}
-
static int get_target_device_size(int fd, const char *blk_device,
uint64_t *device_size)
{
@@ -64,18 +52,18 @@
data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC);
if (data_device < 0) {
- write_console(fd, "Error opening block device (%s)\n", strerror(errno));
+ WriteFdFmt(fd, "Error opening block device (%s)\n", strerror(errno));
return -1;
}
if (lseek64(data_device, 1024, SEEK_SET) < 0) {
- write_console(fd, "Error seeking to superblock\n");
+ WriteFdFmt(fd, "Error seeking to superblock\n");
adb_close(data_device);
return -1;
}
if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) {
- write_console(fd, "Error reading superblock\n");
+ WriteFdFmt(fd, "Error reading superblock\n");
adb_close(data_device);
return -1;
}
@@ -99,73 +87,64 @@
int retval = -1;
if (make_block_device_writable(block_device)) {
- write_console(fd, "Could not make block device %s writable (%s).\n",
- block_device, strerror(errno));
+ WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
+ block_device, strerror(errno));
goto errout;
}
device = adb_open(block_device, O_RDWR | O_CLOEXEC);
if (device == -1) {
- write_console(fd, "Could not open block device %s (%s).\n",
- block_device, strerror(errno));
- write_console(fd, "Maybe run adb remount?\n");
+ WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno));
+ WriteFdFmt(fd, "Maybe run adb remount?\n");
goto errout;
}
// find the start of the verity metadata
if (get_target_device_size(fd, (char*)block_device, &device_length) < 0) {
- write_console(fd, "Could not get target device size.\n");
+ WriteFdFmt(fd, "Could not get target device size.\n");
goto errout;
}
if (lseek64(device, device_length, SEEK_SET) < 0) {
- write_console(fd,
- "Could not seek to start of verity metadata block.\n");
+ WriteFdFmt(fd, "Could not seek to start of verity metadata block.\n");
goto errout;
}
// check the magic number
- if (adb_read(device, &magic_number, sizeof(magic_number))
- != sizeof(magic_number)) {
- write_console(fd, "Couldn't read magic number!\n");
+ if (adb_read(device, &magic_number, sizeof(magic_number)) != sizeof(magic_number)) {
+ WriteFdFmt(fd, "Couldn't read magic number!\n");
goto errout;
}
if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) {
- write_console(fd, "Verity already disabled on %s\n", mount_point);
+ WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
goto errout;
}
if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) {
- write_console(fd, "Verity already enabled on %s\n", mount_point);
+ WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
goto errout;
}
if (magic_number != VERITY_METADATA_MAGIC_NUMBER
&& magic_number != VERITY_METADATA_MAGIC_DISABLE) {
- write_console(fd,
- "Couldn't find verity metadata at offset %" PRIu64 "!\n",
- device_length);
+ WriteFdFmt(fd, "Couldn't find verity metadata at offset %" PRIu64 "!\n", device_length);
goto errout;
}
if (lseek64(device, device_length, SEEK_SET) < 0) {
- write_console(fd,
- "Could not seek to start of verity metadata block.\n");
+ WriteFdFmt(fd, "Could not seek to start of verity metadata block.\n");
goto errout;
}
if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) {
- write_console(
- fd, "Could not set verity %s flag on device %s with error %s\n",
- enable ? "enabled" : "disabled",
- block_device, strerror(errno));
+ WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n",
+ enable ? "enabled" : "disabled",
+ block_device, strerror(errno));
goto errout;
}
- write_console(fd, "Verity %s on %s\n",
- enable ? "enabled" : "disabled",
- mount_point);
+ WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
retval = 0;
errout:
if (device != -1)
@@ -184,14 +163,13 @@
property_get("ro.secure", propbuf, "0");
if (strcmp(propbuf, "1")) {
- write_console(fd, "verity not enabled - ENG build\n");
+ WriteFdFmt(fd, "verity not enabled - ENG build\n");
goto errout;
}
property_get("ro.debuggable", propbuf, "0");
if (strcmp(propbuf, "1")) {
- write_console(
- fd, "verity cannot be disabled/enabled - USER build\n");
+ WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
goto errout;
}
@@ -201,8 +179,7 @@
fstab = fs_mgr_read_fstab(fstab_filename);
if (!fstab) {
- write_console(fd, "Failed to open %s\nMaybe run adb root?\n",
- fstab_filename);
+ WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename);
goto errout;
}
@@ -218,12 +195,11 @@
}
if (any_changed) {
- write_console(
- fd, "Now reboot your device for settings to take effect\n");
+ WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
}
} else {
- write_console(fd, "%s-verity only works for userdebug builds\n",
- enable ? "enable" : "disable");
+ WriteFdFmt(fd, "%s-verity only works for userdebug builds\n",
+ enable ? "enable" : "disable");
}
errout:
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index f468029..32ca17d 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -37,23 +37,6 @@
static void local_socket_close_locked(asocket *s);
-int sendfailmsg(int fd, const char *reason)
-{
- char buf[9];
- int len;
- len = strlen(reason);
- if (len > 0xffff) {
- len = 0xffff;
- }
-
- snprintf(buf, sizeof buf, "FAIL%04x", len);
- if (!WriteFdExactly(fd, buf, 8)) {
- return -1;
- }
-
- return WriteFdExactly(fd, reason, len) ? 0 : -1;
-}
-
static unsigned local_socket_next_id = 1;
static asocket local_socket_list = {
@@ -608,7 +591,7 @@
s->ready = local_socket_ready;
s->shutdown = NULL;
s->close = local_socket_close;
- adb_write(s->fd, "OKAY", 4);
+ SendOkay(s->fd);
s->ready(s);
}
@@ -620,11 +603,11 @@
s->ready = local_socket_ready;
s->shutdown = NULL;
s->close = local_socket_close;
- sendfailmsg(s->fd, "closed");
+ SendFail(s->fd, "closed");
s->close(s);
}
-unsigned unhex(unsigned char *s, int len)
+static unsigned unhex(unsigned char *s, int len)
{
unsigned n = 0, c;
@@ -654,6 +637,8 @@
return n;
}
+#if ADB_HOST
+
#define PREFIX(str) { str, sizeof(str) - 1 }
static const struct prefix_struct {
const char *str;
@@ -670,7 +655,7 @@
skipping over the 'serial' parameter in the ADB protocol,
where parameter string may be a host:port string containing
the protocol delimiter (colon). */
-char *skip_host_serial(char *service) {
+static char *skip_host_serial(char *service) {
char *first_colon, *serial_end;
int i;
@@ -698,6 +683,8 @@
return serial_end;
}
+#endif // ADB_HOST
+
static int smart_socket_enqueue(asocket *s, apacket *p)
{
unsigned len;
@@ -799,7 +786,7 @@
s2 = create_host_service_socket(service, serial);
if(s2 == 0) {
D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
- sendfailmsg(s->peer->fd, "unknown host service");
+ SendFail(s->peer->fd, "unknown host service");
goto fail;
}
@@ -810,7 +797,7 @@
** connection, and close this smart socket now
** that its work is done.
*/
- adb_write(s->peer->fd, "OKAY", 4);
+ SendOkay(s->peer->fd);
s->peer->ready = local_socket_ready;
s->peer->shutdown = NULL;
@@ -831,7 +818,7 @@
s->transport = acquire_one_transport(CS_ANY, kTransportAny, NULL, &error_msg);
if (s->transport == NULL) {
- sendfailmsg(s->peer->fd, error_msg.c_str());
+ SendFail(s->peer->fd, error_msg);
goto fail;
}
}
@@ -841,7 +828,7 @@
/* if there's no remote we fail the connection
** right here and terminate it
*/
- sendfailmsg(s->peer->fd, "device offline (x)");
+ SendFail(s->peer->fd, "device offline (x)");
goto fail;
}
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 633f6f5..a21272f 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -22,7 +22,6 @@
#include <windows.h>
#include <errno.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/adb/test_track_devices.cpp b/adb/test_track_devices.cpp
index 77b3ad9..3e823e9 100644
--- a/adb/test_track_devices.cpp
+++ b/adb/test_track_devices.cpp
@@ -1,3 +1,5 @@
+// TODO: replace this with a shell/python script.
+
/* a simple test program, connects to ADB server, and opens a track-devices session */
#include <netdb.h>
#include <sys/socket.h>
@@ -6,6 +8,8 @@
#include <errno.h>
#include <memory.h>
+#include <base/file.h>
+
static void
panic( const char* msg )
{
@@ -13,82 +17,49 @@
exit(1);
}
-static int
-unix_write( int fd, const char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = write(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
+int main(int argc, char* argv[]) {
+ const char* request = "host:track-devices";
+
+ if (argv[1] && strcmp(argv[1], "--jdwp") == 0) {
+ request = "track-jdwp";
}
- return result;
-}
-static int
-unix_read( int fd, char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = read(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
-
-
-int main( void )
-{
- int ret, s;
+ int ret;
struct sockaddr_in server;
char buffer[1024];
- const char* request = "host:track-devices";
- int len;
memset( &server, 0, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons(5037);
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- s = socket( PF_INET, SOCK_STREAM, 0 );
+ int s = socket( PF_INET, SOCK_STREAM, 0 );
ret = connect( s, (struct sockaddr*) &server, sizeof(server) );
if (ret < 0) panic( "could not connect to server" );
/* send the request */
- len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request );
- if (unix_write(s, buffer, len) < 0)
+ int len = snprintf(buffer, sizeof(buffer), "%04zx%s", strlen(request), request);
+ if (!android::base::WriteFully(s, buffer, len))
panic( "could not send request" );
/* read the OKAY answer */
- if (unix_read(s, buffer, 4) != 4)
+ if (!android::base::ReadFully(s, buffer, 4))
panic( "could not read request" );
printf( "server answer: %.*s\n", 4, buffer );
/* now loop */
- for (;;) {
+ while (true) {
char head[5] = "0000";
- if (unix_read(s, head, 4) < 0)
+ if (!android::base::ReadFully(s, head, 4))
panic("could not read length");
- if ( sscanf( head, "%04x", &len ) != 1 )
+ int len;
+ if (sscanf(head, "%04x", &len) != 1 )
panic("could not decode length");
- if (unix_read(s, buffer, len) != len)
+ if (!android::base::ReadFully(s, buffer, len))
panic("could not read data");
printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer );
diff --git a/adb/test_track_jdwp.cpp b/adb/test_track_jdwp.cpp
deleted file mode 100644
index 8ecc6b8..0000000
--- a/adb/test_track_jdwp.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/* a simple test program, connects to ADB server, and opens a track-devices session */
-#include <netdb.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <memory.h>
-
-static void
-panic( const char* msg )
-{
- fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno));
- exit(1);
-}
-
-static int
-unix_write( int fd, const char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = write(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
-
-static int
-unix_read( int fd, char* buf, int len )
-{
- int result = 0;
- while (len > 0) {
- int len2 = read(fd, buf, len);
- if (len2 < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- result += len2;
- len -= len2;
- buf += len2;
- }
- return result;
-}
-
-
-int main( void )
-{
- int ret, s;
- struct sockaddr_in server;
- char buffer[1024];
- const char* request = "track-jdwp";
- int len;
-
- memset( &server, 0, sizeof(server) );
- server.sin_family = AF_INET;
- server.sin_port = htons(5037);
- server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- s = socket( PF_INET, SOCK_STREAM, 0 );
- ret = connect( s, (struct sockaddr*) &server, sizeof(server) );
- if (ret < 0) panic( "could not connect to server" );
-
- /* send the request */
- len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request );
- if (unix_write(s, buffer, len) < 0)
- panic( "could not send request" );
-
- /* read the OKAY answer */
- if (unix_read(s, buffer, 4) != 4)
- panic( "could not read request" );
-
- printf( "server answer: %.*s\n", 4, buffer );
-
- /* now loop */
- for (;;) {
- char head[5] = "0000";
-
- if (unix_read(s, head, 4) < 0)
- panic("could not read length");
-
- if ( sscanf( head, "%04x", &len ) != 1 )
- panic("could not decode length");
-
- if (unix_read(s, buffer, len) != len)
- panic("could not read data");
-
- printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer );
- }
- close(s);
-}
diff --git a/adb/tests/test_adb.py b/adb/tests/test_adb.py
index 52d8056..237ef47 100755
--- a/adb/tests/test_adb.py
+++ b/adb/tests/test_adb.py
@@ -272,13 +272,24 @@
adb = AdbWrapper()
# http://b/19734868
+ # Note that this actually matches ssh(1)'s behavior --- it's
+ # converted to "sh -c echo hello; echo world" which sh interprets
+ # as "sh -c echo" (with an argument to that shell of "hello"),
+ # and then "echo world" back in the first shell.
result = adb.shell("sh -c 'echo hello; echo world'").splitlines()
+ self.assertEqual(["", "world"], result)
+ # If you really wanted "hello" and "world", here's what you'd do:
+ result = adb.shell("echo hello\;echo world").splitlines()
self.assertEqual(["hello", "world"], result)
# http://b/15479704
self.assertEqual('t', adb.shell("'true && echo t'").strip())
self.assertEqual('t', adb.shell("sh -c 'true && echo t'").strip())
+ # http://b/20564385
+ self.assertEqual('t', adb.shell("FOO=a BAR=b echo t").strip())
+ self.assertEqual('123Linux', adb.shell("echo -n 123\;uname").strip())
+
class AdbFile(unittest.TestCase):
SCRATCH_DIR = "/data/local/tmp"
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 45740a8..5c50c0a 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -26,7 +26,10 @@
#include <string.h>
#include <unistd.h>
+#include <base/stringprintf.h>
+
#include "adb.h"
+#include "adb_utils.h"
static void transport_unref(atransport *t);
@@ -42,34 +45,6 @@
ADB_MUTEX_DEFINE( transport_lock );
-#if ADB_TRACE
-#define MAX_DUMP_HEX_LEN 16
-void dump_hex(const unsigned char* ptr, size_t len)
-{
- int nn, len2 = len;
- // Build a string instead of logging each character.
- // MAX chars in 2 digit hex, one space, MAX chars, one '\0'.
- char buffer[MAX_DUMP_HEX_LEN *2 + 1 + MAX_DUMP_HEX_LEN + 1 ], *pb = buffer;
-
- if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN;
-
- for (nn = 0; nn < len2; nn++) {
- sprintf(pb, "%02x", ptr[nn]);
- pb += 2;
- }
- sprintf(pb++, " ");
-
- for (nn = 0; nn < len2; nn++) {
- int c = ptr[nn];
- if (c < 32 || c > 127)
- c = '.';
- *pb++ = c;
- }
- *pb++ = '\0';
- DR("%s\n", buffer);
-}
-#endif
-
void kick_transport(atransport* t)
{
if (t && !t->kicked)
@@ -117,10 +92,7 @@
}
}
-#if ADB_TRACE
-static void
-dump_packet(const char* name, const char* func, apacket* p)
-{
+static void dump_packet(const char* name, const char* func, apacket* p) {
unsigned command = p->msg.command;
int len = p->msg.data_length;
char cmd[9];
@@ -155,7 +127,6 @@
name, func, cmd, arg0, arg1, len);
dump_hex(p->data, len);
}
-#endif /* ADB_TRACE */
static int
read_packet(int fd, const char* name, apacket** ppacket)
@@ -180,11 +151,9 @@
}
}
-#if ADB_TRACE
if (ADB_TRACING) {
dump_packet(name, "from remote", *ppacket);
}
-#endif
return 0;
}
@@ -199,11 +168,9 @@
name = buff;
}
-#if ADB_TRACE
if (ADB_TRACING) {
dump_packet(name, "to remote", *ppacket);
}
-#endif
len = sizeof(ppacket);
while(len > 0) {
r = adb_write(fd, p, len);
@@ -389,17 +356,6 @@
#if ADB_HOST
-static int list_transports_msg(char* buffer, size_t bufferlen)
-{
- char head[5];
- int len;
-
- len = list_transports(buffer+4, bufferlen-4, 0);
- snprintf(head, sizeof(head), "%04x", len);
- memcpy(buffer, head, 4);
- len += 4;
- return len;
-}
/* this adds support required by the 'track-devices' service.
* this is used to send the content of "list_transport" to any
@@ -457,39 +413,29 @@
return -1;
}
-static int
-device_tracker_send( device_tracker* tracker,
- const char* buffer,
- int len )
-{
- apacket* p = get_apacket();
- asocket* peer = tracker->socket.peer;
+static int device_tracker_send(device_tracker* tracker, const std::string& string) {
+ apacket* p = get_apacket();
+ asocket* peer = tracker->socket.peer;
- memcpy(p->data, buffer, len);
- p->len = len;
- return peer->enqueue( peer, p );
+ snprintf(reinterpret_cast<char*>(p->data), 5, "%04x", static_cast<int>(string.size()));
+ memcpy(&p->data[4], string.data(), string.size());
+ p->len = 4 + string.size();
+ return peer->enqueue(peer, p);
}
+static void device_tracker_ready(asocket* socket) {
+ device_tracker* tracker = reinterpret_cast<device_tracker*>(socket);
-static void
-device_tracker_ready( asocket* socket )
-{
- device_tracker* tracker = (device_tracker*) socket;
-
- /* we want to send the device list when the tracker connects
- * for the first time, even if no update occured */
+ // We want to send the device list when the tracker connects
+ // for the first time, even if no update occurred.
if (tracker->update_needed > 0) {
- char buffer[1024];
- int len;
-
tracker->update_needed = 0;
- len = list_transports_msg(buffer, sizeof(buffer));
- device_tracker_send(tracker, buffer, len);
+ std::string transports = list_transports(false);
+ device_tracker_send(tracker, transports);
}
}
-
asocket*
create_device_tracker(void)
{
@@ -510,27 +456,25 @@
}
-/* call this function each time the transport list has changed */
-void update_transports(void) {
- char buffer[1024];
- int len;
- device_tracker* tracker;
+// Call this function each time the transport list has changed.
+void update_transports() {
+ std::string transports = list_transports(false);
- len = list_transports_msg(buffer, sizeof(buffer));
-
- tracker = device_tracker_list;
- while (tracker != NULL) {
- device_tracker* next = tracker->next;
- /* note: this may destroy the tracker if the connection is closed */
- device_tracker_send(tracker, buffer, len);
+ device_tracker* tracker = device_tracker_list;
+ while (tracker != nullptr) {
+ device_tracker* next = tracker->next;
+ // This may destroy the tracker if the connection is closed.
+ device_tracker_send(tracker, transports);
tracker = next;
}
}
+
#else
-void update_transports(void)
-{
- // nothing to do on the device side
+
+void update_transports() {
+ // Nothing to do on the device side.
}
+
#endif // ADB_HOST
struct tmsg
@@ -804,7 +748,7 @@
int ambiguous = 0;
retry:
- if (error_out) *error_out = "device not found";
+ if (error_out) *error_out = android::base::StringPrintf("device '%s' not found", serial);
adb_mutex_lock(&transport_lock);
for (t = transport_list.next; t != &transport_list; t = t->next) {
@@ -895,100 +839,71 @@
return result;
}
-#if ADB_HOST
-static const char *statename(atransport *t)
-{
- switch(t->connection_state){
+const char* atransport::connection_state_name() const {
+ switch (connection_state) {
case CS_OFFLINE: return "offline";
case CS_BOOTLOADER: return "bootloader";
case CS_DEVICE: return "device";
case CS_HOST: return "host";
case CS_RECOVERY: return "recovery";
- case CS_SIDELOAD: return "sideload";
case CS_NOPERM: return "no permissions";
+ case CS_SIDELOAD: return "sideload";
case CS_UNAUTHORIZED: return "unauthorized";
default: return "unknown";
}
}
-static void add_qual(char **buf, size_t *buf_size,
- const char *prefix, const char *qual, bool sanitize_qual)
-{
- if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual)
+#if ADB_HOST
+
+static void append_transport_info(std::string* result, const char* key, const char* value, bool sanitize) {
+ if (value == nullptr || *value == '\0') {
return;
-
- int prefix_len;
- size_t len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual);
-
- if (sanitize_qual) {
- for (char* cp = *buf + prefix_len; cp < *buf + len; cp++) {
- if (!isalnum(*cp))
- *cp = '_';
- }
}
- *buf_size -= len;
- *buf += len;
+ *result += ' ';
+ *result += key;
+
+ for (const char* p = value; *p; ++p) {
+ result->push_back((!sanitize || isalnum(*p)) ? *p : '_');
+ }
}
-static size_t format_transport(atransport *t, char *buf, size_t bufsize,
- int long_listing)
-{
+static void append_transport(atransport* t, std::string* result, bool long_listing) {
const char* serial = t->serial;
- if (!serial || !serial[0])
+ if (!serial || !serial[0]) {
serial = "????????????";
+ }
if (!long_listing) {
- return snprintf(buf, bufsize, "%s\t%s\n", serial, statename(t));
+ *result += serial;
+ *result += '\t';
+ *result += t->connection_state_name();
} else {
- size_t len, remaining = bufsize;
+ android::base::StringAppendF(result, "%-22s %s", serial, t->connection_state_name());
- len = snprintf(buf, remaining, "%-22s %s", serial, statename(t));
- remaining -= len;
- buf += len;
-
- add_qual(&buf, &remaining, " ", t->devpath, false);
- add_qual(&buf, &remaining, " product:", t->product, false);
- add_qual(&buf, &remaining, " model:", t->model, true);
- add_qual(&buf, &remaining, " device:", t->device, false);
-
- len = snprintf(buf, remaining, "\n");
- remaining -= len;
-
- return bufsize - remaining;
+ append_transport_info(result, "", t->devpath, false);
+ append_transport_info(result, "product:", t->product, false);
+ append_transport_info(result, "model:", t->model, true);
+ append_transport_info(result, "device:", t->device, false);
}
+ *result += '\n';
}
-int list_transports(char *buf, size_t bufsize, int long_listing)
-{
- char* p = buf;
- char* end = buf + bufsize;
- int len;
- atransport *t;
-
- /* XXX OVERRUN PROBLEMS XXX */
+std::string list_transports(bool long_listing) {
+ std::string result;
adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
- len = format_transport(t, p, end - p, long_listing);
- if (p + len >= end) {
- /* discard last line if buffer is too short */
- break;
- }
- p += len;
+ for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
+ append_transport(t, &result, long_listing);
}
- p[0] = 0;
adb_mutex_unlock(&transport_lock);
- return p - buf;
+ return result;
}
-
/* hack for osx */
void close_usb_devices()
{
- atransport *t;
-
adb_mutex_lock(&transport_lock);
- for(t = transport_list.next; t != &transport_list; t = t->next) {
+ for (atransport* t = transport_list.next; t != &transport_list; t = t->next) {
if ( !t->kicked ) {
t->kicked = 1;
t->kick(t);
diff --git a/adb/transport.h b/adb/transport.h
index a2077e8..5b6fdac 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -23,10 +23,6 @@
#include "adb.h"
-#if ADB_TRACE
-void dump_hex(const unsigned char* ptr, size_t len);
-#endif
-
/*
* Obtain a transport from the available transports.
* If state is != CS_ANY, only transports in that state are considered.
@@ -45,7 +41,7 @@
** get_device_transport does an acquire on your behalf before returning
*/
void init_transport_registration(void);
-int list_transports(char* buf, size_t bufsize, int long_listing);
+std::string list_transports(bool long_listing);
atransport* find_transport(const char* serial);
void register_usb_transport(usb_handle* h, const char* serial,
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 4d93bb5..b1deffd 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -25,6 +25,8 @@
#include <string.h>
#include <sys/types.h>
+#include <base/stringprintf.h>
+
#if !ADB_HOST
#include "cutils/properties.h"
#endif
@@ -88,7 +90,6 @@
int local_connect_arbitrary_ports(int console_port, int adb_port)
{
- char buf[64];
int fd = -1;
#if ADB_HOST
@@ -105,8 +106,8 @@
D("client: connected on remote on fd %d\n", fd);
close_on_exec(fd);
disable_tcp_nagle(fd);
- snprintf(buf, sizeof buf, "emulator-%d", console_port);
- register_socket_transport(fd, buf, adb_port, 1);
+ std::string serial = android::base::StringPrintf("emulator-%d", console_port);
+ register_socket_transport(fd, serial.c_str(), adb_port, 1);
return 0;
}
return -1;
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 094ab48..b7e6b17 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -371,7 +371,8 @@
} else {
line += '-';
}
- line += android::base::StringPrintf(" %8" PRIxPTR, it->end - it->start);
+ line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR,
+ it->offset, it->end - it->start);
if (it->name.length() > 0) {
line += " " + it->name;
std::string build_id;
@@ -379,6 +380,9 @@
line += " (BuildId: " + build_id + ")";
}
}
+ if (it->load_base != 0) {
+ line += android::base::StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
+ }
_LOG(log, logtype::MAPS, "%s\n", line.c_str());
}
if (print_fault_address_marker) {
@@ -792,7 +796,7 @@
*detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
dump_sibling_threads, total_sleep_time_usec);
- ALOGI("\nTombstone written to: %s\n", path);
+ _LOG(&log, logtype::BACKTRACE, "\nTombstone written to: %s\n", path);
// Either of these file descriptors can be -1, any error is ignored.
close(amfd);
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index d6a6d2e..e722f82 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -67,7 +67,7 @@
}
if (write_to_logcat) {
- __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_INFO, LOG_TAG, buf);
+ __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_FATAL, LOG_TAG, buf);
if (write_to_activitymanager) {
if (!android::base::WriteFully(log->amfd, buf, len)) {
// timeout or other failure on write; stop informing the activity manager
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index da96307..784bc03 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -37,6 +37,8 @@
uintptr_t start;
uintptr_t end;
+ uintptr_t offset;
+ uintptr_t load_base;
int flags;
std::string name;
};
@@ -82,6 +84,14 @@
return map.end > 0;
}
+ static uintptr_t GetRelativePc(const backtrace_map_t& map, uintptr_t pc) {
+ if (IsValid(map)) {
+ return pc - map.start + map.load_base;
+ } else {
+ return pc;
+ }
+ }
+
protected:
BacktraceMap(pid_t pid);
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index 91ca8b7..d75c210 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -97,12 +97,7 @@
map_name = "<unknown>";
}
- uintptr_t relative_pc;
- if (BacktraceMap::IsValid(frame->map)) {
- relative_pc = frame->pc - frame->map.start;
- } else {
- relative_pc = frame->pc;
- }
+ uintptr_t relative_pc = BacktraceMap::GetRelativePc(frame->map, frame->pc);
std::string line(StringPrintf("#%02zu pc %" PRIPTR " %s", frame->num, relative_pc, map_name));
if (!frame->func_name.empty()) {
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index 6134438..e10cce1 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -83,13 +83,12 @@
if (!PtraceRead(Tid(), addr & ~(sizeof(word_t) - 1), &data_word)) {
return 0;
}
- align_bytes = sizeof(word_t) - align_bytes;
- memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + sizeof(word_t) - align_bytes,
- align_bytes);
- addr += align_bytes;
- buffer += align_bytes;
- bytes -= align_bytes;
- bytes_read += align_bytes;
+ size_t copy_bytes = MIN(sizeof(word_t) - align_bytes, bytes);
+ memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + align_bytes, copy_bytes);
+ addr += copy_bytes;
+ buffer += copy_bytes;
+ bytes -= copy_bytes;
+ bytes_read += copy_bytes;
}
size_t num_words = bytes / sizeof(word_t);
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index fa59d07..879fea5 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -51,6 +51,8 @@
map.start = unw_map.start;
map.end = unw_map.end;
+ map.offset = unw_map.offset;
+ map.load_base = unw_map.load_base;
map.flags = unw_map.flags;
map.name = unw_map.path;
@@ -91,6 +93,8 @@
map.start = unw_map.start;
map.end = unw_map.end;
+ map.offset = unw_map.offset;
+ map.load_base = unw_map.load_base;
map.flags = unw_map.flags;
map.name = unw_map.path;
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 4af6592..ba3cbb5 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -771,6 +771,7 @@
// Check map name empty, but exists.
frame.map.start = 1;
frame.map.end = 1;
+ frame.map.load_base = 0;
#if defined(__LP64__)
EXPECT_EQ("#01 pc 0000000000000001 <unknown>",
#else
@@ -808,6 +809,16 @@
EXPECT_EQ("#01 pc 12345678 MapFake (ProcFake+645)",
#endif
backtrace->FormatFrameData(&frame));
+
+ // Check func_name is set, func offset is non-zero, and load_base is non-zero.
+ frame.func_offset = 645;
+ frame.map.load_base = 100;
+#if defined(__LP64__)
+ EXPECT_EQ("#01 pc 00000000123456dc MapFake (ProcFake+645)",
+#else
+ EXPECT_EQ("#01 pc 123456dc MapFake (ProcFake+645)",
+#endif
+ backtrace->FormatFrameData(&frame));
}
struct map_test_t {
@@ -871,6 +882,17 @@
ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
}
+void InitMemory(uint8_t* memory, size_t bytes) {
+ for (size_t i = 0; i < bytes; i++) {
+ memory[i] = i;
+ if (memory[i] == '\0') {
+ // Don't use '\0' in our data so we can verify that an overread doesn't
+ // occur by using a '\0' as the character after the read data.
+ memory[i] = 23;
+ }
+ }
+}
+
void* ThreadReadTest(void* data) {
thread_t* thread_data = reinterpret_cast<thread_t*>(data);
@@ -889,9 +911,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
thread_data->data = memory;
@@ -919,9 +939,8 @@
// Create a page of data to use to do quick compares.
uint8_t* expected = new uint8_t[pagesize];
- for (size_t i = 0; i < pagesize; i++) {
- expected[i] = i;
- }
+ InitMemory(expected, pagesize);
+
uint8_t* data = new uint8_t[2*pagesize];
// Verify that we can only read one page worth of data.
size_t bytes_read = backtrace->Read(read_addr, data, 2 * pagesize);
@@ -935,6 +954,20 @@
ASSERT_TRUE(memcmp(data, &expected[i], 2 * sizeof(word_t)) == 0)
<< "Offset at " << i << " failed";
}
+
+ // Verify small unaligned reads.
+ for (size_t i = 1; i < sizeof(word_t); i++) {
+ for (size_t j = 1; j < sizeof(word_t); j++) {
+ // Set one byte past what we expect to read, to guarantee we don't overread.
+ data[j] = '\0';
+ bytes_read = backtrace->Read(read_addr + i, data, j);
+ ASSERT_EQ(j, bytes_read);
+ ASSERT_TRUE(memcmp(data, &expected[i], j) == 0)
+ << "Offset at " << i << " length " << j << " miscompared";
+ ASSERT_EQ('\0', data[j])
+ << "Offset at " << i << " length " << j << " wrote too much data";
+ }
+ }
delete data;
delete expected;
}
@@ -978,9 +1011,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
g_addr = reinterpret_cast<uintptr_t>(memory);
g_ready = 1;
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index 059c031..b6c6196 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -25,6 +25,9 @@
#include <log/log.h>
#include <log/log_read.h>
+// Hijack this header as a common include file used by most all sources
+// to report some utilities defined here and there.
+
namespace android {
// Furnished in main.cpp. Caller must own and free returned value
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index b063630..10f7255 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -70,21 +70,7 @@
mSizes[log_id] += size;
++mElements[log_id];
- uid_t uid = e->getUid();
- unsigned short dropped = e->getDropped();
- android::hash_t hash = android::hash_type(uid);
- uidTable_t &table = uidTable[log_id];
- ssize_t index = table.find(-1, hash, uid);
- if (index == -1) {
- UidEntry initEntry(uid);
- initEntry.add(size);
- initEntry.add_dropped(dropped);
- table.add(hash, initEntry);
- } else {
- UidEntry &entry = table.editEntryAt(index);
- entry.add(size);
- entry.add_dropped(dropped);
- }
+ uidTable[log_id].add(e->getUid(), e);
mSizesTotal[log_id] += size;
++mElementsTotal[log_id];
@@ -93,28 +79,7 @@
return;
}
- pid_t pid = e->getPid();
- hash = android::hash_type(pid);
- index = pidTable.find(-1, hash, pid);
- if (index == -1) {
- PidEntry initEntry(pid, uid, android::pidToName(pid));
- initEntry.add(size);
- initEntry.add_dropped(dropped);
- pidTable.add(hash, initEntry);
- } else {
- PidEntry &entry = pidTable.editEntryAt(index);
- if (entry.getUid() != uid) {
- entry.setUid(uid);
- entry.setName(android::pidToName(pid));
- } else if (!entry.getName()) {
- char *name = android::pidToName(pid);
- if (name) {
- entry.setName(name);
- }
- }
- entry.add(size);
- entry.add_dropped(dropped);
- }
+ pidTable.add(e->getPid(), e);
}
void LogStatistics::subtract(LogBufferElement *e) {
@@ -123,31 +88,13 @@
mSizes[log_id] -= size;
--mElements[log_id];
- uid_t uid = e->getUid();
- unsigned short dropped = e->getDropped();
- android::hash_t hash = android::hash_type(uid);
- uidTable_t &table = uidTable[log_id];
- ssize_t index = table.find(-1, hash, uid);
- if (index != -1) {
- UidEntry &entry = table.editEntryAt(index);
- if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
- table.removeAt(index);
- }
- }
+ uidTable[log_id].subtract(e->getUid(), e);
if (!enable) {
return;
}
- pid_t pid = e->getPid();
- hash = android::hash_type(pid);
- index = pidTable.find(-1, hash, pid);
- if (index != -1) {
- PidEntry &entry = pidTable.editEntryAt(index);
- if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
- pidTable.removeAt(index);
- }
- }
+ pidTable.subtract(e->getPid(), e);
}
// Atomically set an entry to drop
@@ -157,28 +104,13 @@
unsigned short size = e->getMsgLen();
mSizes[log_id] -= size;
- uid_t uid = e->getUid();
- android::hash_t hash = android::hash_type(uid);
- typeof uidTable[0] &table = uidTable[log_id];
- ssize_t index = table.find(-1, hash, uid);
- if (index != -1) {
- UidEntry &entry = table.editEntryAt(index);
- entry.subtract(size);
- entry.add_dropped(1);
- }
+ uidTable[log_id].drop(e->getUid(), e);
if (!enable) {
return;
}
- pid_t pid = e->getPid();
- hash = android::hash_type(pid);
- index = pidTable.find(-1, hash, pid);
- if (index != -1) {
- PidEntry &entry = pidTable.editEntryAt(index);
- entry.subtract(size);
- entry.add_dropped(1);
- }
+ pidTable.drop(e->getPid(), e);
}
// caller must own and free character string
@@ -379,6 +311,7 @@
}
if (enable) {
+ // Pid table
bool headerPrinted = false;
std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
ssize_t index = -1;
@@ -460,48 +393,14 @@
}
uid_t LogStatistics::pidToUid(pid_t pid) {
- uid_t uid;
- android::hash_t hash = android::hash_type(pid);
- ssize_t index = pidTable.find(-1, hash, pid);
- if (index == -1) {
- uid = android::pidToUid(pid);
- PidEntry initEntry(pid, uid, android::pidToName(pid));
- pidTable.add(hash, initEntry);
- } else {
- PidEntry &entry = pidTable.editEntryAt(index);
- if (!entry.getName()) {
- char *name = android::pidToName(pid);
- if (name) {
- entry.setName(name);
- }
- }
- uid = entry.getUid();
- }
- return uid;
+ return pidTable.entryAt(pidTable.add(pid)).getUid();
}
// caller must free character string
char *LogStatistics::pidToName(pid_t pid) {
- char *name;
-
- android::hash_t hash = android::hash_type(pid);
- ssize_t index = pidTable.find(-1, hash, pid);
- if (index == -1) {
- name = android::pidToName(pid);
- PidEntry initEntry(pid, android::pidToUid(pid), name ? strdup(name) : NULL);
- pidTable.add(hash, initEntry);
- } else {
- PidEntry &entry = pidTable.editEntryAt(index);
- const char *n = entry.getName();
- if (n) {
- name = strdup(n);
- } else {
- name = android::pidToName(pid);
- if (name) {
- entry.setName(strdup(name));
- }
- }
+ const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
+ if (!name) {
+ return NULL;
}
-
- return name;
+ return strdup(name);
}
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index f3110d7..a935c27 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -73,52 +73,139 @@
ssize_t next(ssize_t index) {
return android::BasicHashtable<TKey, TEntry>::next(index);
}
+
+ size_t add(TKey key, LogBufferElement *e) {
+ android::hash_t hash = android::hash_type(key);
+ ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
+ if (index == -1) {
+ return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(e));
+ }
+ android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(e);
+ return index;
+ }
+
+ inline size_t add(TKey key) {
+ android::hash_t hash = android::hash_type(key);
+ ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
+ if (index == -1) {
+ return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(key));
+ }
+ android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(key);
+ return index;
+ }
+
+ void subtract(TKey key, LogBufferElement *e) {
+ ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
+ if ((index != -1)
+ && android::BasicHashtable<TKey, TEntry>::editEntryAt(index).subtract(e)) {
+ android::BasicHashtable<TKey, TEntry>::removeAt(index);
+ }
+ }
+
+ inline void drop(TKey key, LogBufferElement *e) {
+ ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
+ if (index != -1) {
+ android::BasicHashtable<TKey, TEntry>::editEntryAt(index).drop(e);
+ }
+ }
+
};
-struct UidEntry {
- const uid_t uid;
+struct EntryBase {
size_t size;
+
+ EntryBase():size(0) { }
+ EntryBase(LogBufferElement *e):size(e->getMsgLen()) { }
+
+ size_t getSizes() const { return size; }
+
+ inline void add(LogBufferElement *e) { size += e->getMsgLen(); }
+ inline bool subtract(LogBufferElement *e) { size -= e->getMsgLen(); return !size; }
+};
+
+struct EntryBaseDropped : public EntryBase {
size_t dropped;
- UidEntry(uid_t uid):uid(uid),size(0),dropped(0) { }
+ EntryBaseDropped():dropped(0) { }
+ EntryBaseDropped(LogBufferElement *e):EntryBase(e),dropped(e->getDropped()){ }
- inline const uid_t&getKey() const { return uid; }
- size_t getSizes() const { return size; }
size_t getDropped() const { return dropped; }
- inline void add(size_t s) { size += s; }
- inline void add_dropped(size_t d) { dropped += d; }
- inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
- inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }
+ inline void add(LogBufferElement *e) {
+ dropped += e->getDropped();
+ EntryBase::add(e);
+ }
+ inline bool subtract(LogBufferElement *e) {
+ dropped -= e->getDropped();
+ return EntryBase::subtract(e) && !dropped;
+ }
+ inline void drop(LogBufferElement *e) {
+ dropped += 1;
+ EntryBase::subtract(e);
+ }
};
-struct PidEntry {
+struct UidEntry : public EntryBaseDropped {
+ const uid_t uid;
+
+ UidEntry(LogBufferElement *e):EntryBaseDropped(e),uid(e->getUid()) { }
+
+ inline const uid_t&getKey() const { return uid; }
+};
+
+namespace android {
+// caller must own and free character string
+char *pidToName(pid_t pid);
+uid_t pidToUid(pid_t pid);
+}
+
+struct PidEntry : public EntryBaseDropped {
const pid_t pid;
uid_t uid;
char *name;
- size_t size;
- size_t dropped;
- PidEntry(pid_t p, uid_t u, char *n):pid(p),uid(u),name(n),size(0),dropped(0) { }
+ PidEntry(pid_t p):
+ EntryBaseDropped(),
+ pid(p),
+ uid(android::pidToUid(p)),
+ name(android::pidToName(pid)) { }
+ PidEntry(LogBufferElement *e):
+ EntryBaseDropped(e),
+ pid(e->getPid()),
+ uid(e->getUid()),
+ name(android::pidToName(e->getPid())) { }
PidEntry(const PidEntry &c):
+ EntryBaseDropped(c),
pid(c.pid),
uid(c.uid),
- name(c.name ? strdup(c.name) : NULL),
- size(c.size),
- dropped(c.dropped) { }
+ name(c.name ? strdup(c.name) : NULL) { }
~PidEntry() { free(name); }
const pid_t&getKey() const { return pid; }
const uid_t&getUid() const { return uid; }
- uid_t&setUid(uid_t u) { return uid = u; }
const char*getName() const { return name; }
- char *setName(char *n) { free(name); return name = n; }
- size_t getSizes() const { return size; }
- size_t getDropped() const { return dropped; }
- inline void add(size_t s) { size += s; }
- inline void add_dropped(size_t d) { dropped += d; }
- inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
- inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }
+
+ inline void add(pid_t p) {
+ if (!name) {
+ char *n = android::pidToName(p);
+ if (n) {
+ name = n;
+ }
+ }
+ }
+
+ inline void add(LogBufferElement *e) {
+ uid_t u = e->getUid();
+ if (getUid() != u) {
+ uid = u;
+ free(name);
+ name = android::pidToName(e->getPid());
+ } else {
+ add(e->getPid());
+ }
+ EntryBaseDropped::add(e);
+ }
+
};
// Log Statistics
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h
index 9171d85..5ab6195 100644
--- a/mkbootimg/bootimg.h
+++ b/mkbootimg/bootimg.h
@@ -15,6 +15,8 @@
** limitations under the License.
*/
+#include <stdint.h>
+
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
@@ -28,31 +30,31 @@
struct boot_img_hdr
{
- unsigned char magic[BOOT_MAGIC_SIZE];
+ uint8_t magic[BOOT_MAGIC_SIZE];
- unsigned kernel_size; /* size in bytes */
- unsigned kernel_addr; /* physical load addr */
+ uint32_t kernel_size; /* size in bytes */
+ uint32_t kernel_addr; /* physical load addr */
- unsigned ramdisk_size; /* size in bytes */
- unsigned ramdisk_addr; /* physical load addr */
+ uint32_t ramdisk_size; /* size in bytes */
+ uint32_t ramdisk_addr; /* physical load addr */
- unsigned second_size; /* size in bytes */
- unsigned second_addr; /* physical load addr */
+ uint32_t second_size; /* size in bytes */
+ uint32_t second_addr; /* physical load addr */
- unsigned tags_addr; /* physical addr for kernel tags */
- unsigned page_size; /* flash page size we assume */
- unsigned unused[2]; /* future expansion: should be 0 */
+ uint32_t tags_addr; /* physical addr for kernel tags */
+ uint32_t page_size; /* flash page size we assume */
+ uint32_t unused[2]; /* future expansion: should be 0 */
- unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
+ uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
- unsigned char cmdline[BOOT_ARGS_SIZE];
+ uint8_t cmdline[BOOT_ARGS_SIZE];
- unsigned id[8]; /* timestamp / checksum / sha1 / etc */
+ uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
/* Supplemental command line data; kept here to maintain
* binary compatibility with older versions of mkbootimg */
- unsigned char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
-};
+ uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
+} __attribute__((packed));
/*
** +-----------------+
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index edc5104..b6a2801 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -106,24 +106,24 @@
{
boot_img_hdr hdr;
- char *kernel_fn = 0;
- void *kernel_data = 0;
- char *ramdisk_fn = 0;
- void *ramdisk_data = 0;
- char *second_fn = 0;
- void *second_data = 0;
+ char *kernel_fn = NULL;
+ void *kernel_data = NULL;
+ char *ramdisk_fn = NULL;
+ void *ramdisk_data = NULL;
+ char *second_fn = NULL;
+ void *second_data = NULL;
char *cmdline = "";
- char *bootimg = 0;
+ char *bootimg = NULL;
char *board = "";
- unsigned pagesize = 2048;
+ uint32_t pagesize = 2048;
int fd;
SHA_CTX ctx;
const uint8_t* sha;
- unsigned base = 0x10000000;
- unsigned kernel_offset = 0x00008000;
- unsigned ramdisk_offset = 0x01000000;
- unsigned second_offset = 0x00f00000;
- unsigned tags_offset = 0x00000100;
+ uint32_t base = 0x10000000U;
+ uint32_t kernel_offset = 0x00008000U;
+ uint32_t ramdisk_offset = 0x01000000U;
+ uint32_t second_offset = 0x00f00000U;
+ uint32_t tags_offset = 0x00000100U;
size_t cmdlen;
argc--;
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 3ecb1db..7ab76b8 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -26,7 +26,7 @@
#
# create some directories (some are mount points)
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data)
+ sbin dev proc sys system data oem)
include $(BUILD_SYSTEM)/base_rules.mk
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 40cd070..d44f98b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -263,6 +263,7 @@
mkdir /data/misc/ethernet 0770 system system
mkdir /data/misc/dhcp 0770 dhcp dhcp
mkdir /data/misc/user 0771 root root
+ mkdir /data/misc/perfprofd 0775 root root
# give system access to wpa_supplicant.conf for backup and restore
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root
@@ -655,3 +656,11 @@
class main
disabled
oneshot
+
+on property:ro.debuggable=1
+ start perfprofd
+
+service perfprofd /system/xbin/perfprofd
+ disabled
+ user root
+ oneshot