Merge "Rely on the platform -std default."
diff --git a/adb/Android.mk b/adb/Android.mk
index 41d3762..be04cfa 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -43,7 +43,6 @@
# get enough of adb in here that we no longer need minadb. https://b/17626262
LIBADB_SRC_FILES := \
adb.cpp \
- adb_auth.cpp \
adb_io.cpp \
adb_listeners.cpp \
adb_trace.cpp \
@@ -101,7 +100,7 @@
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
- adb_auth_client.cpp \
+ adbd_auth.cpp \
jdwp_service.cpp \
usb_linux_client.cpp \
@@ -322,7 +321,6 @@
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
-LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STRIP_MODULE := keep_symbols
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 9ae3f1c..29d6e65 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -94,6 +94,18 @@
abort();
}
+uint32_t calculate_apacket_checksum(const apacket* p) {
+ const unsigned char* x = reinterpret_cast<const unsigned char*>(p->data);
+ uint32_t sum = 0;
+ size_t count = p->msg.data_length;
+
+ while (count-- > 0) {
+ sum += *x++;
+ }
+
+ return sum;
+}
+
apacket* get_apacket(void)
{
apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
@@ -351,19 +363,31 @@
break;
case A_AUTH:
- if (p->msg.arg0 == ADB_AUTH_TOKEN) {
- t->connection_state = kCsUnauthorized;
- send_auth_response(p->data, p->msg.data_length, t);
- } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
- if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
- adb_auth_verified(t);
- t->failed_auth_attempts = 0;
- } else {
- if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
- send_auth_request(t);
- }
- } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
- adb_auth_confirm_key(p->data, p->msg.data_length, t);
+ switch (p->msg.arg0) {
+#if ADB_HOST
+ case ADB_AUTH_TOKEN:
+ t->connection_state = kCsUnauthorized;
+ send_auth_response(p->data, p->msg.data_length, t);
+ break;
+#else
+ case ADB_AUTH_SIGNATURE:
+ if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
+ adbd_auth_verified(t);
+ t->failed_auth_attempts = 0;
+ } else {
+ if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
+ send_auth_request(t);
+ }
+ break;
+
+ case ADB_AUTH_RSAPUBLICKEY:
+ adbd_auth_confirm_key(p->data, p->msg.data_length, t);
+ break;
+#endif
+ default:
+ t->connection_state = kCsOffline;
+ handle_offline(t);
+ break;
}
break;
diff --git a/adb/adb.h b/adb/adb.h
index 0b9fe5b..df59aaa 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -18,6 +18,7 @@
#define __ADB_H
#include <limits.h>
+#include <stdint.h>
#include <sys/types.h>
#include <string>
@@ -56,25 +57,27 @@
struct usb_handle;
struct amessage {
- unsigned command; /* command identifier constant */
- unsigned arg0; /* first argument */
- unsigned arg1; /* second argument */
- unsigned data_length; /* length of payload (0 is allowed) */
- unsigned data_check; /* checksum of data payload */
- unsigned magic; /* command ^ 0xffffffff */
+ uint32_t command; /* command identifier constant */
+ uint32_t arg0; /* first argument */
+ uint32_t arg1; /* second argument */
+ uint32_t data_length; /* length of payload (0 is allowed) */
+ uint32_t data_check; /* checksum of data payload */
+ uint32_t magic; /* command ^ 0xffffffff */
};
struct apacket
{
apacket *next;
- unsigned len;
- unsigned char *ptr;
+ size_t len;
+ char* ptr;
amessage msg;
- unsigned char data[MAX_PAYLOAD];
+ char data[MAX_PAYLOAD];
};
+uint32_t calculate_apacket_checksum(const apacket* packet);
+
/* the adisconnect structure is used to record a callback that
** will be called whenever a transport is disconnected (e.g. by the user)
** this should be used to cleanup objects that depend on the
@@ -136,8 +139,10 @@
int init_socket_transport(atransport *t, int s, int port, int local);
void init_usb_transport(atransport *t, usb_handle *usb, ConnectionState state);
+std::string getEmulatorSerialString(int console_port);
#if ADB_HOST
atransport* find_emulator_transport_by_adb_port(int adb_port);
+atransport* find_emulator_transport_by_console_port(int console_port);
#endif
int service_to_fd(const char* name, const atransport* transport);
@@ -199,7 +204,7 @@
// USB device detection.
#if ADB_HOST
-int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
+int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol);
#endif
ConnectionState connection_state(atransport *t);
diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp
deleted file mode 100644
index 0b07158..0000000
--- a/adb/adb_auth.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.
- */
-
-#define TRACE_TAG ADB
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "transport.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-bool auth_required = true;
-
-void send_auth_request(atransport *t)
-{
- LOG(INFO) << "Calling send_auth_request...";
-
- if (!adb_auth_generate_token(t->token, sizeof(t->token))) {
- PLOG(ERROR) << "Error generating token";
- return;
- }
-
- apacket* p = get_apacket();
- memcpy(p->data, t->token, sizeof(t->token));
- p->msg.command = A_AUTH;
- p->msg.arg0 = ADB_AUTH_TOKEN;
- p->msg.data_length = sizeof(t->token);
- send_packet(p, t);
-}
-
-static void send_auth_publickey(atransport* t) {
- LOG(INFO) << "Calling send_auth_publickey";
-
- std::string key = adb_auth_get_userkey();
- if (key.empty()) {
- D("Failed to get user public key");
- return;
- }
-
- if (key.size() >= MAX_PAYLOAD_V1) {
- D("User public key too large (%zu B)", key.size());
- return;
- }
-
- apacket* p = get_apacket();
- memcpy(p->data, key.c_str(), key.size() + 1);
-
- p->msg.command = A_AUTH;
- p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
-
- // adbd expects a null-terminated string.
- p->msg.data_length = key.size() + 1;
- send_packet(p, t);
-}
-
-void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
- std::shared_ptr<RSA> key = t->NextKey();
- if (key == nullptr) {
- // No more private keys to try, send the public key.
- send_auth_publickey(t);
- return;
- }
-
- LOG(INFO) << "Calling send_auth_response";
- apacket* p = get_apacket();
-
- int ret = adb_auth_sign(key.get(), token, token_size, p->data);
- if (!ret) {
- D("Error signing the token");
- put_apacket(p);
- return;
- }
-
- p->msg.command = A_AUTH;
- p->msg.arg0 = ADB_AUTH_SIGNATURE;
- p->msg.data_length = ret;
- send_packet(p, t);
-}
-
-void adb_auth_verified(atransport *t)
-{
- handle_online(t);
- send_connect(t);
-}
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 59b80d8..a6f224f 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -24,14 +24,6 @@
#include <openssl/rsa.h>
-extern bool auth_required;
-
-int adb_auth_keygen(const char* filename);
-void adb_auth_verified(atransport *t);
-
-void send_auth_request(atransport *t);
-void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
-
/* AUTH packets first argument */
/* Request */
#define ADB_AUTH_TOKEN 1
@@ -42,25 +34,25 @@
#if ADB_HOST
void adb_auth_init();
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
+
+int adb_auth_keygen(const char* filename);
std::string adb_auth_get_userkey();
std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
-static inline bool adb_auth_generate_token(void*, size_t) { abort(); }
-static inline bool adb_auth_verify(void*, size_t, void*, int) { abort(); }
-static inline void adb_auth_confirm_key(unsigned char*, size_t, atransport*) { abort(); }
+void send_auth_response(const char* token, size_t token_size, atransport* t);
#else // !ADB_HOST
-static inline int adb_auth_sign(void*, const unsigned char*, size_t, unsigned char*) { abort(); }
-static inline std::string adb_auth_get_userkey() { abort(); }
-static inline std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() { abort(); }
+extern bool auth_required;
void adbd_auth_init(void);
+void adbd_auth_verified(atransport *t);
+
void adbd_cloexec_auth_socket();
-bool adb_auth_generate_token(void* token, size_t token_size);
-bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len);
-void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len);
+void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
+
+void send_auth_request(atransport *t);
#endif // ADB_HOST
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 072c7f5..ff2d76d 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -45,6 +45,7 @@
#include "adb_auth.h"
#include "adb_utils.h"
#include "sysdeps.h"
+#include "transport.h"
static std::mutex& g_keys_mutex = *new std::mutex;
static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
@@ -297,14 +298,15 @@
return result;
}
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig) {
+static int adb_auth_sign(RSA* key, const char* token, size_t token_size, char* sig) {
if (token_size != TOKEN_SIZE) {
D("Unexpected token size %zd", token_size);
return 0;
}
unsigned int len;
- if (!RSA_sign(NID_sha1, token, token_size, sig, &len, key)) {
+ if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+ reinterpret_cast<uint8_t*>(sig), &len, key)) {
return 0;
}
@@ -421,3 +423,52 @@
read_keys(path.c_str());
}
}
+
+static void send_auth_publickey(atransport* t) {
+ LOG(INFO) << "Calling send_auth_publickey";
+
+ std::string key = adb_auth_get_userkey();
+ if (key.empty()) {
+ D("Failed to get user public key");
+ return;
+ }
+
+ if (key.size() >= MAX_PAYLOAD_V1) {
+ D("User public key too large (%zu B)", key.size());
+ return;
+ }
+
+ apacket* p = get_apacket();
+ memcpy(p->data, key.c_str(), key.size() + 1);
+
+ p->msg.command = A_AUTH;
+ p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
+
+ // adbd expects a null-terminated string.
+ p->msg.data_length = key.size() + 1;
+ send_packet(p, t);
+}
+
+void send_auth_response(const char* token, size_t token_size, atransport* t) {
+ std::shared_ptr<RSA> key = t->NextKey();
+ if (key == nullptr) {
+ // No more private keys to try, send the public key.
+ send_auth_publickey(t);
+ return;
+ }
+
+ LOG(INFO) << "Calling send_auth_response";
+ apacket* p = get_apacket();
+
+ int ret = adb_auth_sign(key.get(), token, token_size, p->data);
+ if (!ret) {
+ D("Error signing the token");
+ put_apacket(p);
+ return;
+ }
+
+ p->msg.command = A_AUTH;
+ p->msg.arg0 = ADB_AUTH_SIGNATURE;
+ p->msg.data_length = ret;
+ send_packet(p, t);
+}
diff --git a/adb/adb_auth_client.cpp b/adb/adbd_auth.cpp
similarity index 79%
rename from adb/adb_auth_client.cpp
rename to adb/adbd_auth.cpp
index 84ad6ef..b5f87be 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adbd_auth.cpp
@@ -44,7 +44,9 @@
static atransport* usb_transport;
static bool needs_retry = false;
-bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len) {
+bool auth_required = true;
+
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len) {
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
for (const auto& path : key_paths) {
@@ -76,7 +78,9 @@
continue;
}
- bool verified = (RSA_verify(NID_sha1, token, token_size, sig, sig_len, key) == 1);
+ bool verified =
+ (RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+ reinterpret_cast<const uint8_t*>(sig), sig_len, key) == 1);
RSA_free(key);
if (verified) return true;
}
@@ -85,7 +89,7 @@
return false;
}
-bool adb_auth_generate_token(void* token, size_t token_size) {
+static bool adbd_auth_generate_token(void* token, size_t token_size) {
FILE* fp = fopen("/dev/urandom", "re");
if (!fp) return false;
bool okay = (fread(token, token_size, 1, fp) == 1);
@@ -105,7 +109,7 @@
framework_fd = -1;
}
-static void adb_auth_event(int fd, unsigned events, void*) {
+static void adbd_auth_event(int fd, unsigned events, void*) {
if (events & FDE_READ) {
char response[2];
int ret = unix_read(fd, response, sizeof(response));
@@ -113,13 +117,13 @@
framework_disconnected();
} else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
if (usb_transport) {
- adb_auth_verified(usb_transport);
+ adbd_auth_verified(usb_transport);
}
}
}
}
-void adb_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
+void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
if (!usb_transport) {
usb_transport = t;
t->AddDisconnect(&usb_disconnect);
@@ -150,7 +154,7 @@
}
}
-static void adb_auth_listener(int fd, unsigned events, void* data) {
+static void adbd_auth_listener(int fd, unsigned events, void* data) {
int s = adb_socket_accept(fd, nullptr, nullptr);
if (s < 0) {
PLOG(ERROR) << "Failed to accept";
@@ -163,7 +167,7 @@
}
framework_fd = s;
- fdevent_install(&framework_fde, framework_fd, adb_auth_event, nullptr);
+ fdevent_install(&framework_fde, framework_fd, adbd_auth_event, nullptr);
fdevent_add(&framework_fde, FDE_READ);
if (needs_retry) {
@@ -193,6 +197,28 @@
return;
}
- fdevent_install(&listener_fde, fd, adb_auth_listener, NULL);
+ fdevent_install(&listener_fde, fd, adbd_auth_listener, NULL);
fdevent_add(&listener_fde, FDE_READ);
}
+
+void send_auth_request(atransport* t) {
+ LOG(INFO) << "Calling send_auth_request...";
+
+ if (!adbd_auth_generate_token(t->token, sizeof(t->token))) {
+ PLOG(ERROR) << "Error generating token";
+ return;
+ }
+
+ apacket* p = get_apacket();
+ memcpy(p->data, t->token, sizeof(t->token));
+ p->msg.command = A_AUTH;
+ p->msg.arg0 = ADB_AUTH_TOKEN;
+ p->msg.data_length = sizeof(t->token);
+ send_packet(p, t);
+}
+
+void adbd_auth_verified(atransport *t)
+{
+ handle_online(t);
+ send_connect(t);
+}
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index c348dd5..24be529 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <vector>
+#include <android-base/parseint.h>
#include <android-base/strings.h>
#include "sysdeps.h"
@@ -143,9 +144,11 @@
//
size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
- int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
- int total = std::stoi(line.substr(idx2 + 1));
- br_->UpdateProgress(line_message_, progress, total);
+ int progress, total;
+ if (android::base::ParseInt(line.substr(idx1, (idx2 - idx1)), &progress) &&
+ android::base::ParseInt(line.substr(idx2 + 1), &total)) {
+ br_->UpdateProgress(line_message_, progress, total);
+ }
} else {
invalid_lines_.push_back(line);
}
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 2dfad94..837902a 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -31,10 +31,10 @@
#include <unistd.h>
#include <utime.h>
-#include <android/log.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <private/android_filesystem_config.h>
+#include <private/android_logger.h>
#include <selinux/android.h>
#include "adb.h"
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index 7b00d9d..e2b388b 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -82,6 +82,7 @@
#include "shell_service.h"
#include <errno.h>
+#include <paths.h>
#include <pty.h>
#include <pwd.h>
#include <sys/select.h>
@@ -92,10 +93,9 @@
#include <unordered_map>
#include <vector>
-#include <android/log.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
-#include <paths.h>
+#include <private/android_logger.h>
#include "adb.h"
#include "adb_io.h"
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index b809c4f..fff6049 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -122,7 +122,7 @@
}
static int local_socket_enqueue(asocket* s, apacket* p) {
- D("LS(%d): enqueue %d", s->id, p->len);
+ D("LS(%d): enqueue %zu", s->id, p->len);
p->ptr = p->data;
@@ -195,7 +195,7 @@
/* dispose of any unwritten data */
for (p = s->pkt_first; p; p = n) {
- D("LS(%d): discarding %d bytes", s->id, p->len);
+ D("LS(%d): discarding %zu bytes", s->id, p->len);
n = p->next;
put_apacket(p);
}
@@ -305,7 +305,7 @@
if (ev & FDE_READ) {
apacket* p = get_apacket();
- unsigned char* x = p->data;
+ char* x = p->data;
const size_t max_payload = s->get_max_payload();
size_t avail = max_payload;
int r = 0;
@@ -553,7 +553,7 @@
s->close(s);
}
-static unsigned unhex(unsigned char* s, int len) {
+static unsigned unhex(char* s, int len) {
unsigned n = 0, c;
while (len-- > 0) {
@@ -665,7 +665,7 @@
TransportType type = kTransportAny;
#endif
- D("SS(%d): enqueue %d", s->id, p->len);
+ D("SS(%d): enqueue %zu", s->id, p->len);
if (s->pkt_first == 0) {
s->pkt_first = p;
@@ -698,7 +698,7 @@
D("SS(%d): len is %d", s->id, len);
/* can't do anything until we have the full header */
if ((len + 4) > p->len) {
- D("SS(%d): waiting for %d more bytes", s->id, len + 4 - p->len);
+ D("SS(%d): waiting for %zu more bytes", s->id, len + 4 - p->len);
return 0;
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 3ed589c..ad9b9fd 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -594,11 +594,14 @@
}
inline int network_loopback_client(int port, int type, std::string* error) {
- return _fd_set_error_str(socket_loopback_client(port, type), error);
+ return _fd_set_error_str(socket_network_client("localhost", port, type), error);
}
inline int network_loopback_server(int port, int type, std::string* error) {
- return _fd_set_error_str(socket_loopback_server(port, type), error);
+ int fd = socket_loopback_server(port, type);
+ if (fd < 0 && errno == EAFNOSUPPORT)
+ return _fd_set_error_str(socket_loopback_server6(port, type), error);
+ return _fd_set_error_str(fd, error);
}
inline int network_inaddr_any_server(int port, int type, std::string* error) {
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 87712fc..7b4bb1c 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -150,32 +150,17 @@
}
}
-void send_packet(apacket *p, atransport *t)
-{
- unsigned char *x;
- unsigned sum;
- unsigned count;
-
+void send_packet(apacket* p, atransport* t) {
p->msg.magic = p->msg.command ^ 0xffffffff;
-
- count = p->msg.data_length;
- x = (unsigned char *) p->data;
- sum = 0;
- while(count-- > 0){
- sum += *x++;
- }
- p->msg.data_check = sum;
+ p->msg.data_check = calculate_apacket_checksum(p);
print_packet("send", p);
if (t == NULL) {
- D("Transport is null");
- // Zap errno because print_packet() and other stuff have errno effect.
- errno = 0;
- fatal_errno("Transport is null");
+ fatal("Transport is null");
}
- if(write_packet(t->transport_socket, t->serial, &p)){
+ if (write_packet(t->transport_socket, t->serial, &p)) {
fatal_errno("cannot enqueue packet on transport socket");
}
}
@@ -1052,25 +1037,14 @@
return 0;
}
-int check_data(apacket *p)
-{
- unsigned count, sum;
- unsigned char *x;
-
- count = p->msg.data_length;
- x = p->data;
- sum = 0;
- while(count-- > 0) {
- sum += *x++;
- }
-
- if(sum != p->msg.data_check) {
+int check_data(apacket* p) {
+ if (calculate_apacket_checksum(p) != p->msg.data_check) {
return -1;
- } else {
- return 0;
}
+ return 0;
}
+#if ADB_HOST
std::shared_ptr<RSA> atransport::NextKey() {
if (keys_.empty()) keys_ = adb_auth_get_private_keys();
@@ -1078,3 +1052,4 @@
keys_.pop_front();
return result;
}
+#endif
diff --git a/adb/transport.h b/adb/transport.h
index 959681f..621516c 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -108,9 +108,11 @@
return type == kTransportLocal && local_port_for_emulator_ == -1;
}
+#if ADB_HOST
std::shared_ptr<RSA> NextKey();
+#endif
- unsigned char token[TOKEN_SIZE] = {};
+ char token[TOKEN_SIZE] = {};
size_t failed_auth_attempts = 0;
const std::string connection_state_name() const;
@@ -161,7 +163,9 @@
// A list of adisconnect callbacks called when the transport is kicked.
std::list<adisconnect*> disconnects_;
+#if ADB_HOST
std::deque<std::shared_ptr<RSA>> keys_;
+#endif
DISALLOW_COPY_AND_ASSIGN(atransport);
};
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index a94b41e..ea2bf77 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -103,7 +103,8 @@
int fd = -1;
#if ADB_HOST
- if (find_emulator_transport_by_adb_port(adb_port) != nullptr) {
+ if (find_emulator_transport_by_adb_port(adb_port) != nullptr ||
+ find_emulator_transport_by_console_port(console_port) != nullptr) {
return -1;
}
@@ -120,7 +121,7 @@
D("client: connected on remote on fd %d", fd);
close_on_exec(fd);
disable_tcp_nagle(fd);
- std::string serial = android::base::StringPrintf("emulator-%d", console_port);
+ std::string serial = getEmulatorSerialString(console_port);
if (register_socket_transport(fd, serial.c_str(), adb_port, 1) == 0) {
return 0;
}
@@ -431,6 +432,11 @@
return NULL;
}
+std::string getEmulatorSerialString(int console_port)
+{
+ return android::base::StringPrintf("emulator-%d", console_port);
+}
+
atransport* find_emulator_transport_by_adb_port(int adb_port)
{
std::lock_guard<std::mutex> lock(local_transports_lock);
@@ -438,6 +444,12 @@
return result;
}
+atransport* find_emulator_transport_by_console_port(int console_port)
+{
+ return find_transport(getEmulatorSerialString(console_port).c_str());
+}
+
+
/* Only call this function if you already hold local_transports_lock. */
int get_available_local_transport_index_locked()
{
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index d05d928..d054601 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -94,7 +94,7 @@
}
#if ADB_HOST
-int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
+int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol)
{
return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);
}
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index 500898a..3e5028d 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -205,9 +205,8 @@
interface->bInterfaceProtocol, interface->bNumEndpoints);
if (interface->bNumEndpoints == 2 &&
- is_adb_interface(vid, pid, interface->bInterfaceClass,
- interface->bInterfaceSubClass, interface->bInterfaceProtocol)) {
-
+ is_adb_interface(interface->bInterfaceClass, interface->bInterfaceSubClass,
+ interface->bInterfaceProtocol)) {
struct stat st;
char pathbuf[128];
char link[256];
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index adcbb3e..2ee2aae 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -345,7 +345,7 @@
//* check to make sure interface class, subclass and protocol match ADB
//* avoid opening mass storage endpoints
- if (!is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) {
+ if (!is_adb_interface(interfaceClass, interfaceSubClass, interfaceProtocol)) {
goto err_bad_adb_interface;
}
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index 4649454..755f07e 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -553,10 +553,9 @@
return 0;
}
- if (is_adb_interface(device_desc.idVendor, device_desc.idProduct,
- interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) {
-
- if(interf_desc.bInterfaceProtocol == 0x01) {
+ if (is_adb_interface(interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass,
+ interf_desc.bInterfaceProtocol)) {
+ if (interf_desc.bInterfaceProtocol == 0x01) {
AdbEndpointInformation endpoint_info;
// assuming zero is a valid bulk endpoint ID
if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index ed75e2d..2c8570e 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -21,17 +21,19 @@
#include <stdlib.h>
#include <limits>
+#include <string>
namespace android {
namespace base {
// Parses the unsigned decimal integer in the string 's' and sets 'out' to
// that value. Optionally allows the caller to define a 'max' beyond which
-// otherwise valid values will be rejected. Returns boolean success.
+// otherwise valid values will be rejected. Returns boolean success; 'out'
+// is untouched if parsing fails.
template <typename T>
bool ParseUint(const char* s, T* out,
T max = std::numeric_limits<T>::max()) {
- int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
errno = 0;
char* end;
unsigned long long int result = strtoull(s, &end, base);
@@ -45,15 +47,22 @@
return true;
}
+// TODO: string_view
+template <typename T>
+bool ParseUint(const std::string& s, T* out,
+ T max = std::numeric_limits<T>::max()) {
+ return ParseUint(s.c_str(), out, max);
+}
+
// Parses the signed decimal integer in the string 's' and sets 'out' to
// that value. Optionally allows the caller to define a 'min' and 'max
// beyond which otherwise valid values will be rejected. Returns boolean
-// success.
+// success; 'out' is untouched if parsing fails.
template <typename T>
bool ParseInt(const char* s, T* out,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max()) {
- int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
errno = 0;
char* end;
long long int result = strtoll(s, &end, base);
@@ -67,6 +76,14 @@
return true;
}
+// TODO: string_view
+template <typename T>
+bool ParseInt(const std::string& s, T* out,
+ T min = std::numeric_limits<T>::min(),
+ T max = std::numeric_limits<T>::max()) {
+ return ParseInt(s.c_str(), out, min, max);
+}
+
} // namespace base
} // namespace android
diff --git a/base/parseint_test.cpp b/base/parseint_test.cpp
index 6a3ba31..483b1d3 100644
--- a/base/parseint_test.cpp
+++ b/base/parseint_test.cpp
@@ -19,7 +19,7 @@
#include <gtest/gtest.h>
TEST(parseint, signed_smoke) {
- int i;
+ int i = 0;
ASSERT_FALSE(android::base::ParseInt("x", &i));
ASSERT_FALSE(android::base::ParseInt("123x", &i));
@@ -28,7 +28,7 @@
ASSERT_TRUE(android::base::ParseInt("-123", &i));
ASSERT_EQ(-123, i);
- short s;
+ short s = 0;
ASSERT_TRUE(android::base::ParseInt("1234", &s));
ASSERT_EQ(1234, s);
@@ -39,7 +39,7 @@
}
TEST(parseint, unsigned_smoke) {
- unsigned int i;
+ unsigned int i = 0u;
ASSERT_FALSE(android::base::ParseUint("x", &i));
ASSERT_FALSE(android::base::ParseUint("123x", &i));
@@ -47,7 +47,7 @@
ASSERT_EQ(123u, i);
ASSERT_FALSE(android::base::ParseUint("-123", &i));
- unsigned short s;
+ unsigned short s = 0u;
ASSERT_TRUE(android::base::ParseUint("1234", &s));
ASSERT_EQ(1234u, s);
@@ -58,21 +58,41 @@
}
TEST(parseint, no_implicit_octal) {
- int i;
+ int i = 0;
ASSERT_TRUE(android::base::ParseInt("0123", &i));
ASSERT_EQ(123, i);
- unsigned int u;
+ unsigned int u = 0u;
ASSERT_TRUE(android::base::ParseUint("0123", &u));
ASSERT_EQ(123u, u);
}
TEST(parseint, explicit_hex) {
- int i;
+ int i = 0;
ASSERT_TRUE(android::base::ParseInt("0x123", &i));
ASSERT_EQ(0x123, i);
- unsigned int u;
+ unsigned int u = 0u;
ASSERT_TRUE(android::base::ParseUint("0x123", &u));
ASSERT_EQ(0x123u, u);
}
+
+TEST(parseint, string) {
+ int i = 0;
+ ASSERT_TRUE(android::base::ParseInt(std::string("123"), &i));
+ ASSERT_EQ(123, i);
+
+ unsigned int u = 0u;
+ ASSERT_TRUE(android::base::ParseUint(std::string("123"), &u));
+ ASSERT_EQ(123u, u);
+}
+
+TEST(parseint, untouched_on_failure) {
+ int i = 123;
+ ASSERT_FALSE(android::base::ParseInt("456x", &i));
+ ASSERT_EQ(123, i);
+
+ unsigned int u = 123u;
+ ASSERT_FALSE(android::base::ParseInt("456x", &u));
+ ASSERT_EQ(123u, u);
+}
diff --git a/base/properties.cpp b/base/properties.cpp
index fab3005..37daf9a 100644
--- a/base/properties.cpp
+++ b/base/properties.cpp
@@ -52,7 +52,7 @@
T GetIntProperty(const std::string& key, T default_value, T min, T max) {
T result;
std::string value = GetProperty(key, "");
- if (!value.empty() && android::base::ParseInt(value.c_str(), &result, min, max)) return result;
+ if (!value.empty() && android::base::ParseInt(value, &result, min, max)) return result;
return default_value;
}
@@ -60,7 +60,7 @@
T GetUintProperty(const std::string& key, T default_value, T max) {
T result;
std::string value = GetProperty(key, "");
- if (!value.empty() && android::base::ParseUint(value.c_str(), &result, max)) return result;
+ if (!value.empty() && android::base::ParseUint(value, &result, max)) return result;
return default_value;
}
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 346eada..78be944 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -59,7 +59,7 @@
// Ignore existing bootstat records (which do not contain file content).
if (!content.empty()) {
int32_t value;
- if (android::base::ParseInt(content.c_str(), &value)) {
+ if (android::base::ParseInt(content, &value)) {
bootstat::LogHistogram("bootstat_mtime_matches_content", value == *uptime);
}
}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 0ab4c98..e5ddab3 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -60,7 +60,7 @@
BootEventRecordStore boot_event_store;
if (!value_str.empty()) {
int32_t value = 0;
- if (android::base::ParseInt(value_str.c_str(), &value)) {
+ if (android::base::ParseInt(value_str, &value)) {
boot_event_store.AddBootEventWithValue(event, value);
}
} else {
@@ -193,7 +193,7 @@
std::string build_date_str = GetProperty("ro.build.date.utc");
int32_t build_date;
- if (!android::base::ParseInt(build_date_str.c_str(), &build_date)) {
+ if (!android::base::ParseInt(build_date_str, &build_date)) {
return std::string();
}
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index 0e35323..b89c395 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -51,6 +51,8 @@
#define CANNED_LINE_LENGTH (1024)
#endif
+#define TRAILER "TRAILER!!!"
+
static int verbose = 0;
static int total_size = 0;
@@ -80,8 +82,8 @@
} else {
// Use the compiled-in fs_config() function.
unsigned st_mode = s->st_mode;
- fs_config(path, S_ISDIR(s->st_mode), target_out_path,
- &s->st_uid, &s->st_gid, &st_mode, &capabilities);
+ int is_dir = S_ISDIR(s->st_mode) || strcmp(path, TRAILER) == 0;
+ fs_config(path, is_dir, target_out_path, &s->st_uid, &s->st_gid, &st_mode, &capabilities);
s->st_mode = (typeof(s->st_mode)) st_mode;
}
}
@@ -140,7 +142,7 @@
{
struct stat s;
memset(&s, 0, sizeof(s));
- _eject(&s, "TRAILER!!!", 10, 0, 0);
+ _eject(&s, TRAILER, 10, 0, 0);
while(total_size & 0xff) {
total_size++;
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index cf37701..c67d747 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -31,6 +31,7 @@
#include <errno.h>
#include <inttypes.h>
#include <pthread.h>
+#include <sched.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
@@ -41,6 +42,7 @@
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/un.h>
+#include <sys/wait.h>
#include <unistd.h>
#include "private/libc_logging.h"
@@ -56,6 +58,13 @@
static debuggerd_callbacks_t g_callbacks;
+// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
+#define fatal(...) \
+ do { \
+ __libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \
+ _exit(1); \
+ } while (0)
+
static int socket_abstract_client(const char* name, int type) {
sockaddr_un addr;
@@ -188,7 +197,7 @@
return result;
}
-static void send_debuggerd_packet() {
+static void send_debuggerd_packet(pid_t crashing_tid, pid_t pseudothread_tid) {
// Mutex to prevent multiple crashing threads from trying to talk
// to debuggerd at the same time.
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -218,7 +227,8 @@
// that's actually in our process.
debugger_msg_t msg;
msg.action = DEBUGGER_ACTION_CRASH;
- msg.tid = gettid();
+ msg.tid = crashing_tid;
+ msg.ignore_tid = pseudothread_tid;
msg.abort_msg_address = 0;
if (g_callbacks.get_abort_message) {
@@ -229,11 +239,9 @@
if (ret == sizeof(msg)) {
char debuggerd_ack;
ret = TEMP_FAILURE_RETRY(read(s, &debuggerd_ack, 1));
- int saved_errno = errno;
if (g_callbacks.post_dump) {
g_callbacks.post_dump();
}
- errno = saved_errno;
} else {
// read or write failed -- broken connection?
__libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed while talking to debuggerd: %s",
@@ -243,6 +251,33 @@
close(s);
}
+struct debugger_thread_info {
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pid_t crashing_tid;
+ pid_t pseudothread_tid;
+ int signal_number;
+ siginfo_t* info;
+};
+
+// Logging and contacting debuggerd requires free file descriptors, which we might not have.
+// Work around this by spawning a "thread" that shares its parent's address space, but not its file
+// descriptor table, so that we can close random file descriptors without affecting the original
+// process. Note that this doesn't go through pthread_create, so TLS is shared with the spawning
+// process.
+static void* pseudothread_stack;
+static int debuggerd_dispatch_pseudothread(void* arg) {
+ debugger_thread_info* thread_info = static_cast<debugger_thread_info*>(arg);
+
+ for (int i = 3; i < 1024; ++i) {
+ close(i);
+ }
+
+ log_signal_summary(thread_info->signal_number, thread_info->info);
+ send_debuggerd_packet(thread_info->crashing_tid, thread_info->pseudothread_tid);
+ pthread_mutex_unlock(&thread_info->mutex);
+ return 0;
+}
+
/*
* Catches fatal signals so we can ask debuggerd to ptrace us before
* we crash.
@@ -254,9 +289,25 @@
info = nullptr;
}
- log_signal_summary(signal_number, info);
+ debugger_thread_info thread_info = {
+ .crashing_tid = gettid(),
+ .signal_number = signal_number,
+ .info = info
+ };
- send_debuggerd_packet();
+ pthread_mutex_lock(&thread_info.mutex);
+ pid_t child_pid = clone(debuggerd_dispatch_pseudothread, pseudothread_stack,
+ CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID,
+ &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid);
+
+ if (child_pid == -1) {
+ fatal("failed to spawn debuggerd dispatch thread: %s", strerror(errno));
+ }
+
+ // Wait for the child to finish and unlock the mutex.
+ // This relies on bionic behavior that isn't guaranteed by the standard.
+ pthread_mutex_lock(&thread_info.mutex);
+
// We need to return from the signal handler so that debuggerd can dump the
// thread that crashed, but returning here does not guarantee that the signal
@@ -281,9 +332,7 @@
int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), signal_number, info);
if (rc != 0) {
- __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to resend signal during crash: %s",
- strerror(errno));
- _exit(0);
+ fatal("failed to resend signal during crash: %s", strerror(errno));
}
}
@@ -292,6 +341,23 @@
g_callbacks = *callbacks;
}
+ void* thread_stack_allocation =
+ mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (thread_stack_allocation == MAP_FAILED) {
+ fatal("failed to allocate debuggerd thread stack");
+ }
+
+ char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE;
+ if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
+ fatal("failed to mprotect debuggerd thread stack");
+ }
+
+ // Stack grows negatively, set it to the last byte in the page...
+ stack = (stack + PAGE_SIZE - 1);
+ // and align it.
+ stack -= 15;
+ pseudothread_stack = stack;
+
struct sigaction action;
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
diff --git a/debuggerd/crasher.cpp b/debuggerd/crasher.cpp
index 7d3509c..cfcc26e 100644
--- a/debuggerd/crasher.cpp
+++ b/debuggerd/crasher.cpp
@@ -1,5 +1,6 @@
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
@@ -141,7 +142,13 @@
{
fprintf(stderr, "%s: init pid=%d tid=%d\n", __progname, getpid(), gettid());
- if (!strncmp(arg, "thread-", strlen("thread-"))) {
+ if (!strncmp(arg, "exhaustfd-", strlen("exhaustfd-"))) {
+ errno = 0;
+ while (errno != EMFILE) {
+ open("/dev/null", O_RDONLY);
+ }
+ return do_action(arg + strlen("exhaustfd-"));
+ } else if (!strncmp(arg, "thread-", strlen("thread-"))) {
return do_action_on_thread(arg + strlen("thread-"));
} else if (!strcmp(arg, "SIGSEGV-non-null")) {
sigsegv_non_null();
@@ -208,6 +215,8 @@
fprintf(stderr, " SIGTRAP cause a SIGTRAP\n");
fprintf(stderr, "prefix any of the above with 'thread-' to not run\n");
fprintf(stderr, "on the process' main thread.\n");
+ fprintf(stderr, "prefix any of the above with 'exhaustfd-' to exhaust\n");
+ fprintf(stderr, "all available file descriptors before crashing.\n");
return EXIT_SUCCESS;
}
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index a6d3d38..b8a62a5 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -69,6 +69,7 @@
debugger_action_t action;
pid_t pid, tid;
uid_t uid, gid;
+ pid_t ignore_tid;
uintptr_t abort_msg_address;
};
@@ -215,6 +216,7 @@
out_request->action = static_cast<debugger_action_t>(msg.action);
out_request->tid = msg.tid;
+ out_request->ignore_tid = msg.ignore_tid;
out_request->pid = cr.pid;
out_request->uid = cr.uid;
out_request->gid = cr.gid;
@@ -408,7 +410,7 @@
}
#endif
-static void ptrace_siblings(pid_t pid, pid_t main_tid, std::set<pid_t>& tids) {
+static void ptrace_siblings(pid_t pid, pid_t main_tid, pid_t ignore_tid, std::set<pid_t>& tids) {
char task_path[64];
snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
@@ -434,7 +436,7 @@
continue;
}
- if (tid == main_tid) {
+ if (tid == main_tid || tid == ignore_tid) {
continue;
}
@@ -583,7 +585,7 @@
std::set<pid_t> siblings;
if (!attach_gdb) {
- ptrace_siblings(request.pid, request.tid, siblings);
+ ptrace_siblings(request.pid, request.tid, request.ignore_tid, siblings);
}
// Generate the backtrace map before dropping privileges.
diff --git a/debuggerd/include/debuggerd/client.h b/debuggerd/include/debuggerd/client.h
index 8225c73..aeb723b 100644
--- a/debuggerd/include/debuggerd/client.h
+++ b/debuggerd/include/debuggerd/client.h
@@ -43,6 +43,7 @@
typedef struct __attribute__((packed)) {
int32_t action;
pid_t tid;
+ pid_t ignore_tid;
uint64_t abort_msg_address;
} debugger_msg_t;
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index b950e9c..286de5b 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -21,7 +21,6 @@
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../adb \
$(LOCAL_PATH)/../mkbootimg \
- $(LOCAL_PATH)/../../extras/ext4_utils \
$(LOCAL_PATH)/../../extras/f2fs_utils \
LOCAL_SRC_FILES := \
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index d6b631f..4cd423a 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -755,7 +755,7 @@
max_download_size = android::base::Trim(max_download_size);
uint64_t limit;
- if (!android::base::ParseUint(max_download_size.c_str(), &limit)) {
+ if (!android::base::ParseUint(max_download_size, &limit)) {
fprintf(stderr, "couldn't parse max-download-size '%s'\n", max_download_size.c_str());
return 0;
}
@@ -903,7 +903,7 @@
if (!fb_getvar(transport, "slot-count", &var)) {
if (supports_AB_obsolete(transport)) return 2; // Legacy support
}
- if (!android::base::ParseInt(var.c_str(), &count)) return 0;
+ if (!android::base::ParseInt(var, &count)) return 0;
return count;
}
@@ -1362,7 +1362,7 @@
}
int64_t size;
- if (!android::base::ParseInt(partition_size.c_str(), &size)) {
+ if (!android::base::ParseInt(partition_size, &size)) {
fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str());
return;
}
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 8539e23..9b73165 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -1,7 +1,6 @@
#include "fs.h"
#include "fastboot.h"
-#include "make_ext4fs.h"
#include "make_f2fs.h"
#include <errno.h>
@@ -12,6 +11,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <ext4_utils/make_ext4fs.h>
#include <sparse/sparse.h>
static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir)
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index b11ce75..2ed6b91 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -30,20 +30,18 @@
#include <time.h>
#include <unistd.h>
-#include <ext4.h>
-#include <ext4_crypt_init_extensions.h>
-#include <ext4_sb.h>
-
#include <cutils/android_reboot.h>
#include <cutils/partition_utils.h>
#include <cutils/properties.h>
+#include <ext4_utils/ext4.h>
+#include <ext4_utils/ext4_crypt_init_extensions.h>
+#include <ext4_utils/ext4_sb.h>
+#include <ext4_utils/ext4_utils.h>
+#include <ext4_utils/wipe.h>
#include <linux/loop.h>
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
-#include "ext4_utils.h"
-#include "wipe.h"
-
#include "fs_mgr_priv.h"
#include "fs_mgr_priv_verity.h"
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
index 7ee5832..7c3b1ed 100644
--- a/fs_mgr/fs_mgr_format.c
+++ b/fs_mgr/fs_mgr_format.c
@@ -24,13 +24,13 @@
#include <cutils/partition_utils.h>
#include <sys/mount.h>
+#include <ext4_utils/ext4_utils.h>
+#include <ext4_utils/ext4.h>
+#include <ext4_utils/make_ext4fs.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/android.h>
-#include "ext4_utils.h"
-#include "ext4.h"
-#include "make_ext4fs.h"
#include "fs_mgr_priv.h"
#include "cryptfs.h"
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index f81e7d9..0c90a54 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -29,6 +29,7 @@
#include <memory>
#include <android-base/file.h>
+#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <batteryservice/BatteryService.h>
#include <cutils/klog.h>
@@ -182,7 +183,7 @@
int value = 0;
if (readFromFile(path, &buf) > 0)
- value = std::stoi(buf.c_str(), NULL, 0);
+ android::base::ParseInt(buf, &value);
return value;
}
diff --git a/include/android/log.h b/include/android/log.h
index 5f20f8c..9b26839 100644
--- a/include/android/log.h
+++ b/include/android/log.h
@@ -178,9 +178,6 @@
size_t len);
int __android_log_bswrite(int32_t tag, const char *payload);
-int __android_log_security_bwrite(int32_t tag, const void *payload, size_t len);
-int __android_log_security_bswrite(int32_t tag, const char *payload);
-
// ---------------------------------------------------------------------
/*
@@ -820,8 +817,6 @@
int __android_log_is_loggable(int prio, const char *tag, int default_prio);
int __android_log_is_loggable_len(int prio, const char *tag, size_t len, int default_prio);
-int __android_log_security(); /* Device Owner is present */
-
int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,
uint32_t dataLen);
diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h
index 31695cb..7d6a988 100644
--- a/include/cutils/native_handle.h
+++ b/include/cutils/native_handle.h
@@ -17,10 +17,17 @@
#ifndef NATIVE_HANDLE_H_
#define NATIVE_HANDLE_H_
+#include <stdalign.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+/* Declare a char array for use with native_handle_init */
+#define NATIVE_HANDLE_DECLARE_STORAGE(name, maxFds, maxInts) \
+ alignas(native_handle_t) char name[ \
+ sizeof(native_handle_t) + sizeof(int) * (maxFds + maxInts)]
+
typedef struct native_handle
{
int version; /* sizeof(native_handle_t) */
@@ -46,6 +53,14 @@
*/
int native_handle_close(const native_handle_t* h);
+/*
+ * native_handle_init
+ *
+ * Initializes a native_handle_t from storage. storage must be declared with
+ * NATIVE_HANDLE_DECLARE_STORAGE. numFds and numInts must not respectively
+ * exceed maxFds and maxInts used to declare the storage.
+ */
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts);
/*
* native_handle_create
@@ -57,6 +72,15 @@
native_handle_t* native_handle_create(int numFds, int numInts);
/*
+ * native_handle_clone
+ *
+ * creates a native_handle_t and initializes it from another native_handle_t.
+ * Must be destroyed with native_handle_delete().
+ *
+ */
+native_handle_t* native_handle_clone(const native_handle_t* handle);
+
+/*
* native_handle_delete
*
* frees a native_handle_t allocated with native_handle_create().
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index a93c8ea..b9c22c1 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -89,6 +89,7 @@
int socket_network_client_timeout(const char* host, int port, int type,
int timeout, int* getaddrinfo_error);
int socket_loopback_server(int port, int type);
+int socket_loopback_server6(int port, int type);
int socket_local_server(const char* name, int namespaceId, int type);
int socket_local_server_bind(int s, const char* name, int namespaceId);
int socket_local_client_connect(int fd, const char *name, int namespaceId,
diff --git a/include/private/android_logger.h b/include/private/android_logger.h
index d477ac1..141001c 100644
--- a/include/private/android_logger.h
+++ b/include/private/android_logger.h
@@ -126,6 +126,10 @@
log_id_t logId, char prio, const char *prefix,
__android_log_pmsg_file_read_fn fn, void *arg);
+int __android_log_security_bwrite(int32_t tag, const void *payload, size_t len);
+int __android_log_security_bswrite(int32_t tag, const char *payload);
+int __android_log_security(); /* Device Owner is present */
+
#if defined(__cplusplus)
}
#endif
diff --git a/init/Android.mk b/init/Android.mk
index 4a8df32..704304e 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -74,7 +74,6 @@
LOCAL_MODULE:= init
LOCAL_C_INCLUDES += \
- system/extras/ext4_utils \
system/core/mkbootimg
LOCAL_FORCE_STATIC_EXECUTABLE := true
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 200b723..da4b84e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -37,8 +37,6 @@
#include <unistd.h>
#include <linux/loop.h>
#include <linux/module.h>
-#include <ext4_crypt.h>
-#include <ext4_crypt_init_extensions.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -51,6 +49,8 @@
#include <bootloader_message_writer.h>
#include <cutils/partition_utils.h>
#include <cutils/android_reboot.h>
+#include <ext4_utils/ext4_crypt.h>
+#include <ext4_utils/ext4_crypt_init_extensions.h>
#include <logwrap/logwrap.h>
#include "action.h"
@@ -304,7 +304,7 @@
/* mkdir <path> [mode] [owner] [group] */
if (args.size() >= 3) {
- mode = std::stoul(args[2], 0, 8);
+ mode = std::strtoul(args[2].c_str(), 0, 8);
}
ret = make_dir(args[1].c_str(), mode);
@@ -637,10 +637,13 @@
static int do_setrlimit(const std::vector<std::string>& args) {
struct rlimit limit;
int resource;
- resource = std::stoi(args[1]);
- limit.rlim_cur = std::stoi(args[2]);
- limit.rlim_max = std::stoi(args[3]);
- return setrlimit(resource, &limit);
+ if (android::base::ParseInt(args[1], &resource) &&
+ android::base::ParseUint(args[2], &limit.rlim_cur) &&
+ android::base::ParseUint(args[3], &limit.rlim_max)) {
+ return setrlimit(resource, &limit);
+ }
+ LOG(WARNING) << "ignoring setrlimit " << args[1] << " " << args[2] << " " << args[3];
+ return -1;
}
static int do_start(const std::vector<std::string>& args) {
@@ -709,7 +712,7 @@
std::string timeout = property_get("ro.build.shutdown_timeout");
unsigned int delay = 0;
- if (android::base::ParseUint(timeout.c_str(), &delay) && delay > 0) {
+ if (android::base::ParseUint(timeout, &delay) && delay > 0) {
Timer t;
// Ask all services to terminate.
ServiceManager::GetInstance().ForEachService(
@@ -764,13 +767,11 @@
}
static int do_sysclktz(const std::vector<std::string>& args) {
- struct timezone tz;
-
- memset(&tz, 0, sizeof(tz));
- tz.tz_minuteswest = std::stoi(args[1]);
- if (settimeofday(NULL, &tz))
- return -1;
- return 0;
+ struct timezone tz = {};
+ if (android::base::ParseInt(args[1], &tz.tz_minuteswest) && settimeofday(NULL, &tz) != -1) {
+ return 0;
+ }
+ return -1;
}
static int do_verity_load_state(const std::vector<std::string>& args) {
@@ -914,7 +915,8 @@
static int do_loglevel(const std::vector<std::string>& args) {
// TODO: support names instead/as well?
- int log_level = std::stoi(args[1]);
+ int log_level = -1;
+ android::base::ParseInt(args[1], &log_level);
android::base::LogSeverity severity;
switch (log_level) {
case 7: severity = android::base::DEBUG; break;
@@ -947,9 +949,12 @@
if (args.size() == 2) {
return wait_for_file(args[1].c_str(), COMMAND_RETRY_TIMEOUT);
} else if (args.size() == 3) {
- return wait_for_file(args[1].c_str(), std::stoi(args[2]));
- } else
- return -1;
+ int timeout;
+ if (android::base::ParseInt(args[2], &timeout)) {
+ return wait_for_file(args[1].c_str(), timeout);
+ }
+ }
+ return -1;
}
/*
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 9ec26af..d017390 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -122,14 +122,20 @@
return false;
}
dirent* current_file;
+ std::vector<std::string> files;
while ((current_file = readdir(config_dir.get()))) {
- std::string current_path =
- android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
// Ignore directories and only process regular files.
if (current_file->d_type == DT_REG) {
- if (!ParseConfigFile(current_path)) {
- LOG(ERROR) << "could not import file '" << current_path << "'";
- }
+ std::string current_path =
+ android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
+ files.emplace_back(current_path);
+ }
+ }
+ // Sort first so we load files in a consistent order (bug 31996208)
+ std::sort(files.begin(), files.end());
+ for (const auto& file : files) {
+ if (!ParseConfigFile(file)) {
+ LOG(ERROR) << "could not import file '" << file << "'";
}
}
return true;
diff --git a/init/service.cpp b/init/service.cpp
index 503d84f..22fb013 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -31,6 +31,7 @@
#include <selinux/selinux.h>
#include <android-base/file.h>
+#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/android_reboot.h>
@@ -46,6 +47,7 @@
#include "property_service.h"
#include "util.h"
+using android::base::ParseInt;
using android::base::StringPrintf;
using android::base::WriteStringToFile;
@@ -351,22 +353,19 @@
}
bool Service::ParsePriority(const std::vector<std::string>& args, std::string* err) {
- priority_ = std::stoi(args[1]);
-
- if (priority_ < ANDROID_PRIORITY_HIGHEST || priority_ > ANDROID_PRIORITY_LOWEST) {
- priority_ = 0;
+ priority_ = 0;
+ if (!ParseInt(args[1], &priority_,
+ static_cast<int>(ANDROID_PRIORITY_LOWEST),
+ static_cast<int>(ANDROID_PRIORITY_HIGHEST))) {
*err = StringPrintf("process priority value must be range %d - %d",
ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST);
return false;
}
-
return true;
}
bool Service::ParseIoprio(const std::vector<std::string>& args, std::string* err) {
- ioprio_pri_ = std::stoul(args[2], 0, 8);
-
- if (ioprio_pri_ < 0 || ioprio_pri_ > 7) {
+ if (!ParseInt(args[2], &ioprio_pri_, 0, 7)) {
*err = "priority value must be range 0 - 7";
return false;
}
@@ -387,7 +386,12 @@
bool Service::ParseKeycodes(const std::vector<std::string>& args, std::string* err) {
for (std::size_t i = 1; i < args.size(); i++) {
- keycodes_.emplace_back(std::stoi(args[i]));
+ int code;
+ if (ParseInt(args[i], &code)) {
+ keycodes_.emplace_back(code);
+ } else {
+ LOG(WARNING) << "ignoring invalid keycode: " << args[i];
+ }
}
return true;
}
@@ -420,17 +424,13 @@
}
bool Service::ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err) {
- oom_score_adjust_ = std::stol(args[1], 0, 10);
-
- if (oom_score_adjust_ < -1000 || oom_score_adjust_ > 1000) {
+ if (!ParseInt(args[1], &oom_score_adjust_, -1000, 1000)) {
*err = "oom_score_adjust value must be in range -1000 - +1000";
return false;
}
-
return true;
}
-
bool Service::ParseSeclabel(const std::vector<std::string>& args, std::string* err) {
seclabel_ = args[1];
return true;
@@ -448,7 +448,7 @@
return false;
}
- int perm = std::stoul(args[3], 0, 8);
+ int perm = std::strtoul(args[3].c_str(), 0, 8);
uid_t uid = args.size() > 4 ? decode_uid(args[4].c_str()) : 0;
gid_t gid = args.size() > 5 ? decode_uid(args[5].c_str()) : 0;
std::string socketcon = args.size() > 6 ? args[6] : "";
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index fd8b713..148c418 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -17,6 +17,7 @@
#include <errno.h>
#include <stdint.h>
#include <string.h>
+#include <sys/uio.h>
#include <sys/param.h>
#include <sys/ptrace.h>
#include <sys/types.h>
@@ -72,42 +73,20 @@
if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) {
return 0;
}
-
bytes = MIN(map.end - addr, bytes);
- size_t bytes_read = 0;
- word_t data_word;
- size_t align_bytes = addr & (sizeof(word_t) - 1);
- if (align_bytes != 0) {
- if (!PtraceRead(Tid(), addr & ~(sizeof(word_t) - 1), &data_word)) {
- return 0;
- }
- 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);
- for (size_t i = 0; i < num_words; i++) {
- if (!PtraceRead(Tid(), addr, &data_word)) {
- return bytes_read;
- }
- memcpy(buffer, &data_word, sizeof(word_t));
- buffer += sizeof(word_t);
- addr += sizeof(word_t);
- bytes_read += sizeof(word_t);
- }
+ struct iovec local_io;
+ local_io.iov_base = buffer;
+ local_io.iov_len = bytes;
- size_t left_over = bytes & (sizeof(word_t) - 1);
- if (left_over) {
- if (!PtraceRead(Tid(), addr, &data_word)) {
- return bytes_read;
- }
- memcpy(buffer, &data_word, left_over);
- bytes_read += left_over;
+ struct iovec remote_io;
+ remote_io.iov_base = reinterpret_cast<void*>(addr);
+ remote_io.iov_len = bytes;
+
+ ssize_t bytes_read = process_vm_readv(Tid(), &local_io, 1, &remote_io, 1, 0);
+ if (bytes_read == -1) {
+ return 0;
}
- return bytes_read;
+ return static_cast<size_t>(bytes_read);
#endif
}
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 2110701..94275bd 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -87,12 +87,6 @@
"uevent.c",
],
- // TODO: remove liblog as whole static library, once we don't have prebuilt that requires
- // liblog symbols present in libcutils.
- whole_static_libs: [
- "liblog",
- ],
-
static_libs: ["libdebuggerd_client"],
export_static_lib_headers: ["libdebuggerd_client"],
},
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 7f3479d..9f4840a 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -28,6 +28,20 @@
static const int kMaxNativeFds = 1024;
static const int kMaxNativeInts = 1024;
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts)
+{
+ if ((uintptr_t) storage % alignof(native_handle_t)) {
+ return NULL;
+ }
+
+ native_handle_t* handle = (native_handle_t*) storage;
+ handle->version = sizeof(native_handle_t);
+ handle->numFds = numFds;
+ handle->numInts = numInts;
+
+ return handle;
+}
+
native_handle_t* native_handle_create(int numFds, int numInts)
{
if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
@@ -44,6 +58,27 @@
return h;
}
+native_handle_t* native_handle_clone(const native_handle_t* handle)
+{
+ native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
+ int i;
+
+ for (i = 0; i < handle->numFds; i++) {
+ clone->data[i] = dup(handle->data[i]);
+ if (clone->data[i] < 0) {
+ clone->numFds = i;
+ native_handle_close(clone);
+ native_handle_delete(clone);
+ return NULL;
+ }
+ }
+
+ memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
+ sizeof(int) * handle->numInts);
+
+ return clone;
+}
+
int native_handle_delete(native_handle_t* h)
{
if (h) {
diff --git a/libcutils/socket_loopback_client_unix.c b/libcutils/socket_loopback_client_unix.c
index e14cffb..137e369 100644
--- a/libcutils/socket_loopback_client_unix.c
+++ b/libcutils/socket_loopback_client_unix.c
@@ -35,23 +35,6 @@
*/
int socket_loopback_client(int port, int type)
{
- struct sockaddr_in addr;
- int s;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- s = socket(AF_INET, type, 0);
- if(s < 0) return -1;
-
- if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- close(s);
- return -1;
- }
-
- return s;
-
+ return socket_network_client("localhost", port, type);
}
diff --git a/libcutils/socket_loopback_server_unix.c b/libcutils/socket_loopback_server_unix.c
index b600e34..7b92fd6 100644
--- a/libcutils/socket_loopback_server_unix.c
+++ b/libcutils/socket_loopback_server_unix.c
@@ -31,24 +31,18 @@
#include <cutils/sockets.h>
-/* open listen() port on loopback interface */
-int socket_loopback_server(int port, int type)
+static int _socket_loopback_server(int family, int type, struct sockaddr * addr, size_t size)
{
- struct sockaddr_in addr;
int s, n;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- s = socket(AF_INET, type, 0);
- if(s < 0) return -1;
+ s = socket(family, type, 0);
+ if(s < 0)
+ return -1;
n = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
- if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if(bind(s, addr, size) < 0) {
close(s);
return -1;
}
@@ -60,10 +54,35 @@
if (ret < 0) {
close(s);
- return -1;
+ return -1;
}
}
return s;
}
+/* open listen() port on loopback IPv6 interface */
+int socket_loopback_server6(int port, int type)
+{
+ struct sockaddr_in6 addr;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(port);
+ addr.sin6_addr = in6addr_loopback;
+
+ return _socket_loopback_server(AF_INET6, type, (struct sockaddr *) &addr, sizeof(addr));
+}
+
+/* open listen() port on loopback interface */
+int socket_loopback_server(int port, int type)
+{
+ struct sockaddr_in addr;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ return _socket_loopback_server(AF_INET, type, (struct sockaddr *) &addr, sizeof(addr));
+}
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index a4244cd..11d8afb 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -22,8 +22,7 @@
#include <stdlib.h>
#include <string.h>
-#include <android/log.h>
-#include <log/logger.h>
+#include <private/android_logger.h>
#include "log_portability.h"
diff --git a/libsparse/output_file.c b/libsparse/output_file.c
index 6578d99..2115998 100644
--- a/libsparse/output_file.c
+++ b/libsparse/output_file.c
@@ -63,7 +63,7 @@
int (*open)(struct output_file *, int fd);
int (*skip)(struct output_file *, int64_t);
int (*pad)(struct output_file *, int64_t);
- int (*write)(struct output_file *, void *, int);
+ int (*write)(struct output_file *, void *, size_t);
void (*close)(struct output_file *);
};
@@ -149,18 +149,23 @@
return 0;
}
-static int file_write(struct output_file *out, void *data, int len)
+static int file_write(struct output_file *out, void *data, size_t len)
{
- int ret;
+ ssize_t ret;
struct output_file_normal *outn = to_output_file_normal(out);
- ret = write(outn->fd, data, len);
- if (ret < 0) {
- error_errno("write");
- return -1;
- } else if (ret < len) {
- error("incomplete write");
- return -1;
+ while (len > 0) {
+ ret = write(outn->fd, data, len);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ error_errno("write");
+ return -1;
+ }
+
+ data = (char *)data + ret;
+ len -= ret;
}
return 0;
@@ -232,18 +237,20 @@
return 0;
}
-static int gz_file_write(struct output_file *out, void *data, int len)
+static int gz_file_write(struct output_file *out, void *data, size_t len)
{
int ret;
struct output_file_gz *outgz = to_output_file_gz(out);
- ret = gzwrite(outgz->gz_fd, data, len);
- if (ret < 0) {
- error_errno("gzwrite");
- return -1;
- } else if (ret < len) {
- error("incomplete gzwrite");
- return -1;
+ while (len > 0) {
+ ret = gzwrite(outgz->gz_fd, data,
+ min(len, (unsigned int)INT_MAX));
+ if (ret == 0) {
+ error("gzwrite %s", gzerror(outgz->gz_fd, NULL));
+ return -1;
+ }
+ len -= ret;
+ data = (char *)data + ret;
}
return 0;
@@ -293,7 +300,7 @@
return -1;
}
-static int callback_file_write(struct output_file *out, void *data, int len)
+static int callback_file_write(struct output_file *out, void *data, size_t len)
{
struct output_file_callback *outc = to_output_file_callback(out);
@@ -698,14 +705,16 @@
int ret;
int64_t aligned_offset;
int aligned_diff;
- int buffer_size;
+ uint64_t buffer_size;
char *ptr;
aligned_offset = offset & ~(4096 - 1);
aligned_diff = offset - aligned_offset;
- buffer_size = len + aligned_diff;
+ buffer_size = (uint64_t)len + (uint64_t)aligned_diff;
#ifndef _WIN32
+ if (buffer_size > SIZE_MAX)
+ return -E2BIG;
char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
aligned_offset);
if (data == MAP_FAILED) {
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 9c9043e..66800b1 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -570,6 +570,14 @@
EXPECT_EQ(1, signals);
}
+// meant to be handed to ASSERT_FALSE / EXPECT_FALSE to expand the message
+static testing::AssertionResult IsFalse(int ret, const char* command) {
+ return ret ?
+ (testing::AssertionSuccess() <<
+ "ret=" << ret << " command=\"" << command << "\"") :
+ testing::AssertionFailure();
+}
+
TEST(logcat, logrotate) {
static const char form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
char buf[sizeof(form)];
@@ -581,7 +589,7 @@
snprintf(command, sizeof(command), comm, buf);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (!ret) {
snprintf(command, sizeof(command), "ls -s %s 2>/dev/null", buf);
@@ -611,7 +619,7 @@
}
}
snprintf(command, sizeof(command), "rm -rf %s", buf);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
}
TEST(logcat, logrotate_suffix) {
@@ -625,7 +633,7 @@
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (!ret) {
snprintf(command, sizeof(command), "ls %s 2>/dev/null", tmp_out_dir);
@@ -664,7 +672,7 @@
EXPECT_EQ(11, log_file_count);
}
snprintf(command, sizeof(command), "rm -rf %s", tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
}
TEST(logcat, logrotate_continue) {
@@ -679,10 +687,10 @@
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (ret) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
FILE *fp;
@@ -690,7 +698,7 @@
EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
if (!fp) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
char *line = NULL;
@@ -714,23 +722,23 @@
EXPECT_TRUE(NULL != second_last_line);
if (!second_last_line) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
// re-run the command, it should only add a few lines more content if it
// continues where it left off.
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (ret) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
EXPECT_NE(nullptr, dir);
if (!dir) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
struct dirent *entry;
@@ -769,7 +777,7 @@
free(second_last_line);
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
}
TEST(logcat, logrotate_clear) {
@@ -790,17 +798,17 @@
logcat_cmd, tmp_out_dir, log_filename, num_val);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (ret) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
EXPECT_NE(nullptr, dir);
if (!dir) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
struct dirent *entry;
@@ -819,17 +827,18 @@
strcat(command, clear_cmd);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (ret) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
EXPECT_NE(nullptr, dir);
if (!dir) {
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
return;
}
struct dirent *entry;
@@ -845,7 +854,7 @@
}
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
}
static int logrotate_count_id(const char *logcat_cmd, const char *tmp_out_dir) {
@@ -856,7 +865,7 @@
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
int ret;
- EXPECT_FALSE((ret = system(command)));
+ EXPECT_FALSE(IsFalse(ret = system(command), command));
if (ret) {
return -1;
}
@@ -914,7 +923,7 @@
static const char cleanup_cmd[] = "rm -rf %s";
char command[strlen(cleanup_cmd) + strlen(tmp_out_dir_form)];
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
- EXPECT_FALSE(system(command));
+ EXPECT_FALSE(IsFalse(system(command), command));
}
TEST(logcat, logrotate_nodir) {
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index c6ebd52..f69bc50 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -21,6 +21,8 @@
#include <sys/types.h>
#include <unistd.h>
+#include <list>
+
#include <log/logger.h>
#include "LogStatistics.h"
@@ -467,55 +469,86 @@
short spaces = 1;
log_id_for_each(id) {
- if (!(logMask & (1 << id))) {
- continue;
- }
+ if (!(logMask & (1 << id))) continue;
oldLength = output.length();
- if (spaces < 0) {
- spaces = 0;
- }
+ if (spaces < 0) spaces = 0;
output += android::base::StringPrintf("%*s%s", spaces, "",
android_log_id_to_name(id));
spaces += spaces_total + oldLength - output.length();
}
+ if (spaces < 0) spaces = 0;
+ output += android::base::StringPrintf("%*sTotal", spaces, "");
- spaces = 4;
- output += "\nTotal";
+ static const char TotalStr[] = "\nTotal";
+ spaces = 10 - strlen(TotalStr);
+ output += TotalStr;
+ size_t totalSize = 0;
+ size_t totalEls = 0;
log_id_for_each(id) {
- if (!(logMask & (1 << id))) {
- continue;
- }
+ if (!(logMask & (1 << id))) continue;
oldLength = output.length();
- if (spaces < 0) {
- spaces = 0;
- }
- output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
- sizesTotal(id),
- elementsTotal(id));
+ if (spaces < 0) spaces = 0;
+ size_t szs = sizesTotal(id);
+ totalSize += szs;
+ size_t els = elementsTotal(id);
+ totalEls += els;
+ output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
spaces += spaces_total + oldLength - output.length();
}
+ if (spaces < 0) spaces = 0;
+ output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls);
- spaces = 6;
- output += "\nNow";
+ static const char NowStr[] = "\nNow";
+ spaces = 10 - strlen(NowStr);
+ output += NowStr;
+ totalSize = 0;
+ totalEls = 0;
log_id_for_each(id) {
- if (!(logMask & (1 << id))) {
- continue;
- }
+ if (!(logMask & (1 << id))) continue;
size_t els = elements(id);
if (els) {
oldLength = output.length();
- if (spaces < 0) {
- spaces = 0;
- }
- output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
- sizes(id), els);
+ if (spaces < 0) spaces = 0;
+ size_t szs = sizes(id);
+ totalSize += szs;
+ totalEls += els;
+ output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
spaces -= output.length() - oldLength;
}
spaces += spaces_total;
}
+ if (spaces < 0) spaces = 0;
+ output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls);
+
+ static const char OverheadStr[] = "\nOverhead";
+ spaces = 10 - strlen(OverheadStr);
+ output += OverheadStr;
+
+ totalSize = 0;
+ log_id_for_each(id) {
+ if (!(logMask & (1 << id))) continue;
+
+ size_t els = elements(id);
+ if (els) {
+ oldLength = output.length();
+ if (spaces < 0) spaces = 0;
+ // estimate the std::list overhead.
+ static const size_t overhead =
+ ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) &
+ -sizeof(uint64_t)) +
+ sizeof(std::list<LogBufferElement*>);
+ size_t szs = sizes(id) + els * overhead;
+ totalSize += szs;
+ output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
+ spaces -= output.length() - oldLength;
+ }
+ spaces += spaces_total;
+ }
+ if (spaces < 0) spaces = 0;
+ output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
// Report on Chattiest
@@ -523,9 +556,7 @@
// Chattiest by application (UID)
log_id_for_each(id) {
- if (!(logMask & (1 << id))) {
- continue;
- }
+ if (!(logMask & (1 << id))) continue;
name = (uid == AID_ROOT)
? "Chattiest UIDs in %s log buffer:"
@@ -539,27 +570,21 @@
: "Logging for this PID:";
output += pidTable.format(*this, uid, pid, name);
name = "Chattiest TIDs";
- if (pid) {
- name += android::base::StringPrintf(" for PID %d", pid);
- }
+ if (pid) name += android::base::StringPrintf(" for PID %d", pid);
name += ":";
output += tidTable.format(*this, uid, pid, name);
}
if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
name = "Chattiest events log buffer TAGs";
- if (pid) {
- name += android::base::StringPrintf(" for PID %d", pid);
- }
+ if (pid) name += android::base::StringPrintf(" for PID %d", pid);
name += ":";
output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
}
if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
name = "Chattiest security log buffer TAGs";
- if (pid) {
- name += android::base::StringPrintf(" for PID %d", pid);
- }
+ if (pid) name += android::base::StringPrintf(" for PID %d", pid);
name += ":";
output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
}
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index f549606..d4c51fd 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
#define LOG_TAG "sdcard"
#include "fuse.h"
@@ -223,7 +227,8 @@
}
static int touch(char* path, mode_t mode) {
- int fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
+ int fd = TEMP_FAILURE_RETRY(open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC,
+ mode));
if (fd == -1) {
if (errno == EEXIST) {
return 0;
@@ -469,27 +474,34 @@
hdr.len = sizeof(hdr);
hdr.error = err;
hdr.unique = unique;
- write(fuse->fd, &hdr, sizeof(hdr));
+ ssize_t ret = TEMP_FAILURE_RETRY(write(fuse->fd, &hdr, sizeof(hdr)));
+ if (ret == -1) {
+ PLOG(ERROR) << "*** STATUS FAILED ***";
+ } else if (static_cast<size_t>(ret) != sizeof(hdr)) {
+ LOG(ERROR) << "*** STATUS FAILED: written " << ret << " expected "
+ << sizeof(hdr) << " ***";
+ }
}
static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
{
struct fuse_out_header hdr;
- struct iovec vec[2];
- int res;
-
hdr.len = len + sizeof(hdr);
hdr.error = 0;
hdr.unique = unique;
+ struct iovec vec[2];
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = data;
vec[1].iov_len = len;
- res = writev(fuse->fd, vec, 2);
- if (res < 0) {
+ ssize_t ret = TEMP_FAILURE_RETRY(writev(fuse->fd, vec, 2));
+ if (ret == -1) {
PLOG(ERROR) << "*** REPLY FAILED ***";
+ } else if (static_cast<size_t>(ret) != sizeof(hdr) + len) {
+ LOG(ERROR) << "*** REPLY FAILED: written " << ret << " expected "
+ << sizeof(hdr) + len << " ***";
}
}
@@ -501,7 +513,7 @@
struct fuse_entry_out out;
struct stat s;
- if (lstat(path, &s) < 0) {
+ if (lstat(path, &s) == -1) {
return -errno;
}
@@ -528,7 +540,7 @@
struct fuse_attr_out out;
struct stat s;
- if (lstat(path, &s) < 0) {
+ if (lstat(path, &s) == -1) {
return -errno;
}
memset(&out, 0, sizeof(out));
@@ -542,10 +554,7 @@
const __u64 child, const char* name) {
struct fuse_out_header hdr;
struct fuse_notify_delete_out data;
- struct iovec vec[3];
size_t namelen = strlen(name);
- int res;
-
hdr.len = sizeof(hdr) + sizeof(data) + namelen + 1;
hdr.error = FUSE_NOTIFY_DELETE;
hdr.unique = 0;
@@ -555,6 +564,7 @@
data.namelen = namelen;
data.padding = 0;
+ struct iovec vec[3];
vec[0].iov_base = &hdr;
vec[0].iov_len = sizeof(hdr);
vec[1].iov_base = &data;
@@ -562,10 +572,15 @@
vec[2].iov_base = (void*) name;
vec[2].iov_len = namelen + 1;
- res = writev(fuse->fd, vec, 3);
+ ssize_t ret = TEMP_FAILURE_RETRY(writev(fuse->fd, vec, 3));
/* Ignore ENOENT, since other views may not have seen the entry */
- if (res < 0 && errno != ENOENT) {
- PLOG(ERROR) << "*** NOTIFY FAILED ***";
+ if (ret == -1) {
+ if (errno != ENOENT) {
+ PLOG(ERROR) << "*** NOTIFY FAILED ***";
+ }
+ } else if (static_cast<size_t>(ret) != sizeof(hdr) + sizeof(data) + namelen + 1) {
+ LOG(ERROR) << "*** NOTIFY FAILED: written " << ret << " expected "
+ << sizeof(hdr) + sizeof(data) + namelen + 1 << " ***";
}
}
@@ -665,7 +680,7 @@
/* XXX: incomplete implementation on purpose.
* chmod/chown should NEVER be implemented.*/
- if ((req->valid & FATTR_SIZE) && truncate64(path, req->size) < 0) {
+ if ((req->valid & FATTR_SIZE) && TEMP_FAILURE_RETRY(truncate64(path, req->size)) == -1) {
return -errno;
}
@@ -727,7 +742,7 @@
return -EACCES;
}
__u32 mode = (req->mode & (~0777)) | 0664;
- if (mknod(child_path, mode, req->rdev) < 0) {
+ if (mknod(child_path, mode, req->rdev) == -1) {
return -errno;
}
return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
@@ -757,7 +772,7 @@
return -EACCES;
}
__u32 mode = (req->mode & (~0777)) | 0775;
- if (mkdir(child_path, mode) < 0) {
+ if (mkdir(child_path, mode) == -1) {
return -errno;
}
@@ -804,7 +819,7 @@
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
return -EACCES;
}
- if (unlink(child_path) < 0) {
+ if (unlink(child_path) == -1) {
return -errno;
}
pthread_mutex_lock(&fuse->global->lock);
@@ -854,7 +869,7 @@
if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
return -EACCES;
}
- if (rmdir(child_path) < 0) {
+ if (rmdir(child_path) == -1) {
return -errno;
}
pthread_mutex_lock(&fuse->global->lock);
@@ -942,7 +957,7 @@
DLOG(INFO) << "[" << handler->token << "] RENAME " << old_child_path << "->" << new_child_path;
res = rename(old_child_path, new_child_path);
- if (res < 0) {
+ if (res == -1) {
res = -errno;
goto io_error;
}
@@ -1004,8 +1019,8 @@
return -ENOMEM;
}
DLOG(INFO) << "[" << handler->token << "] OPEN " << path;
- h->fd = open(path, req->flags);
- if (h->fd < 0) {
+ h->fd = TEMP_FAILURE_RETRY(open(path, req->flags));
+ if (h->fd == -1) {
free(h);
return -errno;
}
@@ -1035,8 +1050,8 @@
if (size > MAX_READ) {
return -EINVAL;
}
- res = pread64(h->fd, read_buffer, size, offset);
- if (res < 0) {
+ res = TEMP_FAILURE_RETRY(pread64(h->fd, read_buffer, size, offset));
+ if (res == -1) {
return -errno;
}
fuse_reply(fuse, unique, read_buffer, res);
@@ -1059,8 +1074,8 @@
DLOG(INFO) << "[" << handler->token << "] WRITE " << std::hex << h << std::dec
<< "(" << h->fd << ") " << req->size << "@" << req->offset;
- res = pwrite64(h->fd, buffer, req->size, req->offset);
- if (res < 0) {
+ res = TEMP_FAILURE_RETRY(pwrite64(h->fd, buffer, req->size, req->offset));
+ if (res == -1) {
return -errno;
}
out.size = res;
@@ -1084,7 +1099,7 @@
if (res < 0) {
return -ENOENT;
}
- if (statfs(fuse->global->root.name, &stat) < 0) {
+ if (TEMP_FAILURE_RETRY(statfs(fuse->global->root.name, &stat)) == -1) {
return -errno;
}
memset(&out, 0, sizeof(out));
@@ -1293,7 +1308,6 @@
return NO_STATUS;
}
-
static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler,
const struct fuse_in_header *hdr, const void *data, size_t data_len)
{
@@ -1427,7 +1441,7 @@
for (;;) {
ssize_t len = TEMP_FAILURE_RETRY(read(fuse->fd,
handler->request_buffer, sizeof(handler->request_buffer)));
- if (len < 0) {
+ if (len == -1) {
if (errno == ENODEV) {
LOG(ERROR) << "[" << handler->token << "] someone stole our marbles!";
exit(2);
@@ -1436,14 +1450,14 @@
continue;
}
- if ((size_t)len < sizeof(struct fuse_in_header)) {
+ if (static_cast<size_t>(len) < sizeof(struct fuse_in_header)) {
LOG(ERROR) << "[" << handler->token << "] request too short: len=" << len;
continue;
}
const struct fuse_in_header* hdr =
reinterpret_cast<const struct fuse_in_header*>(handler->request_buffer);
- if (hdr->len != (size_t)len) {
+ if (hdr->len != static_cast<size_t>(len)) {
LOG(ERROR) << "[" << handler->token << "] malformed header: len=" << len
<< ", hdr->len=" << hdr->len;
continue;
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index 70bbf26..bc502a0 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -111,7 +111,7 @@
char event_buf[512];
int nfd = inotify_init();
- if (nfd < 0) {
+ if (nfd == -1) {
PLOG(ERROR) << "inotify_init failed";
return;
}
@@ -142,17 +142,19 @@
}
int event_pos = 0;
- int res = read(nfd, event_buf, sizeof(event_buf));
- if (res < (int) sizeof(*event)) {
- if (errno == EINTR)
- continue;
+ ssize_t res = TEMP_FAILURE_RETRY(read(nfd, event_buf, sizeof(event_buf)));
+ if (res == -1) {
PLOG(ERROR) << "failed to read inotify event";
return;
+ } else if (static_cast<size_t>(res) < sizeof(*event)) {
+ LOG(ERROR) << "failed to read inotify event: read " << res << " expected "
+ << sizeof(event_buf);
+ return;
}
- while (res >= (int) sizeof(*event)) {
+ while (res >= static_cast<ssize_t>(sizeof(*event))) {
int event_size;
- event = (struct inotify_event *) (event_buf + event_pos);
+ event = reinterpret_cast<struct inotify_event*>(event_buf + event_pos);
DLOG(INFO) << "inotify event: " << std::hex << event->mask << std::dec;
if ((event->mask & IN_IGNORED) == IN_IGNORED) {
@@ -171,7 +173,7 @@
static int fuse_setup(struct fuse* fuse, gid_t gid, mode_t mask) {
char opts[256];
- fuse->fd = open("/dev/fuse", O_RDWR);
+ fuse->fd = TEMP_FAILURE_RETRY(open("/dev/fuse", O_RDWR | O_CLOEXEC));
if (fuse->fd == -1) {
PLOG(ERROR) << "failed to open fuse device";
return -1;
@@ -182,8 +184,8 @@
snprintf(opts, sizeof(opts),
"fd=%i,rootmode=40000,default_permissions,allow_other,user_id=%d,group_id=%d",
fuse->fd, fuse->global->uid, fuse->global->gid);
- if (mount("/dev/fuse", fuse->dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC |
- MS_NOATIME, opts) != 0) {
+ if (mount("/dev/fuse", fuse->dest_path, "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME,
+ opts) == -1) {
PLOG(ERROR) << "failed to mount fuse filesystem";
return -1;
}
@@ -321,7 +323,7 @@
fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid);
if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
- MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) != 0) {
+ MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
return false;
}
@@ -480,7 +482,7 @@
rlim.rlim_cur = 8192;
rlim.rlim_max = 8192;
- if (setrlimit(RLIMIT_NOFILE, &rlim)) {
+ if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
PLOG(ERROR) << "setting RLIMIT_NOFILE failed";
}