Merge "Fix google-explicit-constructor warnings."
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index d8b1654..45c6142 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1613,6 +1613,11 @@
else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
int exec_in = !strcmp(argv[0], "exec-in");
+ if (argc < 2) {
+ fprintf(stderr, "Usage: adb %s command\n", argv[0]);
+ return 1;
+ }
+
std::string cmd = "exec:";
cmd += argv[1];
argc -= 2;
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index c863ed2..0ba6b4b 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -31,6 +31,9 @@
#include <unistd.h>
#include <algorithm>
+#include <atomic>
+
+#include <android-base/logging.h>
#include "adb.h"
#include "transport.h"
@@ -49,14 +52,19 @@
#define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x)
+static int dummy_fd = -1;
+
struct usb_handle
{
adb_cond_t notify;
adb_mutex_t lock;
+ bool open_new_connection;
+ std::atomic<bool> kicked;
int (*write)(usb_handle *h, const void *data, int len);
int (*read)(usb_handle *h, void *data, int len);
void (*kick)(usb_handle *h);
+ void (*close)(usb_handle *h);
// Legacy f_adb
int fd;
@@ -241,8 +249,10 @@
while (true) {
// wait until the USB device needs opening
adb_mutex_lock(&usb->lock);
- while (usb->fd != -1)
+ while (!usb->open_new_connection) {
adb_cond_wait(&usb->notify, &usb->lock);
+ }
+ usb->open_new_connection = false;
adb_mutex_unlock(&usb->lock);
D("[ usb_thread - opening device ]");
@@ -281,6 +291,10 @@
h->fd, n, errno, strerror(errno));
return -1;
}
+ if (h->kicked) {
+ D("usb_adb_write finished due to kicked");
+ return -1;
+ }
D("[ done fd=%d ]", h->fd);
return 0;
}
@@ -299,6 +313,10 @@
h->fd, n, errno, strerror(errno));
return -1;
}
+ if (h->kicked) {
+ D("usb_adb_read finished due to kicked");
+ return -1;
+ }
len -= n;
data = ((char*)data) + n;
}
@@ -306,14 +324,23 @@
return 0;
}
-static void usb_adb_kick(usb_handle *h)
-{
+static void usb_adb_kick(usb_handle *h) {
D("usb_kick");
- adb_mutex_lock(&h->lock);
- unix_close(h->fd);
- h->fd = -1;
+ // Other threads may be calling usb_adb_read/usb_adb_write at the same time.
+ // If we close h->fd, the file descriptor will be reused to open other files,
+ // and the read/write thread may operate on the wrong file. So instead
+ // we set the kicked flag and reopen h->fd to a dummy file here. After read/write
+ // threads finish, we close h->fd in usb_adb_close().
+ h->kicked = true;
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->fd));
+}
- // notify usb_adb_open_thread that we are disconnected
+static void usb_adb_close(usb_handle *h) {
+ h->kicked = false;
+ adb_close(h->fd);
+ // Notify usb_adb_open_thread to open a new connection.
+ adb_mutex_lock(&h->lock);
+ h->open_new_connection = true;
adb_cond_signal(&h->notify);
adb_mutex_unlock(&h->lock);
}
@@ -326,8 +353,11 @@
h->write = usb_adb_write;
h->read = usb_adb_read;
h->kick = usb_adb_kick;
+ h->close = usb_adb_close;
+ h->kicked = false;
h->fd = -1;
+ h->open_new_connection = true;
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
@@ -350,7 +380,7 @@
}
-static void init_functionfs(struct usb_handle *h)
+static bool init_functionfs(struct usb_handle *h)
{
ssize_t ret;
struct desc_v1 v1_descriptor;
@@ -413,7 +443,7 @@
goto err;
}
- return;
+ return true;
err:
if (h->bulk_in > 0) {
@@ -428,7 +458,7 @@
adb_close(h->control);
h->control = -1;
}
- return;
+ return false;
}
static void usb_ffs_open_thread(void* x) {
@@ -439,16 +469,16 @@
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)
+ while (!usb->open_new_connection) {
adb_cond_wait(&usb->notify, &usb->lock);
+ }
+ usb->open_new_connection = false;
adb_mutex_unlock(&usb->lock);
while (true) {
- init_functionfs(usb);
-
- if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
+ if (init_functionfs(usb)) {
break;
-
+ }
adb_sleep_ms(1000);
}
property_set("sys.usb.ffs.ready", "1");
@@ -513,16 +543,22 @@
D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);
}
- adb_mutex_lock(&h->lock);
-
// don't close ep0 here, since we may not need to reinitialize it with
// the same descriptors again. if however ep1/ep2 fail to re-open in
// init_functionfs, only then would we close and open ep0 again.
+ // Ditto the comment in usb_adb_kick.
+ h->kicked = true;
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_out));
+ TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_in));
+}
+
+static void usb_ffs_close(usb_handle *h) {
+ h->kicked = false;
adb_close(h->bulk_out);
adb_close(h->bulk_in);
- h->bulk_out = h->bulk_in = -1;
-
- // notify usb_ffs_open_thread that we are disconnected
+ // Notify usb_adb_open_thread to open a new connection.
+ adb_mutex_lock(&h->lock);
+ h->open_new_connection = true;
adb_cond_signal(&h->notify);
adb_mutex_unlock(&h->lock);
}
@@ -537,10 +573,13 @@
h->write = usb_ffs_write;
h->read = usb_ffs_read;
h->kick = usb_ffs_kick;
+ h->close = usb_ffs_close;
+ h->kicked = false;
h->control = -1;
h->bulk_out = -1;
h->bulk_out = -1;
+ h->open_new_connection = true;
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
@@ -552,6 +591,8 @@
void usb_init()
{
+ dummy_fd = adb_open("/dev/null", O_WRONLY);
+ CHECK_NE(dummy_fd, -1);
if (access(USB_FFS_ADB_EP0, F_OK) == 0)
usb_ffs_init();
else
@@ -569,6 +610,7 @@
}
int usb_close(usb_handle *h)
{
+ h->close(h);
return 0;
}
diff --git a/fastboot/protocol.cpp b/fastboot/protocol.cpp
index 4850b4a..1785b76 100644
--- a/fastboot/protocol.cpp
+++ b/fastboot/protocol.cpp
@@ -54,14 +54,14 @@
while (true) {
int r = transport->Read(status, 64);
if (r < 0) {
- sprintf(ERROR, "status read failed (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "status read failed (%s)", strerror(errno));
transport->Close();
return -1;
}
status[r] = 0;
if (r < 4) {
- sprintf(ERROR, "status malformed (%d bytes)", r);
+ snprintf(ERROR, sizeof(ERROR), "status malformed (%d bytes)", r);
transport->Close();
return -1;
}
@@ -80,7 +80,7 @@
if (!memcmp(status, "FAIL", 4)) {
if (r > 4) {
- sprintf(ERROR, "remote: %s", status + 4);
+ snprintf(ERROR, sizeof(ERROR), "remote: %s", status + 4);
} else {
strcpy(ERROR, "remote failure");
}
@@ -108,7 +108,7 @@
static int _command_start(Transport* transport, const char* cmd, uint32_t size, char* response) {
size_t cmdsize = strlen(cmd);
if (cmdsize > 64) {
- sprintf(ERROR, "command too large");
+ snprintf(ERROR, sizeof(ERROR), "command too large");
return -1;
}
@@ -117,7 +117,7 @@
}
if (transport->Write(cmd, cmdsize) != static_cast<int>(cmdsize)) {
- sprintf(ERROR, "command write failed (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "command write failed (%s)", strerror(errno));
transport->Close();
return -1;
}
@@ -128,12 +128,12 @@
static int _command_data(Transport* transport, const void* data, uint32_t size) {
int r = transport->Write(data, size);
if (r < 0) {
- sprintf(ERROR, "data transfer failure (%s)", strerror(errno));
+ snprintf(ERROR, sizeof(ERROR), "data transfer failure (%s)", strerror(errno));
transport->Close();
return -1;
}
if (r != ((int) size)) {
- sprintf(ERROR, "data transfer failure (short transfer)");
+ snprintf(ERROR, sizeof(ERROR), "data transfer failure (short transfer)");
transport->Close();
return -1;
}
@@ -182,7 +182,7 @@
int fb_download_data(Transport* transport, const void* data, uint32_t size) {
char cmd[64];
- sprintf(cmd, "download:%08x", size);
+ snprintf(cmd, sizeof(cmd), "download:%08x", size);
return _command_send(transport, cmd, data, size, 0) < 0 ? -1 : 0;
}
@@ -216,7 +216,7 @@
if (len > TRANSPORT_BUF_SIZE) {
if (transport_buf_len > 0) {
- sprintf(ERROR, "internal error: transport_buf not empty\n");
+ snprintf(ERROR, sizeof(ERROR), "internal error: transport_buf not empty\n");
return -1;
}
to_write = round_down(len, TRANSPORT_BUF_SIZE);
@@ -230,7 +230,7 @@
if (len > 0) {
if (len > TRANSPORT_BUF_SIZE) {
- sprintf(ERROR, "internal error: too much left for transport_buf\n");
+ snprintf(ERROR, sizeof(ERROR), "internal error: too much left for transport_buf\n");
return -1;
}
memcpy(transport_buf, ptr, len);
@@ -257,7 +257,7 @@
}
char cmd[64];
- sprintf(cmd, "download:%08x", size);
+ snprintf(cmd, sizeof(cmd), "download:%08x", size);
int r = _command_start(transport, cmd, size, 0);
if (r < 0) {
return -1;
diff --git a/logcat/tests/logcat_benchmark.cpp b/logcat/tests/logcat_benchmark.cpp
index be815be..dd85164 100644
--- a/logcat/tests/logcat_benchmark.cpp
+++ b/logcat/tests/logcat_benchmark.cpp
@@ -49,7 +49,7 @@
}
}
- timestamp(const char *buffer)
+ explicit timestamp(const char *buffer)
{
init(buffer);
}
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 8c30f79..db65978 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -380,7 +380,7 @@
tid(tid),
padding(0) {
}
- LogBufferElementKey(uint64_t key):value(key) { }
+ explicit LogBufferElementKey(uint64_t key):value(key) { }
uint64_t getKey() { return value; }
};
diff --git a/toolbox/ps.c b/toolbox/ps.c
index d366f3e..633c48e 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -282,6 +282,13 @@
} else if(!strcmp(argv[1],"--abi")) {
display_flags |= SHOW_ABI;
} else if(!strcmp(argv[1],"--ppid")) {
+ if (argc < 3) {
+ /* Bug 26554285: Use printf because some apps require at least
+ * one line of output to stdout even for errors.
+ */
+ printf("no ppid\n");
+ return 1;
+ }
ppid_filter = atoi(argv[2]);
if (ppid_filter == 0) {
/* Bug 26554285: Use printf because some apps require at least