Merge "Mark time conversion functions as constexpr"
diff --git a/adb/Android.mk b/adb/Android.mk
index 7d3978b..6951904 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -5,7 +5,11 @@
LOCAL_PATH:= $(call my-dir)
-ADB_CLANG :=
+ifeq ($(HOST_OS),windows)
+ adb_host_clang := false # libc++ for mingw not ready yet.
+else
+ adb_host_clang := true
+endif
# libadb
# =========================================================
@@ -21,11 +25,17 @@
adb_auth.cpp \
adb_io.cpp \
adb_listeners.cpp \
+ adb_utils.cpp \
sockets.cpp \
transport.cpp \
transport_local.cpp \
transport_usb.cpp \
+LIBADB_TEST_SRCS := \
+ adb_io_test.cpp \
+ adb_utils_test.cpp \
+ transport_test.cpp \
+
LIBADB_CFLAGS := \
-Wall -Werror \
-Wno-unused-parameter \
@@ -59,10 +69,12 @@
qemu_tracing.cpp \
usb_linux_client.cpp \
+LOCAL_SHARED_LIBRARIES := libbase
+
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
LOCAL_MODULE := libadb
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=1
LOCAL_SRC_FILES := \
@@ -70,6 +82,8 @@
$(LIBADB_$(HOST_OS)_SRC_FILES) \
adb_auth_host.cpp \
+LOCAL_SHARED_LIBRARIES := libbase
+
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the SSL includes to our path.
LOCAL_STATIC_LIBRARIES := libcrypto_static
@@ -80,12 +94,8 @@
include $(BUILD_HOST_STATIC_LIBRARY)
-LIBADB_TEST_SRCS := \
- adb_io_test.cpp \
- transport_test.cpp \
-
include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
LOCAL_MODULE := adbd_test
LOCAL_CFLAGS := -DADB_HOST=0 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS)
@@ -94,7 +104,7 @@
include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
LOCAL_MODULE := adb_test
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.cpp
@@ -129,15 +139,11 @@
endif
ifeq ($(HOST_OS),windows)
+ LOCAL_LDLIBS += -lws2_32 -lgdi32
EXTRA_STATIC_LIBS := AdbWinApi
- ifneq ($(strip $(USE_MINGW)),)
- # MinGW under Linux case
- LOCAL_LDLIBS += -lws2_32 -lgdi32
- USE_SYSDEPS_WIN32 := 1
- endif
endif
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := $(adb_host_clang)
LOCAL_SRC_FILES := \
adb_main.cpp \
@@ -158,13 +164,21 @@
LOCAL_STATIC_LIBRARIES := \
libadb \
+ libbase \
libcrypto_static \
+ libcutils \
$(EXTRA_STATIC_LIBS) \
-ifeq ($(USE_SYSDEPS_WIN32),)
- LOCAL_STATIC_LIBRARIES += libcutils
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+ LOCAL_CXX_STL := libc++_static
endif
+# Don't add anything here, we don't want additional shared dependencies
+# on the host adb tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
include $(BUILD_HOST_EXECUTABLE)
$(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))
@@ -181,7 +195,7 @@
include $(CLEAR_VARS)
-LOCAL_CLANG := $(ADB_CLANG)
+LOCAL_CLANG := true
LOCAL_SRC_FILES := \
adb_main.cpp \
diff --git a/adb/adb.cpp b/adb/adb.cpp
index ad85184f..de82cd4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -32,6 +32,8 @@
#include <string>
+#include <base/stringprintf.h>
+
#include "adb_auth.h"
#include "adb_io.h"
#include "adb_listeners.h"
@@ -802,7 +804,6 @@
if (!strncmp(service, "forward:",8) ||
!strncmp(service, "killforward:",12)) {
char *local, *remote;
- int r;
atransport *transport;
int createForward = strncmp(service, "kill", 4);
@@ -838,19 +839,20 @@
}
}
- const char* err;
- transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
+ std::string error_msg;
+ transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
if (!transport) {
- sendfailmsg(reply_fd, err);
+ sendfailmsg(reply_fd, error_msg.c_str());
return 1;
}
+ install_status_t r;
if (createForward) {
r = install_listener(local, remote, transport, no_rebind);
} else {
r = remove_listener(local, transport);
}
- if(r == 0) {
+ if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
WriteFdExactly(reply_fd, "OKAY", 4);
@@ -859,22 +861,19 @@
return 1;
}
- if (createForward) {
- const char* message;
- switch (r) {
- case INSTALL_STATUS_CANNOT_BIND:
- message = "cannot bind to socket";
- break;
- case INSTALL_STATUS_CANNOT_REBIND:
- message = "cannot rebind existing socket";
- break;
- default:
- message = "internal error";
- }
- sendfailmsg(reply_fd, message);
- } else {
- sendfailmsg(reply_fd, "cannot remove listener");
+ std::string message;
+ switch (r) {
+ case INSTALL_STATUS_OK: message = " "; break;
+ case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
+ case INSTALL_STATUS_CANNOT_BIND:
+ message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
+ break;
+ case INSTALL_STATUS_CANNOT_REBIND:
+ message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
+ break;
+ case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
}
+ sendfailmsg(reply_fd, message.c_str());
return 1;
}
return 0;
@@ -910,14 +909,14 @@
serial = service;
}
- const char* error_string = "unknown failure";
- transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
+ std::string error_msg = "unknown failure";
+ transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
if (transport) {
s->transport = transport;
adb_write(reply_fd, "OKAY", 4);
} else {
- sendfailmsg(reply_fd, error_string);
+ sendfailmsg(reply_fd, error_msg.c_str());
}
return 1;
}
@@ -975,7 +974,7 @@
if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
const char *out = "unknown";
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
- if (transport && transport->serial) {
+ if (transport && transport->serial) {
out = transport->serial;
}
send_msg_with_okay(reply_fd, out, strlen(out));
@@ -984,7 +983,7 @@
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
const char *out = "unknown";
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
- if (transport && transport->devpath) {
+ if (transport && transport->devpath) {
out = transport->devpath;
}
send_msg_with_okay(reply_fd, out, strlen(out));
diff --git a/adb/adb.h b/adb/adb.h
index 749515c..cb2cf60 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -23,10 +23,6 @@
#include "adb_trace.h"
#include "fdevent.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define MAX_PAYLOAD 4096
#define A_SYNC 0x434e5953
@@ -47,14 +43,8 @@
// Increment this when we want to force users to start a new adb server.
#define ADB_SERVER_VERSION 32
-typedef struct amessage amessage;
-typedef struct apacket apacket;
-typedef struct asocket asocket;
-typedef struct alistener alistener;
-typedef struct aservice aservice;
-typedef struct atransport atransport;
-typedef struct adisconnect adisconnect;
-typedef struct usb_handle usb_handle;
+struct atransport;
+struct usb_handle;
struct amessage {
unsigned command; /* command identifier constant */
@@ -171,12 +161,12 @@
** object, it's a special value used to indicate that a client wants to
** connect to a service implemented within the ADB server itself.
*/
-typedef enum transport_type {
+enum transport_type {
kTransportUsb,
kTransportLocal,
kTransportAny,
kTransportHost,
-} transport_type;
+};
#define TOKEN_SIZE 20
@@ -363,10 +353,10 @@
extern int HOST;
extern int SHELL_EXIT_NOTIFY_FD;
-typedef enum {
+enum subproc_mode {
SUBPROC_PTY = 0,
SUBPROC_RAW = 1,
-} subproc_mode;
+} ;
#define CHUNK_SIZE (64*1024)
@@ -389,8 +379,4 @@
void send_connect(atransport *t);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 635556e..1e1978d 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -19,10 +19,6 @@
#include "adb.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern int auth_enabled;
int adb_auth_keygen(const char* filename);
@@ -68,8 +64,4 @@
#endif // ADB_HOST
-#ifdef __cplusplus
-}
-#endif
-
#endif // __ADB_AUTH_H
diff --git a/adb/adb_client.h b/adb/adb_client.h
index 9af176f..934362a 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -3,10 +3,6 @@
#include "adb.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* connect to adb, connect to the named service, and return
** a valid fd for interacting with that service upon success
** or a negative number on failure
@@ -58,8 +54,4 @@
*/
int adb_status(int fd);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/adb/adb_io.h b/adb/adb_io.h
index 7d09e7b..8d237ce 100644
--- a/adb/adb_io.h
+++ b/adb/adb_io.h
@@ -20,10 +20,6 @@
#include <stdbool.h>
#include <sys/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*
* Reads exactly len bytes from fd into buf.
*
@@ -46,8 +42,4 @@
/* Same as WriteFdExactly, but with an implicit len = strlen(buf). */
bool WriteStringFully(int fd, const char* str);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* ADB_IO_H */
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index 84b9c64..a1a5ddb 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -190,17 +190,17 @@
return result;
}
-int remove_listener(const char *local_name, atransport* transport)
+install_status_t remove_listener(const char *local_name, atransport* transport)
{
alistener *l;
for (l = listener_list.next; l != &listener_list; l = l->next) {
if (!strcmp(local_name, l->local_name)) {
listener_disconnect(l, l->transport);
- return 0;
+ return INSTALL_STATUS_OK;
}
}
- return -1;
+ return INSTALL_STATUS_LISTENER_NOT_FOUND;
}
void remove_all_listeners(void)
@@ -268,10 +268,10 @@
listener->fd = local_name_to_fd(local_name);
if (listener->fd < 0) {
+ printf("cannot bind '%s': %s\n", local_name, strerror(errno));
free(listener->local_name);
free(listener->connect_to);
free(listener);
- printf("cannot bind '%s'\n", local_name);
return INSTALL_STATUS_CANNOT_BIND;
}
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
index 14fdcd6..f55fdee 100644
--- a/adb/adb_listeners.h
+++ b/adb/adb_listeners.h
@@ -19,17 +19,14 @@
#include "adb.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// error/status codes for install_listener.
-typedef enum {
+enum install_status_t {
INSTALL_STATUS_OK = 0,
INSTALL_STATUS_INTERNAL_ERROR = -1,
INSTALL_STATUS_CANNOT_BIND = -2,
INSTALL_STATUS_CANNOT_REBIND = -3,
-} install_status_t;
+ INSTALL_STATUS_LISTENER_NOT_FOUND = -4,
+};
extern alistener listener_list;
@@ -44,11 +41,7 @@
int format_listeners(char* buf, size_t buflen);
-int remove_listener(const char *local_name, atransport* transport);
+install_status_t remove_listener(const char* local_name, atransport* transport);
void remove_all_listeners(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __ADB_LISTENERS_H */
diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
index fb17e89..5acaf80 100644
--- a/adb/adb_main.cpp
+++ b/adb/adb_main.cpp
@@ -383,7 +383,7 @@
/* If adbd runs inside the emulator this will enable adb tracing via
* adb-debug qemud service in the emulator. */
adb_qemu_trace_init();
- while (1) {
+ while (true) {
int c;
int option_index = 0;
static struct option opts[] = {
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
index ef5dc24..32b6ae4 100644
--- a/adb/adb_trace.h
+++ b/adb/adb_trace.h
@@ -23,10 +23,6 @@
#include <stdio.h>
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */
#define ADB_TRACE 1
@@ -34,7 +30,7 @@
* forget to update the corresponding 'tags' table in
* the adb_trace_init() function implemented in adb.c
*/
-typedef enum {
+enum AdbTrace {
TRACE_ADB = 0, /* 0x001 */
TRACE_SOCKETS,
TRACE_PACKETS,
@@ -47,7 +43,7 @@
TRACE_SERVICES,
TRACE_AUTH,
TRACE_FDEVENT,
-} AdbTrace;
+} ;
#if ADB_TRACE
@@ -148,8 +144,4 @@
# define ADB_TRACING 0
#endif /* ADB_TRACE */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __ADB_TRACE_H */
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
new file mode 100644
index 0000000..f10c143
--- /dev/null
+++ b/adb/adb_utils.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "adb_utils.h"
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "sysdeps.h"
+
+bool getcwd(std::string* s) {
+ char* cwd = getcwd(nullptr, 0);
+ if (cwd != nullptr) *s = cwd;
+ free(cwd);
+ return (cwd != nullptr);
+}
+
+bool directory_exists(const std::string& path) {
+ struct stat sb;
+ return lstat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
+}
+
+std::string escape_arg(const std::string& s) {
+ std::string result = s;
+
+ // Insert a \ before any ' in the string.
+ for (auto it = result.begin(); it != result.end(); ++it) {
+ if (*it == '\'') {
+ it = result.insert(it, '\\') + 1;
+ }
+ }
+
+ // Prefix and suffix the whole string with '.
+ result.insert(result.begin(), '\'');
+ result.push_back('\'');
+ return result;
+}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
new file mode 100644
index 0000000..4b64afa
--- /dev/null
+++ b/adb/adb_utils.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ADB_UTILS_H_
+#define _ADB_UTILS_H_
+
+#include <string>
+
+bool getcwd(std::string* cwd);
+bool directory_exists(const std::string& path);
+
+std::string escape_arg(const std::string& s);
+
+#endif
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
new file mode 100644
index 0000000..a395079
--- /dev/null
+++ b/adb/adb_utils_test.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "adb_utils.h"
+
+#include <gtest/gtest.h>
+
+TEST(adb_utils, directory_exists) {
+ ASSERT_TRUE(directory_exists("/proc"));
+ ASSERT_FALSE(directory_exists("/proc/self")); // Symbolic link.
+ ASSERT_FALSE(directory_exists("/proc/does-not-exist"));
+}
+
+TEST(adb_utils, escape_arg) {
+ ASSERT_EQ(R"('')", escape_arg(""));
+
+ ASSERT_EQ(R"('abc')", escape_arg("abc"));
+
+ ASSERT_EQ(R"(' abc')", escape_arg(" abc"));
+ ASSERT_EQ(R"('\'abc')", escape_arg("'abc"));
+ ASSERT_EQ(R"('"abc')", escape_arg("\"abc"));
+ ASSERT_EQ(R"('\abc')", escape_arg("\\abc"));
+ ASSERT_EQ(R"('(abc')", escape_arg("(abc"));
+ ASSERT_EQ(R"(')abc')", escape_arg(")abc"));
+
+ ASSERT_EQ(R"('abc abc')", escape_arg("abc abc"));
+ ASSERT_EQ(R"('abc\'abc')", escape_arg("abc'abc"));
+ ASSERT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
+ ASSERT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
+ ASSERT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
+ ASSERT_EQ(R"('abc)abc')", escape_arg("abc)abc"));
+
+ ASSERT_EQ(R"('abc ')", escape_arg("abc "));
+ ASSERT_EQ(R"('abc\'')", escape_arg("abc'"));
+ ASSERT_EQ(R"('abc"')", escape_arg("abc\""));
+ ASSERT_EQ(R"('abc\')", escape_arg("abc\\"));
+ ASSERT_EQ(R"('abc(')", escape_arg("abc("));
+ ASSERT_EQ(R"('abc)')", escape_arg("abc)"));
+}
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 19a2fee..58e1ade 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -21,6 +21,7 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
@@ -30,6 +31,10 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <string>
+
+#include <base/stringprintf.h>
+
#if !defined(_WIN32)
#include <termios.h>
#include <unistd.h>
@@ -39,49 +44,38 @@
#include "adb_auth.h"
#include "adb_client.h"
#include "adb_io.h"
+#include "adb_utils.h"
#include "file_sync_service.h"
static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...);
-int find_sync_dirs(const char *srcarg,
- char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
- char **oem_srcdir_out);
-int install_app(transport_type transport, const char* serial, int argc,
- const char** argv);
-int install_multiple_app(transport_type transport, const char* serial, int argc,
+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);
-int uninstall_app(transport_type transport, const char* serial, int argc,
- const char** argv);
-static const char *gProductOutPath = NULL;
+static std::string gProductOutPath;
extern int gListenAll;
-static char *product_file(const char *extra)
-{
- if (gProductOutPath == NULL) {
+static std::string product_file(const char *extra) {
+ if (gProductOutPath.empty()) {
fprintf(stderr, "adb: Product directory not specified; "
"use -p or define ANDROID_PRODUCT_OUT\n");
exit(1);
}
- int n = strlen(gProductOutPath) + strlen(extra) + 2;
- char* x = reinterpret_cast<char*>(malloc(n));
- if (x == 0) {
- fprintf(stderr, "adb: Out of memory (product_file())\n");
- exit(1);
- }
-
- snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
- return x;
+ return android::base::StringPrintf("%s%s%s",
+ gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
}
-void version(FILE * out) {
+static void version(FILE* out) {
fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
- ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
+ ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
}
-void help()
-{
+static void help() {
version(stderr);
fprintf(stderr,
@@ -241,8 +235,7 @@
);
}
-int usage()
-{
+static int usage() {
help();
return 1;
}
@@ -328,7 +321,7 @@
stdin_raw_init(STDIN_FILENO);
}
- for (;;) {
+ while (true) {
if (inFd == STDIN_FILENO) {
len = unix_read(inFd, buf, BUFSIZE);
} else {
@@ -414,8 +407,7 @@
return 0;
}
-int interactive_shell(void)
-{
+static int interactive_shell() {
adb_thread_t thr;
int fdi, fd;
@@ -453,8 +445,8 @@
}
}
-int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
- unsigned progress)
+static int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
+ unsigned progress)
{
char buf[4096];
unsigned total;
@@ -512,23 +504,6 @@
return 0;
}
-
-int adb_download(const char *service, const char *fn, unsigned progress)
-{
- void *data;
- unsigned sz;
-
- data = load_file(fn, &sz);
- if(data == 0) {
- fprintf(stderr,"* cannot read '%s' *\n", fn);
- return -1;
- }
-
- int status = adb_download_buffer(service, fn, data, sz, progress);
- free(data);
- return status;
-}
-
#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
/*
@@ -550,7 +525,7 @@
* - When the other side sends "DONEDONE" instead of a block number,
* we hang up.
*/
-int adb_sideload_host(const char* fn) {
+static int adb_sideload_host(const char* fn) {
unsigned sz;
size_t xfer = 0;
int status;
@@ -579,7 +554,7 @@
opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
- for (;;) {
+ while (true) {
if (!ReadFdExactly(fd, buf, 8)) {
fprintf(stderr, "* failed to read command: %s\n", adb_error());
status = -1;
@@ -681,50 +656,6 @@
}
}
-static int should_escape(const char c)
-{
- return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
-}
-
-/* Duplicate and escape given argument. */
-static char *escape_arg(const char *s)
-{
- const char *ts;
- size_t alloc_len;
- char *ret;
- char *dest;
-
- alloc_len = 0;
- for (ts = s; *ts != '\0'; ts++) {
- alloc_len++;
- if (should_escape(*ts)) {
- alloc_len++;
- }
- }
-
- if (alloc_len == 0) {
- // Preserve empty arguments
- ret = (char *) malloc(3);
- ret[0] = '\"';
- ret[1] = '\"';
- ret[2] = '\0';
- return ret;
- }
-
- ret = (char *) malloc(alloc_len + 1);
- dest = ret;
-
- for (ts = s; *ts != '\0'; ts++) {
- if (should_escape(*ts)) {
- *dest++ = '\\';
- }
- *dest++ = *ts;
- }
- *dest++ = '\0';
-
- return ret;
-}
-
/**
* Run ppp in "notty" mode against a resource listed as the first parameter
* eg:
@@ -732,8 +663,7 @@
* ppp dev:/dev/omap_csmi_tty0 <ppp options>
*
*/
-int ppp(int argc, const char **argv)
-{
+static int ppp(int argc, const char** argv) {
#if defined(_WIN32)
fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
return -1;
@@ -798,14 +728,12 @@
#endif /* !defined(_WIN32) */
}
-static int send_shellcommand(transport_type transport, const char* serial,
- char* buf)
-{
- int fd, ret;
-
- for(;;) {
- fd = adb_connect(buf);
- if(fd >= 0)
+static int send_shell_command(transport_type transport, const char* serial,
+ const std::string& command) {
+ int fd;
+ while (true) {
+ fd = adb_connect(command.c_str());
+ if (fd >= 0)
break;
fprintf(stderr,"- waiting for device -\n");
adb_sleep_ms(1000);
@@ -813,41 +741,30 @@
}
read_and_dump(fd);
- ret = adb_close(fd);
- if (ret)
+ int rc = adb_close(fd);
+ if (rc) {
perror("close");
-
- return ret;
+ }
+ return rc;
}
-static int logcat(transport_type transport, const char* serial, int argc,
- const char** argv)
-{
- char buf[4096];
+static int logcat(transport_type transport, const char* serial, int argc, const char** argv) {
+ char* log_tags = getenv("ANDROID_LOG_TAGS");
+ std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
- char *log_tags;
- char *quoted;
-
- log_tags = getenv("ANDROID_LOG_TAGS");
- quoted = escape_arg(log_tags == NULL ? "" : log_tags);
- snprintf(buf, sizeof(buf),
- "shell:export ANDROID_LOG_TAGS=\"%s\"; exec logcat", quoted);
- free(quoted);
+ std::string cmd = "shell:export ANDROID_LOG_TAGS=\"" + quoted + "\"; exec logcat";
if (!strcmp(argv[0], "longcat")) {
- strncat(buf, " -v long", sizeof(buf) - 1);
+ cmd += " -v long";
}
- argc -= 1;
- argv += 1;
- while(argc-- > 0) {
- quoted = escape_arg(*argv++);
- strncat(buf, " ", sizeof(buf) - 1);
- strncat(buf, quoted, sizeof(buf) - 1);
- free(quoted);
+ --argc;
+ ++argv;
+ while (argc-- > 0) {
+ cmd += " " + escape_arg(*argv++);
}
- send_shellcommand(transport, serial, buf);
+ send_shell_command(transport, serial, cmd);
return 0;
}
@@ -871,21 +788,17 @@
}
static int backup(int argc, const char** argv) {
- char buf[4096];
- char default_name[32];
- const char* filename = strcpy(default_name, "./backup.ab");
- int fd, outFd;
- int i, j;
+ const char* filename = "./backup.ab";
/* find, extract, and use any -f argument */
- for (i = 1; i < argc; i++) {
+ for (int i = 1; i < argc; i++) {
if (!strcmp("-f", argv[i])) {
if (i == argc-1) {
fprintf(stderr, "adb: -f passed with no filename\n");
return usage();
}
filename = argv[i+1];
- for (j = i+2; j <= argc; ) {
+ for (int j = i+2; j <= argc; ) {
argv[i++] = argv[j++];
}
argc -= 2;
@@ -898,20 +811,21 @@
adb_unlink(filename);
mkdirs(filename);
- outFd = adb_creat(filename, 0640);
+ int outFd = adb_creat(filename, 0640);
if (outFd < 0) {
fprintf(stderr, "adb: unable to open file %s\n", filename);
return -1;
}
- snprintf(buf, sizeof(buf), "backup");
- for (argc--, argv++; argc; argc--, argv++) {
- strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
- strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
+ std::string cmd = "backup:";
+ --argc;
+ ++argv;
+ while (argc-- > 0) {
+ cmd += " " + escape_arg(*argv++);
}
- D("backup. filename=%s buf=%s\n", filename, buf);
- fd = adb_connect(buf);
+ D("backup. filename=%s cmd=%s\n", filename, cmd.c_str());
+ int fd = adb_connect(cmd.c_str());
if (fd < 0) {
fprintf(stderr, "adb: unable to connect for backup\n");
adb_close(outFd);
@@ -954,81 +868,9 @@
return 0;
}
-#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
-static int top_works(const char *top)
-{
- if (top != NULL && adb_is_absolute_host_path(top)) {
- char path_buf[PATH_MAX];
- snprintf(path_buf, sizeof(path_buf),
- "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
- return access(path_buf, F_OK) == 0;
- }
- return 0;
-}
-
-static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
-{
- strcpy(path_buf, indir);
- while (1) {
- if (top_works(path_buf)) {
- return path_buf;
- }
- char *s = adb_dirstop(path_buf);
- if (s != NULL) {
- *s = '\0';
- } else {
- path_buf[0] = '\0';
- return NULL;
- }
- }
-}
-
-static char *find_top(char path_buf[PATH_MAX])
-{
- char *top = getenv("ANDROID_BUILD_TOP");
- if (top != NULL && top[0] != '\0') {
- if (!top_works(top)) {
- fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
- return NULL;
- }
- } else {
- top = getenv("TOP");
- if (top != NULL && top[0] != '\0') {
- if (!top_works(top)) {
- fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
- return NULL;
- }
- } else {
- top = NULL;
- }
- }
-
- if (top != NULL) {
- /* The environment pointed to a top directory that works.
- */
- strcpy(path_buf, top);
- return path_buf;
- }
-
- /* The environment didn't help. Walk up the tree from the CWD
- * to see if we can find the top.
- */
- char dir[PATH_MAX];
- top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
- if (top == NULL) {
- /* If the CWD isn't under a good-looking top, see if the
- * executable is.
- */
- get_my_path(dir, PATH_MAX);
- top = find_top_from(dir, path_buf);
- }
- return top;
-}
-
/* <hint> may be:
* - A simple product name
* e.g., "sooner"
-TODO: debug? sooner-debug, sooner:debug?
* - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
* e.g., "out/target/product/sooner"
* - An absolute path to the PRODUCT_OUT dir
@@ -1037,62 +879,52 @@
* Given <hint>, try to construct an absolute path to the
* ANDROID_PRODUCT_OUT dir.
*/
-static const char *find_product_out_path(const char *hint)
-{
- static char path_buf[PATH_MAX];
-
+static std::string find_product_out_path(const char* hint) {
if (hint == NULL || hint[0] == '\0') {
- return NULL;
+ return "";
}
- /* If it's already absolute, don't bother doing any work.
- */
+ // If it's already absolute, don't bother doing any work.
if (adb_is_absolute_host_path(hint)) {
- strcpy(path_buf, hint);
- return path_buf;
+ return hint;
}
- /* If there are any slashes in it, assume it's a relative path;
- * make it absolute.
- */
- if (adb_dirstart(hint) != NULL) {
- if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
- fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
- return NULL;
+ // If there are any slashes in it, assume it's a relative path;
+ // make it absolute.
+ if (adb_dirstart(hint) != nullptr) {
+ std::string cwd;
+ if (!getcwd(&cwd)) {
+ fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
+ return "";
}
- if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
- fprintf(stderr, "adb: Couldn't assemble path\n");
- return NULL;
- }
- strcat(path_buf, OS_PATH_SEPARATOR_STR);
- strcat(path_buf, hint);
- return path_buf;
+ return android::base::StringPrintf("%s%s%s", cwd.c_str(), OS_PATH_SEPARATOR_STR, hint);
}
- /* It's a string without any slashes. Try to do something with it.
- *
- * Try to find the root of the build tree, and build a PRODUCT_OUT
- * path from there.
- */
- char top_buf[PATH_MAX];
- const char *top = find_top(top_buf);
- if (top == NULL) {
- fprintf(stderr, "adb: Couldn't find top of build tree\n");
- return NULL;
+ // It's a string without any slashes. Try to do something with it.
+ //
+ // Try to find the root of the build tree, and build a PRODUCT_OUT
+ // path from there.
+ char* top = getenv("ANDROID_BUILD_TOP");
+ if (top == nullptr) {
+ fprintf(stderr, "adb: ANDROID_BUILD_TOP not set!\n");
+ return "";
}
-//TODO: if we have a way to indicate debug, look in out/debug/target/...
- snprintf(path_buf, sizeof(path_buf),
- "%s" OS_PATH_SEPARATOR_STR
- "out" OS_PATH_SEPARATOR_STR
- "target" OS_PATH_SEPARATOR_STR
- "product" OS_PATH_SEPARATOR_STR
- "%s", top_buf, hint);
- if (access(path_buf, F_OK) < 0) {
- fprintf(stderr, "adb: Couldn't find a product dir "
- "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
- return NULL;
+
+ std::string path = top;
+ path += OS_PATH_SEPARATOR_STR;
+ path += "out";
+ path += OS_PATH_SEPARATOR_STR;
+ path += "target";
+ path += OS_PATH_SEPARATOR_STR;
+ path += "product";
+ path += OS_PATH_SEPARATOR_STR;
+ path += hint;
+ if (!directory_exists(path)) {
+ fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
+ "\"%s\" doesn't exist\n", hint, path.c_str());
+ return "";
}
- return path_buf;
+ return path;
}
static void parse_push_pull_args(const char **arg, int narg, char const **path1,
@@ -1147,15 +979,14 @@
const char* serial = NULL;
const char* server_port_str = NULL;
- /* If defined, this should be an absolute path to
- * the directory containing all of the various system images
- * for a particular product. If not defined, and the adb
- * command requires this information, then the user must
- * specify the path using "-p".
- */
- gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
- if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
- gProductOutPath = NULL;
+ // If defined, this should be an absolute path to
+ // the directory containing all of the various system images
+ // for a particular product. If not defined, and the adb
+ // command requires this information, then the user must
+ // specify the path using "-p".
+ char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
+ if (ANDROID_PRODUCT_OUT != nullptr) {
+ gProductOutPath = ANDROID_PRODUCT_OUT;
}
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
@@ -1196,9 +1027,8 @@
product = argv[0] + 2;
}
gProductOutPath = find_product_out_path(product);
- if (gProductOutPath == NULL) {
- fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
- product);
+ if (gProductOutPath.empty()) {
+ fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
return usage();
}
} else if (argv[0][0]=='-' && argv[0][1]=='s') {
@@ -1370,9 +1200,6 @@
return adb_send_emulator_command(argc, argv);
}
else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
- int r;
- int fd;
-
char h = (argv[0][0] == 'h');
if (h) {
@@ -1390,19 +1217,18 @@
return r;
}
- snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
+ std::string cmd = "shell:";
+ cmd += argv[1];
argc -= 2;
argv += 2;
while (argc-- > 0) {
- char *quoted = escape_arg(*argv++);
- strncat(buf, " ", sizeof(buf) - 1);
- strncat(buf, quoted, sizeof(buf) - 1);
- free(quoted);
+ cmd += " " + escape_arg(*argv++);
}
- for(;;) {
- D("interactive shell loop. buff=%s\n", buf);
- fd = adb_connect(buf);
+ while (true) {
+ D("interactive shell loop. cmd=%s\n", cmd.c_str());
+ int fd = adb_connect(cmd.c_str());
+ int r;
if (fd >= 0) {
D("about to read_and_dump(fd=%d)\n", fd);
read_and_dump(fd);
@@ -1430,19 +1256,16 @@
}
else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
int exec_in = !strcmp(argv[0], "exec-in");
- int fd;
- snprintf(buf, sizeof buf, "exec:%s", argv[1]);
+ std::string cmd = "exec:";
+ cmd += argv[1];
argc -= 2;
argv += 2;
while (argc-- > 0) {
- char *quoted = escape_arg(*argv++);
- strncat(buf, " ", sizeof(buf) - 1);
- strncat(buf, quoted, sizeof(buf) - 1);
- free(quoted);
+ cmd += " " + escape_arg(*argv++);
}
- fd = adb_connect(buf);
+ int fd = adb_connect(cmd.c_str());
if (fd < 0) {
fprintf(stderr, "error: %s\n", adb_error());
return -1;
@@ -1634,46 +1457,49 @@
return uninstall_app(ttype, serial, argc, argv);
}
else if (!strcmp(argv[0], "sync")) {
- const char* srcarg;
- char *system_srcpath, *data_srcpath, *vendor_srcpath, *oem_srcpath;
-
- int listonly = 0;
-
- int ret;
+ std::string src;
+ bool list_only = false;
if (argc < 2) {
- /* No local path was specified. */
- srcarg = NULL;
+ // No local path was specified.
+ src = "";
} else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
- listonly = 1;
+ list_only = true;
if (argc == 3) {
- srcarg = argv[2];
+ src = argv[2];
} else {
- srcarg = NULL;
+ src = "";
}
} else if (argc == 2) {
- /* A local path or "android"/"data" arg was specified. */
- srcarg = argv[1];
+ // A local path or "android"/"data" arg was specified.
+ src = argv[1];
} else {
return usage();
}
- ret = find_sync_dirs(srcarg, &system_srcpath, &data_srcpath, &vendor_srcpath,
- &oem_srcpath);
- if (ret != 0) return usage();
- if (system_srcpath != NULL)
- ret = do_sync_sync(system_srcpath, "/system", listonly);
- if (ret == 0 && vendor_srcpath != NULL)
- ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
- if(ret == 0 && oem_srcpath != NULL)
- ret = do_sync_sync(oem_srcpath, "/oem", listonly);
- if (ret == 0 && data_srcpath != NULL)
- ret = do_sync_sync(data_srcpath, "/data", listonly);
+ if (src != "" &&
+ src != "system" && src != "data" && src != "vendor" && src != "oem") {
+ return usage();
+ }
- free(system_srcpath);
- free(vendor_srcpath);
- free(oem_srcpath);
- free(data_srcpath);
- return ret;
+ std::string system_src_path = product_file("system");
+ std::string data_src_path = product_file("data");
+ std::string vendor_src_path = product_file("vendor");
+ std::string oem_src_path = product_file("oem");
+
+ int rc = 0;
+ if (rc == 0 && (src.empty() || src == "system")) {
+ rc = do_sync_sync(system_src_path, "/system", list_only);
+ }
+ if (rc == 0 && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
+ rc = do_sync_sync(vendor_src_path, "/vendor", list_only);
+ }
+ if (rc == 0 && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
+ rc = do_sync_sync(oem_src_path, "/oem", list_only);
+ }
+ if (rc == 0 && (src.empty() || src == "data")) {
+ rc = do_sync_sync(data_src_path, "/data", list_only);
+ }
+ return rc;
}
/* passthrough commands */
else if (!strcmp(argv[0],"get-state") ||
@@ -1768,84 +1594,21 @@
return adb_commandline(argc, argv);
}
-int find_sync_dirs(const char *srcarg,
- char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
- char **oem_srcdir_out)
-{
- char *system_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL, *oem_srcdir = NULL;
- struct stat st;
-
- if(srcarg == NULL) {
- system_srcdir = product_file("system");
- data_srcdir = product_file("data");
- vendor_srcdir = product_file("vendor");
- oem_srcdir = product_file("oem");
- // Check if vendor partition exists.
- if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
- vendor_srcdir = NULL;
- // Check if oem partition exists.
- if (lstat(oem_srcdir, &st) || !S_ISDIR(st.st_mode))
- oem_srcdir = NULL;
- } else {
- // srcarg may be "data", "system", "vendor", "oem" or NULL.
- // If srcarg is NULL, then all partitions are synced.
- if(strcmp(srcarg, "system") == 0) {
- system_srcdir = product_file("system");
- } else if(strcmp(srcarg, "data") == 0) {
- data_srcdir = product_file("data");
- } else if(strcmp(srcarg, "vendor") == 0) {
- vendor_srcdir = product_file("vendor");
- } else if(strcmp(srcarg, "oem") == 0) {
- oem_srcdir = product_file("oem");
- } else {
- // It's not "system", "data", "vendor", or "oem".
- return 1;
- }
- }
-
- if(system_srcdir_out != NULL)
- *system_srcdir_out = system_srcdir;
- else
- free(system_srcdir);
-
- if(vendor_srcdir_out != NULL)
- *vendor_srcdir_out = vendor_srcdir;
- else
- free(vendor_srcdir);
-
- if(oem_srcdir_out != NULL)
- *oem_srcdir_out = oem_srcdir;
- else
- free(oem_srcdir);
-
- if(data_srcdir_out != NULL)
- *data_srcdir_out = data_srcdir;
- else
- free(data_srcdir);
-
- return 0;
-}
-
static int pm_command(transport_type transport, const char* serial,
int argc, const char** argv)
{
- char buf[4096];
+ std::string cmd = "shell:pm";
- snprintf(buf, sizeof(buf), "shell:pm");
-
- while(argc-- > 0) {
- char *quoted = escape_arg(*argv++);
- strncat(buf, " ", sizeof(buf) - 1);
- strncat(buf, quoted, sizeof(buf) - 1);
- free(quoted);
+ while (argc-- > 0) {
+ cmd += " " + escape_arg(*argv++);
}
- send_shellcommand(transport, serial, buf);
+ send_shell_command(transport, serial, cmd);
return 0;
}
-int uninstall_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)
{
/* if the user choose the -k option, we refuse to do it until devices are
out with the option to uninstall the remaining data somehow (adb/ui) */
@@ -1865,15 +1628,8 @@
static int delete_file(transport_type transport, const char* serial, char* filename)
{
- char buf[4096];
- char* quoted;
-
- snprintf(buf, sizeof(buf), "shell:rm -f ");
- quoted = escape_arg(filename);
- strncat(buf, quoted, sizeof(buf)-1);
- free(quoted);
-
- send_shellcommand(transport, serial, buf);
+ std::string cmd = "shell:rm -f " + escape_arg(filename);
+ send_shell_command(transport, serial, cmd);
return 0;
}
@@ -1888,8 +1644,8 @@
}
}
-int install_app(transport_type transport, const char* serial, int argc,
- const char** argv)
+static int install_app(transport_type transport, const char* serial, int argc,
+ const char** argv)
{
static const char *const DATA_DEST = "/data/local/tmp/%s";
static const char *const SD_DEST = "/sdcard/tmp/%s";
@@ -1942,13 +1698,12 @@
return err;
}
-int install_multiple_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)
{
- char buf[1024];
int i;
struct stat sb;
- unsigned long long total_size = 0;
+ uint64_t total_size = 0;
// Find all APK arguments starting at end.
// All other arguments passed through verbatim.
@@ -1974,20 +1729,22 @@
return 1;
}
- snprintf(buf, sizeof(buf), "exec:pm install-create -S %lld", total_size);
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+ std::string cmd = android::base::StringPrintf("exec:pm install-create -S %u", (unsigned) total_size);
+#else
+ std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+#endif
for (i = 1; i < first_apk; i++) {
- char *quoted = escape_arg(argv[i]);
- strncat(buf, " ", sizeof(buf) - 1);
- strncat(buf, quoted, sizeof(buf) - 1);
- free(quoted);
+ cmd += " " + escape_arg(argv[i]);
}
// Create install session
- int fd = adb_connect(buf);
+ int fd = adb_connect(cmd.c_str());
if (fd < 0) {
fprintf(stderr, "Connect error for create: %s\n", adb_error());
return -1;
}
+ char buf[BUFSIZ];
read_status_line(fd, buf, sizeof(buf));
adb_close(fd);
@@ -2016,8 +1773,15 @@
goto finalize_session;
}
- snprintf(buf, sizeof(buf), "exec:pm install-write -S %lld %d %d_%s -",
- (long long int) sb.st_size, session_id, i, get_basename(file));
+#if defined(_WIN32) // Remove when we're using clang for Win32.
+ std::string cmd = android::base::StringPrintf(
+ "exec:pm install-write -S %u %d %d_%s -",
+ (unsigned) sb.st_size, session_id, i, get_basename(file));
+#else
+ std::string cmd = android::base::StringPrintf(
+ "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
+ static_cast<uint64_t>(sb.st_size), session_id, i, get_basename(file));
+#endif
int localFd = adb_open(file, O_RDONLY);
if (localFd < 0) {
@@ -2026,7 +1790,7 @@
goto finalize_session;
}
- int remoteFd = adb_connect(buf);
+ int remoteFd = adb_connect(cmd.c_str());
if (remoteFd < 0) {
fprintf(stderr, "Connect error for write: %s\n", adb_error());
adb_close(localFd);
diff --git a/adb/fdevent.h b/adb/fdevent.h
index a8102ca..8d84b29 100644
--- a/adb/fdevent.h
+++ b/adb/fdevent.h
@@ -19,10 +19,6 @@
#include <stdint.h> /* for int64_t */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* events that may be observed */
#define FDE_READ 0x0001
#define FDE_WRITE 0x0002
@@ -32,7 +28,7 @@
/* features that may be set (via the events set/add/del interface) */
#define FDE_DONT_CLOSE 0x0080
-typedef struct fdevent fdevent;
+struct fdevent;
typedef void (*fd_func)(int fd, unsigned events, void *userdata);
@@ -82,8 +78,4 @@
void *arg;
};
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 4ba730b..49d8783 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -130,8 +130,6 @@
return -1;
}
-typedef struct syncsendbuf syncsendbuf;
-
struct syncsendbuf {
unsigned id;
unsigned size;
@@ -557,8 +555,6 @@
}
}
-typedef struct copyinfo copyinfo;
-
struct copyinfo
{
copyinfo *next;
@@ -804,12 +800,12 @@
}
-typedef struct {
+struct sync_ls_build_list_cb_args {
copyinfo **filelist;
copyinfo **dirlist;
const char *rpath;
const char *lpath;
-} sync_ls_build_list_cb_args;
+};
void
sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time,
@@ -1031,18 +1027,18 @@
}
}
-int do_sync_sync(const char *lpath, const char *rpath, int listonly)
+int do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only)
{
- fprintf(stderr,"syncing %s...\n",rpath);
+ fprintf(stderr, "syncing %s...\n", rpath.c_str());
int fd = adb_connect("sync:");
- if(fd < 0) {
- fprintf(stderr,"error: %s\n", adb_error());
+ if (fd < 0) {
+ fprintf(stderr, "error: %s\n", adb_error());
return 1;
}
BEGIN();
- if(copy_local_dir_remote(fd, lpath, rpath, 1, listonly)){
+ if (copy_local_dir_remote(fd, lpath.c_str(), rpath.c_str(), 1, list_only)) {
return 1;
} else {
END();
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 5b69a63..344eb98 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -17,9 +17,7 @@
#ifndef _FILE_SYNC_SERVICE_H_
#define _FILE_SYNC_SERVICE_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <string>
#define htoll(x) (x)
#define ltohl(x) (x)
@@ -38,7 +36,7 @@
#define ID_FAIL MKID('F','A','I','L')
#define ID_QUIT MKID('Q','U','I','T')
-typedef union {
+union syncmsg {
unsigned id;
struct {
unsigned id;
@@ -65,19 +63,15 @@
unsigned id;
unsigned msglen;
} status;
-} syncmsg;
+} ;
void file_sync_service(int fd, void *cookie);
int do_sync_ls(const char *path);
int do_sync_push(const char *lpath, const char *rpath, int show_progress);
-int do_sync_sync(const char *lpath, const char *rpath, int listonly);
+int do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only);
int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int pullTime);
#define SYNC_DATA_MAX (64*1024)
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/adb/jdwp_service.cpp b/adb/jdwp_service.cpp
index 9cf084e..c0f7ec2 100644
--- a/adb/jdwp_service.cpp
+++ b/adb/jdwp_service.cpp
@@ -121,7 +121,6 @@
#include <sys/socket.h>
#include <sys/un.h>
-typedef struct JdwpProcess JdwpProcess;
struct JdwpProcess {
JdwpProcess* next;
JdwpProcess* prev;
@@ -455,11 +454,10 @@
#define JDWP_CONTROL_NAME "\0jdwp-control"
#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME)-1)
-typedef struct {
+struct JdwpControl {
int listen_socket;
fdevent* fde;
-
-} JdwpControl;
+};
static void
@@ -570,10 +568,10 @@
** this simply returns the list of known JDWP process pids
**/
-typedef struct {
+struct JdwpSocket {
asocket socket;
int pass;
-} JdwpSocket;
+};
static void
jdwp_socket_close( asocket* s )
@@ -642,8 +640,6 @@
** to the client...
**/
-typedef struct JdwpTracker JdwpTracker;
-
struct JdwpTracker {
asocket socket;
JdwpTracker* next;
@@ -754,4 +750,3 @@
}
#endif /* !ADB_HOST */
-
diff --git a/adb/qemu_tracing.h b/adb/qemu_tracing.h
index bf80457..ff42d4f 100644
--- a/adb/qemu_tracing.h
+++ b/adb/qemu_tracing.h
@@ -21,16 +21,8 @@
#ifndef __QEMU_TRACING_H
#define __QEMU_TRACING_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Initializes connection with the adb-debug qemud service in the emulator. */
int adb_qemu_trace_init(void);
void adb_qemu_trace(const char* fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __QEMU_TRACING_H */
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index b150274..1eaee73 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -31,6 +31,7 @@
#include "adb.h"
#include "adb_io.h"
+#include "adb_utils.h"
#include "cutils/properties.h"
static int system_ro = 1;
@@ -56,11 +57,6 @@
return device;
}
-static bool has_partition(const char* path) {
- struct stat sb;
- return (lstat(path, &sb) == 0 && S_ISDIR(sb.st_mode));
-}
-
int make_block_device_writable(const std::string& dev) {
int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
if (fd == -1) {
@@ -90,7 +86,7 @@
}
static bool remount_partition(int fd, const char* partition, int* ro) {
- if (!has_partition(partition)) {
+ if (!directory_exists(partition)) {
return true;
}
if (remount(partition, ro)) {
diff --git a/adb/services.cpp b/adb/services.cpp
index 12eb406..ff13722 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -31,6 +31,8 @@
#include <unistd.h>
#endif
+#include <base/stringprintf.h>
+
#if !ADB_HOST
#include "base/file.h"
#include "cutils/android_reboot.h"
@@ -43,8 +45,6 @@
#include "remount_service.h"
#include "transport.h"
-typedef struct stinfo stinfo;
-
struct stinfo {
void (*func)(int fd, void *cookie);
int fd;
@@ -194,7 +194,7 @@
if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
// Don't return early. Give the reboot command time to take effect
// to avoid messing up scripts which do "adb reboot && adb wait-for-device"
- while (1) {
+ while (true) {
pause();
}
}
@@ -375,7 +375,7 @@
pid_t pid = (pid_t) (uintptr_t) cookie;
D("entered. fd=%d of pid=%d\n", fd, pid);
- for (;;) {
+ while (true) {
int status;
pid_t p = waitpid(pid, &status, 0);
if (p == pid) {
@@ -501,19 +501,8 @@
} else if(!strncmp(name, "unroot:", 7)) {
ret = create_service_thread(restart_unroot_service, NULL);
} else if(!strncmp(name, "backup:", 7)) {
- char* arg = strdup(name + 7);
- if (arg == NULL) return -1;
- char* c = arg;
- for (; *c != '\0'; c++) {
- if (*c == ':')
- *c = ' ';
- }
- char* cmd;
- if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) {
- ret = create_subproc_thread(cmd, SUBPROC_RAW);
- free(cmd);
- }
- free(arg);
+ ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s",
+ (name + 7)).c_str(), SUBPROC_RAW);
} else if(!strncmp(name, "restore:", 8)) {
ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW);
} else if(!strncmp(name, "tcpip:", 6)) {
@@ -559,12 +548,12 @@
D("wait_for_state %d\n", sinfo->state);
- const char* err = "unknown error";
- atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
- if(t != 0) {
+ 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);
} else {
- sendfailmsg(fd, err);
+ sendfailmsg(fd, error_msg.c_str());
}
if (sinfo->serial)
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 48d02d6..f468029 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -487,10 +487,10 @@
/* a Remote socket is used to send/receive data to/from a given transport object
** it needs to be closed when the transport is forcibly destroyed by the user
*/
-typedef struct aremotesocket {
+struct aremotesocket {
asocket socket;
adisconnect disconnect;
-} aremotesocket;
+};
static int remote_socket_enqueue(asocket *s, apacket *p)
{
@@ -827,12 +827,11 @@
}
#else /* !ADB_HOST */
if (s->transport == NULL) {
- const char* error_string = "unknown failure";
- s->transport = acquire_one_transport (CS_ANY,
- kTransportAny, NULL, &error_string);
+ std::string error_msg = "unknown failure";
+ s->transport = acquire_one_transport(CS_ANY, kTransportAny, NULL, &error_msg);
if (s->transport == NULL) {
- sendfailmsg(s->peer->fd, error_string);
+ sendfailmsg(s->peer->fd, error_msg.c_str());
goto fail;
}
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 2ad28fa..d9a1518 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -54,10 +54,6 @@
#include "fdevent.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define OS_PATH_SEPARATOR '\\'
#define OS_PATH_SEPARATOR_STR "\\"
#define ENV_PATH_SEPARATOR_STR ";"
@@ -296,10 +292,6 @@
#include <string.h>
#include <unistd.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define OS_PATH_SEPARATOR '/'
#define OS_PATH_SEPARATOR_STR "/"
#define ENV_PATH_SEPARATOR_STR ":"
@@ -540,8 +532,4 @@
#endif /* !_WIN32 */
-#ifdef __cplusplus
-}
-#endif
-
#endif /* _ADB_SYSDEPS_H */
diff --git a/adb/tests/test_adb.py b/adb/tests/test_adb.py
index f111b043..69dead2 100755
--- a/adb/tests/test_adb.py
+++ b/adb/tests/test_adb.py
@@ -267,6 +267,14 @@
adb.unroot()
adb.wait()
+ def test_argument_escaping(self):
+ """Make sure that argument escaping is somewhat sane."""
+ adb = AdbWrapper()
+
+ # http://b/19734868
+ result = adb.shell("sh -c 'echo hello; echo world'").splitlines()
+ self.assertEqual(["hello", "world"], result)
+
class AdbFile(unittest.TestCase):
SCRATCH_DIR = "/data/local/tmp"
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 4b9eeeb..37f9d7b 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -406,7 +406,6 @@
* number of client connections that want it through a single
* live TCP connection
*/
-typedef struct device_tracker device_tracker;
struct device_tracker {
asocket socket;
int update_needed;
@@ -536,7 +535,6 @@
}
#endif // ADB_HOST
-typedef struct tmsg tmsg;
struct tmsg
{
atransport *transport;
@@ -800,22 +798,20 @@
return !*to_test;
}
-atransport *acquire_one_transport(int state, transport_type ttype,
- const char* serial, const char** error_out)
+atransport* acquire_one_transport(int state, transport_type ttype,
+ const char* serial, std::string* error_out)
{
atransport *t;
atransport *result = NULL;
int ambiguous = 0;
retry:
- if (error_out)
- *error_out = "device not found";
+ if (error_out) *error_out = "device not found";
adb_mutex_lock(&transport_lock);
for (t = transport_list.next; t != &transport_list; t = t->next) {
if (t->connection_state == CS_NOPERM) {
- if (error_out)
- *error_out = "insufficient permissions for device";
+ if (error_out) *error_out = "insufficient permissions for device";
continue;
}
@@ -827,8 +823,7 @@
qual_match(serial, "model:", t->model, true) ||
qual_match(serial, "device:", t->device, false)) {
if (result) {
- if (error_out)
- *error_out = "more than one device";
+ if (error_out) *error_out = "more than one device";
ambiguous = 1;
result = NULL;
break;
@@ -838,8 +833,7 @@
} else {
if (ttype == kTransportUsb && t->type == kTransportUsb) {
if (result) {
- if (error_out)
- *error_out = "more than one device";
+ if (error_out) *error_out = "more than one device";
ambiguous = 1;
result = NULL;
break;
@@ -847,8 +841,7 @@
result = t;
} else if (ttype == kTransportLocal && t->type == kTransportLocal) {
if (result) {
- if (error_out)
- *error_out = "more than one emulator";
+ if (error_out) *error_out = "more than one emulator";
ambiguous = 1;
result = NULL;
break;
@@ -856,8 +849,7 @@
result = t;
} else if (ttype == kTransportAny) {
if (result) {
- if (error_out)
- *error_out = "more than one device and emulator";
+ if (error_out) *error_out = "more than one device and emulator";
ambiguous = 1;
result = NULL;
break;
@@ -870,29 +862,33 @@
if (result) {
if (result->connection_state == CS_UNAUTHORIZED) {
- if (error_out)
- *error_out = "device unauthorized. Please check the confirmation dialog on your device.";
+ if (error_out) {
+ *error_out = "device unauthorized.\n";
+ char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
+ *error_out += "This adbd's $ADB_VENDOR_KEYS is ";
+ *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
+ *error_out += "; try 'adb kill-server' if that seems wrong.\n";
+ *error_out += "Otherwise check for a confirmation dialog on your device.";
+ }
result = NULL;
}
- /* offline devices are ignored -- they are either being born or dying */
+ /* offline devices are ignored -- they are either being born or dying */
if (result && result->connection_state == CS_OFFLINE) {
- if (error_out)
- *error_out = "device offline";
+ if (error_out) *error_out = "device offline";
result = NULL;
}
- /* check for required connection state */
+
+ /* check for required connection state */
if (result && state != CS_ANY && result->connection_state != state) {
- if (error_out)
- *error_out = "invalid device state";
+ if (error_out) *error_out = "invalid device state";
result = NULL;
}
}
if (result) {
/* found one that we can take */
- if (error_out)
- *error_out = NULL;
+ if (error_out) *error_out = "success";
} else if (state != CS_ANY && (serial || !ambiguous)) {
adb_sleep_ms(1000);
goto retry;
diff --git a/adb/transport.h b/adb/transport.h
index 36a0e40..a2077e8 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -17,14 +17,11 @@
#ifndef __TRANSPORT_H
#define __TRANSPORT_H
-#include <stdbool.h>
#include <sys/types.h>
-#include "adb.h"
+#include <string>
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "adb.h"
#if ADB_TRACE
void dump_hex(const unsigned char* ptr, size_t len);
@@ -37,7 +34,7 @@
* If no suitable transport is found, error is set.
*/
atransport* acquire_one_transport(int state, transport_type ttype,
- const char* serial, const char** error_out);
+ const char* serial, std::string* error_out);
void add_transport_disconnect(atransport* t, adisconnect* dis);
void remove_transport_disconnect(atransport* t, adisconnect* dis);
void kick_transport(atransport* t);
@@ -74,8 +71,4 @@
asocket* create_device_tracker(void);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __TRANSPORT_H */
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index fe3c87f..30e6bf5 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -144,7 +144,7 @@
if(serverfd == -1) {
serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
if(serverfd < 0) {
- D("server: cannot bind socket yet\n");
+ D("server: cannot bind socket yet: %s\n", strerror(errno));
adb_sleep_ms(1000);
continue;
}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 8d670f8..6d21104 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -18,6 +18,7 @@
#include "sysdeps.h"
+#include <cutils/properties.h>
#include <dirent.h>
#include <errno.h>
#include <linux/usb/ch9.h>
@@ -163,7 +164,7 @@
struct usb_handle *usb = (struct usb_handle *)x;
int fd;
- while (1) {
+ while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
while (usb->fd != -1)
@@ -347,14 +348,14 @@
{
struct usb_handle *usb = (struct usb_handle *)x;
- while (1) {
+ while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
adb_cond_wait(&usb->notify, &usb->lock);
adb_mutex_unlock(&usb->lock);
- while (1) {
+ while (true) {
init_functionfs(usb);
if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
@@ -362,6 +363,7 @@
adb_sleep_ms(1000);
}
+ property_set("sys.usb.ffs.ready", "1");
D("[ usb_thread - registering device ]\n");
register_usb_transport(usb, 0, 0, 1);
diff --git a/base/include/base/strings.h b/base/include/base/strings.h
index ab56aad..3559342 100644
--- a/base/include/base/strings.h
+++ b/base/include/base/strings.h
@@ -25,7 +25,7 @@
// Splits a string into a vector of strings.
//
-// The string is split at each occurence of a character in delimiters.
+// The string is split at each occurrence of a character in delimiters.
//
// Empty splits will be omitted. I.e. Split("a,,b", ",") -> {"a", "b"}
//
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index b9e957f..7b2975b 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -74,6 +74,16 @@
LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host
endif
+# libc++ not available on windows yet
+ifneq ($(HOST_OS),windows)
+ LOCAL_CXX_STL := libc++_static
+endif
+
+# Don't add anything here, we don't want additional shared dependencies
+# on the host fastboot tool, and shared libraries that link against libc++
+# will violate ODR
+LOCAL_SHARED_LIBRARIES :=
+
include $(BUILD_HOST_EXECUTABLE)
my_dist_files := $(LOCAL_BUILT_MODULE)
diff --git a/include/cutils/dir_hash.h b/include/cutils/dir_hash.h
deleted file mode 100644
index fbb4d02..0000000
--- a/include/cutils/dir_hash.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-typedef enum {
- SHA_1,
-} HashAlgorithm;
-
-int get_file_hash(HashAlgorithm algorithm, const char *path,
- char *output_string, size_t max_output_string);
-
-int get_recursive_hash_manifest(HashAlgorithm algorithm,
- const char *directory_path,
- char **output_string);
diff --git a/include/cutils/partition_utils.h b/include/cutils/partition_utils.h
index 597df92..72ca80d 100644
--- a/include/cutils/partition_utils.h
+++ b/include/cutils/partition_utils.h
@@ -20,7 +20,6 @@
__BEGIN_DECLS
int partition_wiped(char *source);
-void erase_footer(const char *dev_path, long long size);
__END_DECLS
diff --git a/libcutils/dir_hash.c b/libcutils/dir_hash.c
deleted file mode 100644
index 098b5db..0000000
--- a/libcutils/dir_hash.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sha1.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include <sys/stat.h>
-
-#include <netinet/in.h>
-#include <resolv.h>
-
-#include <cutils/dir_hash.h>
-
-/**
- * Copies, if it fits within max_output_string bytes, into output_string
- * a hash of the contents, size, permissions, uid, and gid of the file
- * specified by path, using the specified algorithm. Returns the length
- * of the output string, or a negative number if the buffer is too short.
- */
-int get_file_hash(HashAlgorithm algorithm, const char *path,
- char *output_string, size_t max_output_string) {
- SHA1_CTX context;
- struct stat sb;
- unsigned char md[SHA1_DIGEST_LENGTH];
- int used;
- size_t n;
-
- if (algorithm != SHA_1) {
- errno = EINVAL;
- return -1;
- }
-
- if (stat(path, &sb) != 0) {
- return -1;
- }
-
- if (S_ISLNK(sb.st_mode)) {
- char buf[PATH_MAX];
- int len;
-
- len = readlink(path, buf, sizeof(buf));
- if (len < 0) {
- return -1;
- }
-
- SHA1Init(&context);
- SHA1Update(&context, (unsigned char *) buf, len);
- SHA1Final(md, &context);
- } else if (S_ISREG(sb.st_mode)) {
- char buf[10000];
- FILE *f = fopen(path, "rb");
- int len;
-
- if (f == NULL) {
- return -1;
- }
-
- SHA1Init(&context);
-
- while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
- SHA1Update(&context, (unsigned char *) buf, len);
- }
-
- if (ferror(f)) {
- fclose(f);
- return -1;
- }
-
- fclose(f);
- SHA1Final(md, &context);
- }
-
- if (S_ISLNK(sb.st_mode) || S_ISREG(sb.st_mode)) {
- used = b64_ntop(md, SHA1_DIGEST_LENGTH,
- output_string, max_output_string);
- if (used < 0) {
- errno = ENOSPC;
- return -1;
- }
-
- n = snprintf(output_string + used, max_output_string - used,
- " %d 0%o %d %d", (int) sb.st_size, sb.st_mode,
- (int) sb.st_uid, (int) sb.st_gid);
- } else {
- n = snprintf(output_string, max_output_string,
- "- - 0%o %d %d", sb.st_mode,
- (int) sb.st_uid, (int) sb.st_gid);
- }
-
- if (n >= max_output_string - used) {
- errno = ENOSPC;
- return -(used + n);
- }
-
- return used + n;
-}
-
-struct list {
- char *name;
- struct list *next;
-};
-
-static int cmp(const void *a, const void *b) {
- struct list *const *ra = a;
- struct list *const *rb = b;
-
- return strcmp((*ra)->name, (*rb)->name);
-}
-
-static int recurse(HashAlgorithm algorithm, const char *directory_path,
- struct list **out) {
- struct list *list = NULL;
- struct list *f;
-
- struct dirent *de;
- DIR *d = opendir(directory_path);
-
- if (d == NULL) {
- return -1;
- }
-
- while ((de = readdir(d)) != NULL) {
- if (strcmp(de->d_name, ".") == 0) {
- continue;
- }
- if (strcmp(de->d_name, "..") == 0) {
- continue;
- }
-
- char *name = malloc(strlen(de->d_name) + 1);
- struct list *node = malloc(sizeof(struct list));
-
- if (name == NULL || node == NULL) {
- struct list *next;
- for (f = list; f != NULL; f = next) {
- next = f->next;
- free(f->name);
- free(f);
- }
-
- free(name);
- free(node);
- closedir(d);
- return -1;
- }
-
- strcpy(name, de->d_name);
-
- node->name = name;
- node->next = list;
- list = node;
- }
-
- closedir(d);
-
- for (f = list; f != NULL; f = f->next) {
- struct stat sb;
- char *name;
- char outstr[NAME_MAX + 100];
- char *keep;
- struct list *res;
-
- name = malloc(strlen(f->name) + strlen(directory_path) + 2);
- if (name == NULL) {
- struct list *next;
- for (f = list; f != NULL; f = f->next) {
- next = f->next;
- free(f->name);
- free(f);
- }
- for (f = *out; f != NULL; f = f->next) {
- next = f->next;
- free(f->name);
- free(f);
- }
- *out = NULL;
- return -1;
- }
-
- sprintf(name, "%s/%s", directory_path, f->name);
-
- int len = get_file_hash(algorithm, name,
- outstr, sizeof(outstr));
- if (len < 0) {
- // should not happen
- return -1;
- }
-
- keep = malloc(len + strlen(name) + 3);
- res = malloc(sizeof(struct list));
-
- if (keep == NULL || res == NULL) {
- struct list *next;
- for (f = list; f != NULL; f = f->next) {
- next = f->next;
- free(f->name);
- free(f);
- }
- for (f = *out; f != NULL; f = f->next) {
- next = f->next;
- free(f->name);
- free(f);
- }
- *out = NULL;
-
- free(keep);
- free(res);
- return -1;
- }
-
- sprintf(keep, "%s %s\n", name, outstr);
-
- res->name = keep;
- res->next = *out;
- *out = res;
-
- if ((stat(name, &sb) == 0) && S_ISDIR(sb.st_mode)) {
- if (recurse(algorithm, name, out) < 0) {
- struct list *next;
- for (f = list; f != NULL; f = next) {
- next = f->next;
- free(f->name);
- free(f);
- }
-
- return -1;
- }
- }
- }
-
- struct list *next;
- for (f = list; f != NULL; f = next) {
- next = f->next;
-
- free(f->name);
- free(f);
- }
-}
-
-/**
- * Allocates a string containing the names and hashes of all files recursively
- * reached under the specified directory_path, using the specified algorithm.
- * The string is returned as *output_string; the return value is the length
- * of the string, or a negative number if there was a failure.
- */
-int get_recursive_hash_manifest(HashAlgorithm algorithm,
- const char *directory_path,
- char **output_string) {
- struct list *out = NULL;
- struct list *r;
- struct list **list;
- int count = 0;
- int len = 0;
- int retlen = 0;
- int i;
- char *buf;
-
- if (recurse(algorithm, directory_path, &out) < 0) {
- return -1;
- }
-
- for (r = out; r != NULL; r = r->next) {
- count++;
- len += strlen(r->name);
- }
-
- list = malloc(count * sizeof(struct list *));
- if (list == NULL) {
- struct list *next;
- for (r = out; r != NULL; r = next) {
- next = r->next;
- free(r->name);
- free(r);
- }
- return -1;
- }
-
- count = 0;
- for (r = out; r != NULL; r = r->next) {
- list[count++] = r;
- }
-
- qsort(list, count, sizeof(struct list *), cmp);
-
- buf = malloc(len + 1);
- if (buf == NULL) {
- struct list *next;
- for (r = out; r != NULL; r = next) {
- next = r->next;
- free(r->name);
- free(r);
- }
- free(list);
- return -1;
- }
-
- for (i = 0; i < count; i++) {
- int n = strlen(list[i]->name);
-
- strcpy(buf + retlen, list[i]->name);
- retlen += n;
- }
-
- free(list);
-
- struct list *next;
- for (r = out; r != NULL; r = next) {
- next = r->next;
-
- free(r->name);
- free(r);
- }
-
- *output_string = buf;
- return retlen;
-}
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 57c46a3..8582344 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -1131,7 +1131,22 @@
return kIoError;
}
- int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+ int result = 0;
+#if defined(__linux__)
+ // Make sure we have enough space on the volume to extract the compressed
+ // entry. Note that the call to ftruncate below will change the file size but
+ // will not allocate space on disk.
+ if (declared_length > 0) {
+ result = TEMP_FAILURE_RETRY(fallocate(fd, 0, current_offset, declared_length));
+ if (result == -1) {
+ ALOGW("Zip: unable to allocate space for file to %" PRId64 ": %s",
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ return kIoError;
+ }
+ }
+#endif // defined(__linux__)
+
+ result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
if (result == -1) {
ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
static_cast<int64_t>(declared_length + current_offset), strerror(errno));
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a0436ef..1859461 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -226,6 +226,68 @@
return it;
}
+// Define a temporary mechanism to report the last LogBufferElement pointer
+// for the specified uid, pid and tid. Used below to help merge-sort when
+// pruning for worst UID.
+class LogBufferElementKey {
+ const union {
+ struct {
+ uint16_t uid;
+ uint16_t pid;
+ uint16_t tid;
+ uint16_t padding;
+ } __packed;
+ uint64_t value;
+ } __packed;
+
+public:
+ LogBufferElementKey(uid_t u, pid_t p, pid_t t):uid(u),pid(p),tid(t),padding(0) { }
+ LogBufferElementKey(uint64_t k):value(k) { }
+
+ uint64_t getKey() { return value; }
+};
+
+struct LogBufferElementEntry {
+ const uint64_t key;
+ LogBufferElement *last;
+
+public:
+ LogBufferElementEntry(const uint64_t &k, LogBufferElement *e):key(k),last(e) { }
+
+ const uint64_t&getKey() const { return key; }
+
+ LogBufferElement *getLast() { return last; }
+};
+
+struct LogBufferElementLast : public android::BasicHashtable<uint64_t, LogBufferElementEntry> {
+
+ bool merge(LogBufferElement *e, unsigned short dropped) {
+ LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+ android::hash_t hash = android::hash_type(key.getKey());
+ ssize_t index = find(-1, hash, key.getKey());
+ if (index != -1) {
+ LogBufferElementEntry &entry = editEntryAt(index);
+ LogBufferElement *l = entry.getLast();
+ unsigned short d = l->getDropped();
+ if ((dropped + d) > USHRT_MAX) {
+ removeAt(index);
+ } else {
+ l->setDropped(dropped + d);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ size_t add(LogBufferElement *e) {
+ LogBufferElementKey key(e->getUid(), e->getPid(), e->getTid());
+ android::hash_t hash = android::hash_type(key.getKey());
+ return android::BasicHashtable<uint64_t, LogBufferElementEntry>::
+ add(hash, LogBufferElementEntry(key.getKey(), e));
+ }
+
+};
+
// prune "pruneRows" of type "id" from the buffer.
//
// mLogElementsLock must be held when this function is called.
@@ -301,7 +363,7 @@
bool kick = false;
bool leading = true;
- LogBufferElement *last = NULL;
+ LogBufferElementLast last;
for(it = mLogElements.begin(); it != mLogElements.end();) {
LogBufferElement *e = *it;
@@ -322,24 +384,18 @@
continue;
}
- pid_t pid = e->getPid();
-
// merge any drops
- if (last && dropped
- && ((dropped + last->getDropped()) < USHRT_MAX)
- && (last->getPid() == pid)
- && (last->getTid() == e->getTid())) {
+ if (dropped && last.merge(e, dropped)) {
it = mLogElements.erase(it);
stats.erase(e);
delete e;
- last->setDropped(dropped + last->getDropped());
continue;
}
leading = false;
if (hasBlacklist && mPrune.naughty(e)) {
- last = NULL;
+ last.clear();
it = erase(it);
if (dropped) {
continue;
@@ -361,13 +417,13 @@
}
if (dropped) {
- last = e;
+ last.add(e);
++it;
continue;
}
if (e->getUid() != worst) {
- last = NULL;
+ last.clear();
++it;
continue;
}
@@ -382,17 +438,12 @@
unsigned short len = e->getMsgLen();
stats.drop(e);
e->setDropped(1);
- // merge any drops
- if (last
- && (last->getDropped() < (USHRT_MAX - 1))
- && (last->getPid() == pid)
- && (last->getTid() == e->getTid())) {
+ if (last.merge(e, 1)) {
it = mLogElements.erase(it);
stats.erase(e);
delete e;
- last->setDropped(last->getDropped() + 1);
} else {
- last = e;
+ last.add(e);
++it;
}
if (worst_sizes < second_worst_sizes) {
@@ -400,6 +451,7 @@
}
worst_sizes -= len;
}
+ last.clear();
if (!kick || !mPrune.worstUidEnabled()) {
break; // the following loop will ask bad clients to skip/drop
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 0801fe8..eadc4dd 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -328,22 +328,32 @@
}
if (!headerPrinted) {
+ output.appendFormat("\n\n");
+ android::String8 name("");
if (uid == AID_ROOT) {
- output.appendFormat(
- "\n\nChattiest UIDs in %s:\n",
+ name.appendFormat(
+ "Chattiest UIDs in %s log buffer:",
android_log_id_to_name(id));
} else {
- output.appendFormat(
- "\n\nLogging for your UID in %s:\n",
+ name.appendFormat(
+ "Logging for your UID in %s log buffer:",
android_log_id_to_name(id));
}
- android::String8 name("UID");
android::String8 size("Size");
android::String8 pruned("Pruned");
if (!worstUidEnabledForLogid(id)) {
pruned.setTo("");
}
format_line(output, name, size, pruned);
+
+ name.setTo("UID PACKAGE");
+ size.setTo("BYTES");
+ pruned.setTo("LINES");
+ if (!worstUidEnabledForLogid(id)) {
+ pruned.setTo("");
+ }
+ format_line(output, name, size, pruned);
+
headerPrinted = true;
}
@@ -380,15 +390,22 @@
}
if (!headerPrinted) {
+ output.appendFormat("\n\n");
+ android::String8 name("");
if (uid == AID_ROOT) {
- output.appendFormat("\n\nChattiest PIDs:\n");
+ name.appendFormat("Chattiest PIDs:");
} else {
- output.appendFormat("\n\nLogging for this PID:\n");
+ name.appendFormat("Logging for this PID:");
}
- android::String8 name(" PID/UID");
android::String8 size("Size");
android::String8 pruned("Pruned");
format_line(output, name, size, pruned);
+
+ name.setTo(" PID/UID COMMAND LINE");
+ size.setTo("BYTES");
+ pruned.setTo("LINES");
+ format_line(output, name, size, pruned);
+
headerPrinted = true;
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a2b8f59..a5ea60a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -248,6 +248,7 @@
mkdir /data/misc/bluedroid 0770 bluetooth net_bt_stack
mkdir /data/misc/bluetooth 0770 system system
mkdir /data/misc/keystore 0700 keystore keystore
+ mkdir /data/misc/gatekeeper 0700 system system
mkdir /data/misc/keychain 0771 system system
mkdir /data/misc/net 0750 root shell
mkdir /data/misc/radio 0770 system radio