Merge changes Ib17f0a55,Ia5bbae6b,I339d42fc into nyc-dev
am: 7bbb4a0c49
* commit '7bbb4a0c49d22f19a19fae594706e73c06ad3b42':
fastboot: fix TCP protocol version check.
fastboot: add UDP protocol.
fastboot: add Socket timeout detection.
diff --git a/adb/Android.mk b/adb/Android.mk
index d629223..b792bd4 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -58,6 +58,7 @@
LIBADB_TEST_SRCS := \
adb_io_test.cpp \
adb_utils_test.cpp \
+ sysdeps_test.cpp \
transport_test.cpp \
LIBADB_CFLAGS := \
@@ -157,7 +158,7 @@
LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STATIC_LIBRARIES := libadbd
-LOCAL_SHARED_LIBRARIES := libbase libcutils
+LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
include $(BUILD_NATIVE_TEST)
# libdiagnose_usb
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 58ccd0a..cb54d04 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -883,8 +883,6 @@
fprintf(stderr, "ADB server didn't ACK\n" );
return -1;
}
-
- setsid();
}
#endif /* !defined(_WIN32) */
return 0;
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 474d1b4..8a16e51 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -134,7 +134,7 @@
return result;
}
-// Given a relative or absolute filepath, create the parent directory hierarchy
+// Given a relative or absolute filepath, create the directory hierarchy
// as needed. Returns true if the hierarchy is/was setup.
bool mkdirs(const std::string& path) {
// TODO: all the callers do unlink && mkdirs && adb_creat ---
@@ -157,12 +157,12 @@
return true;
}
+ const std::string parent(adb_dirname(path));
+
// If dirname returned the same path as what we passed in, don't go recursive.
// This can happen on Windows when walking up the directory hierarchy and not
// finding anything that already exists (unlike POSIX that will eventually
// find . or /).
- const std::string parent(adb_dirname(path));
-
if (parent == path) {
errno = ENOENT;
return false;
@@ -174,14 +174,14 @@
}
// Now that the parent directory hierarchy of 'path' has been ensured,
- // create parent itself.
+ // create path itself.
if (adb_mkdir(path, 0775) == -1) {
- // Can't just check for errno == EEXIST because it might be a file that
- // exists.
const int saved_errno = errno;
- if (directory_exists(parent)) {
+ // If someone else created the directory, that is ok.
+ if (directory_exists(path)) {
return true;
}
+ // There might be a pre-existing file at 'path', or there might have been some other error.
errno = saved_errno;
return false;
}
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index 794dce6..f1ebaa1 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -112,20 +112,26 @@
}
void test_mkdirs(const std::string basepath) {
+ // Test creating a directory hierarchy.
EXPECT_TRUE(mkdirs(basepath));
- EXPECT_NE(-1, adb_creat(basepath.c_str(), 0600));
- EXPECT_FALSE(mkdirs(basepath + "/subdir/"));
+ // Test finding an existing directory hierarchy.
+ EXPECT_TRUE(mkdirs(basepath));
+ const std::string filepath = basepath + "/file";
+ // Verify that the hierarchy was created by trying to create a file in it.
+ EXPECT_NE(-1, adb_creat(filepath.c_str(), 0600));
+ // If a file exists where we want a directory, the operation should fail.
+ EXPECT_FALSE(mkdirs(filepath));
}
TEST(adb_utils, mkdirs) {
TemporaryDir td;
// Absolute paths.
- test_mkdirs(std::string(td.path) + "/dir/subdir/file");
+ test_mkdirs(std::string(td.path) + "/dir/subdir");
// Relative paths.
ASSERT_EQ(0, chdir(td.path)) << strerror(errno);
- test_mkdirs(std::string("relative/subrel/file"));
+ test_mkdirs(std::string("relative/subrel"));
}
#if !defined(_WIN32)
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index b7b30c5..27b7109 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -21,6 +21,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
// We only build the affinity WAR code for Linux.
#if defined(__linux__)
@@ -125,6 +126,15 @@
close_stdin();
setup_daemon_logging();
+#if !defined(_WIN32)
+ // Start a new session for the daemon. Do this here instead of after the fork so
+ // that a ctrl-c between the "starting server" and "done starting server" messages
+ // gets a chance to terminate the server.
+ if (setsid() == -1) {
+ fatal("setsid() failed: %s", strerror(errno));
+ }
+#endif
+
// Any error output written to stderr now goes to adb.log. We could
// keep around a copy of the stderr fd and use that to write any errors
// encountered by the following code, but that is probably overkill.
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 85ab4d1..8e76168 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -482,7 +482,7 @@
// Loops to read from stdin and push the data to the given FD.
// The argument should be a pointer to a StdinReadArgs object. This function
// will take ownership of the object and delete it when finished.
-static void* stdin_read_thread_loop(void* x) {
+static void stdin_read_thread_loop(void* x) {
std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
#if !defined(_WIN32)
@@ -586,8 +586,6 @@
}
}
}
-
- return nullptr;
}
// Returns a shell service string with the indicated arguments and command.
diff --git a/adb/services.cpp b/adb/services.cpp
index 9cbf787..75cbe5d 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -57,13 +57,11 @@
void *cookie;
};
-void *service_bootstrap_func(void *x)
-{
+static void service_bootstrap_func(void* x) {
stinfo* sti = reinterpret_cast<stinfo*>(x);
adb_thread_setname(android::base::StringPrintf("service %d", sti->fd));
sti->func(sti->fd, sti->cookie);
free(sti);
- return 0;
}
#if !ADB_HOST
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index d080e09..f84447f 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -198,7 +198,7 @@
// Opens the file at |pts_name|.
int OpenPtyChildFd(const char* pts_name, ScopedFd* error_sfd);
- static void* ThreadHandler(void* userdata);
+ static void ThreadHandler(void* userdata);
void PassDataStreams();
void WaitForExit();
@@ -465,7 +465,7 @@
return child_fd;
}
-void* Subprocess::ThreadHandler(void* userdata) {
+void Subprocess::ThreadHandler(void* userdata) {
Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata);
adb_thread_setname(android::base::StringPrintf(
@@ -475,8 +475,6 @@
D("deleting Subprocess for PID %d", subprocess->pid());
delete subprocess;
-
- return nullptr;
}
void Subprocess::PassDataStreams() {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 16796cd..3bae09e 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -30,6 +30,7 @@
#include <vector>
// Include this before open/unlink are defined as macros below.
+#include <android-base/errors.h>
#include <android-base/utf8.h>
/*
@@ -114,13 +115,62 @@
LeaveCriticalSection( lock );
}
-typedef void* (*adb_thread_func_t)(void* arg);
+typedef void (*adb_thread_func_t)(void* arg);
+typedef HANDLE adb_thread_t;
-typedef void (*win_thread_func_t)(void* arg);
+struct adb_winthread_args {
+ adb_thread_func_t func;
+ void* arg;
+};
-static __inline__ bool adb_thread_create(adb_thread_func_t func, void* arg) {
- uintptr_t tid = _beginthread((win_thread_func_t)func, 0, arg);
- return (tid != static_cast<uintptr_t>(-1L));
+static unsigned __stdcall adb_winthread_wrapper(void* heap_args) {
+ // Move the arguments from the heap onto the thread's stack.
+ adb_winthread_args thread_args = *static_cast<adb_winthread_args*>(heap_args);
+ delete static_cast<adb_winthread_args*>(heap_args);
+ thread_args.func(thread_args.arg);
+ return 0;
+}
+
+static __inline__ bool adb_thread_create(adb_thread_func_t func, void* arg,
+ adb_thread_t* thread = nullptr) {
+ adb_winthread_args* args = new adb_winthread_args{.func = func, .arg = arg};
+ uintptr_t handle = _beginthreadex(nullptr, 0, adb_winthread_wrapper, args, 0, nullptr);
+ if (handle != static_cast<uintptr_t>(0)) {
+ if (thread) {
+ *thread = reinterpret_cast<HANDLE>(handle);
+ } else {
+ CloseHandle(thread);
+ }
+ return true;
+ }
+ return false;
+}
+
+static __inline__ bool adb_thread_join(adb_thread_t thread) {
+ switch (WaitForSingleObject(thread, INFINITE)) {
+ case WAIT_OBJECT_0:
+ CloseHandle(thread);
+ return true;
+
+ case WAIT_FAILED:
+ fprintf(stderr, "adb_thread_join failed: %s\n",
+ android::base::SystemErrorCodeToString(GetLastError()).c_str());
+ break;
+
+ default:
+ abort();
+ }
+
+ return false;
+}
+
+static __inline__ bool adb_thread_detach(adb_thread_t thread) {
+ CloseHandle(thread);
+ return true;
+}
+
+static __inline__ void __attribute__((noreturn)) adb_thread_exit() {
+ _endthreadex(0);
}
static __inline__ int adb_thread_setname(const std::string& name) {
@@ -656,16 +706,53 @@
#define unix_write adb_write
#define unix_close adb_close
-typedef void* (*adb_thread_func_t)( void* arg );
+// Win32 is limited to DWORDs for thread return values; limit the POSIX systems to this as well to
+// ensure compatibility.
+typedef void (*adb_thread_func_t)(void* arg);
+typedef pthread_t adb_thread_t;
-static __inline__ bool adb_thread_create(adb_thread_func_t start, void* arg) {
+struct adb_pthread_args {
+ adb_thread_func_t func;
+ void* arg;
+};
+
+static void* adb_pthread_wrapper(void* heap_args) {
+ // Move the arguments from the heap onto the thread's stack.
+ adb_pthread_args thread_args = *reinterpret_cast<adb_pthread_args*>(heap_args);
+ delete static_cast<adb_pthread_args*>(heap_args);
+ thread_args.func(thread_args.arg);
+ return nullptr;
+}
+
+static __inline__ bool adb_thread_create(adb_thread_func_t start, void* arg,
+ adb_thread_t* thread = nullptr) {
+ pthread_t temp;
pthread_attr_t attr;
pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setdetachstate(&attr, thread ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED);
+ auto* pthread_args = new adb_pthread_args{.func = start, .arg = arg};
+ errno = pthread_create(&temp, &attr, adb_pthread_wrapper, pthread_args);
+ if (errno == 0) {
+ if (thread) {
+ *thread = temp;
+ }
+ return true;
+ }
+ return false;
+}
- pthread_t thread;
- errno = pthread_create(&thread, &attr, start, arg);
- return (errno == 0);
+static __inline__ bool adb_thread_join(adb_thread_t thread) {
+ errno = pthread_join(thread, nullptr);
+ return errno == 0;
+}
+
+static __inline__ bool adb_thread_detach(adb_thread_t thread) {
+ errno = pthread_detach(thread);
+ return errno == 0;
+}
+
+static __inline__ void __attribute__((noreturn)) adb_thread_exit() {
+ pthread_exit(nullptr);
}
static __inline__ int adb_thread_setname(const std::string& name) {
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
new file mode 100644
index 0000000..360eaa7
--- /dev/null
+++ b/adb/sysdeps_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 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 <gtest/gtest.h>
+#include <unistd.h>
+#include <atomic>
+
+#include "sysdeps.h"
+
+static void increment_atomic_int(void* c) {
+ sleep(1);
+ reinterpret_cast<std::atomic<int>*>(c)->fetch_add(1);
+}
+
+TEST(sysdeps_thread, smoke) {
+ std::atomic<int> counter(0);
+
+ for (int i = 0; i < 100; ++i) {
+ ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter));
+ }
+
+ sleep(2);
+ ASSERT_EQ(100, counter.load());
+}
+
+TEST(sysdeps_thread, join) {
+ std::atomic<int> counter(0);
+ std::vector<adb_thread_t> threads(500);
+ for (size_t i = 0; i < threads.size(); ++i) {
+ ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter, &threads[i]));
+ }
+
+ int current = counter.load();
+ ASSERT_GE(current, 0);
+ // Make sure that adb_thread_create actually creates threads, and doesn't do something silly
+ // like synchronously run the function passed in. The sleep in increment_atomic_int should be
+ // enough to keep this from being flakey.
+ ASSERT_LT(current, 500);
+
+ for (const auto& thread : threads) {
+ ASSERT_TRUE(adb_thread_join(thread));
+ }
+
+ ASSERT_EQ(500, counter.load());
+}
+
+TEST(sysdeps_thread, exit) {
+ adb_thread_t thread;
+ ASSERT_TRUE(adb_thread_create(
+ [](void*) {
+ adb_thread_exit();
+ for (;;) continue;
+ },
+ nullptr, &thread));
+ ASSERT_TRUE(adb_thread_join(thread));
+}
diff --git a/adb/sysdeps_win32_test.cpp b/adb/sysdeps_win32_test.cpp
index 8f610cf..c3a3fd7 100755
--- a/adb/sysdeps_win32_test.cpp
+++ b/adb/sysdeps_win32_test.cpp
@@ -87,8 +87,12 @@
TestAdbStrError(-1, "Unknown error");
// Test very big, positive unknown error.
TestAdbStrError(1000000, "Unknown error");
+
// Test success case.
- TestAdbStrError(0, "No error");
+ // Wine returns "Success" for strerror(0), Windows returns "No error", so accept both.
+ std::string success = adb_strerror(0);
+ EXPECT_TRUE(success == "Success" || success == "No error") << "strerror(0) = " << success;
+
// Test error that regular strerror() should have a string for.
TestAdbStrError(EPERM, "Operation not permitted");
// Test error that regular strerror() doesn't have a string for, but that
diff --git a/adb/transport.cpp b/adb/transport.cpp
index f8c8c61..8ca1e49 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -190,8 +190,7 @@
//
// read_transport thread reads data from a transport (representing a usb/tcp connection),
// and makes the main thread call handle_packet().
-static void *read_transport_thread(void *_t)
-{
+static void read_transport_thread(void* _t) {
atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
@@ -244,13 +243,11 @@
D("%s: read_transport thread is exiting", t->serial);
kick_transport(t);
transport_unref(t);
- return 0;
}
// write_transport thread gets packets sent by the main thread (through send_packet()),
// and writes to a transport (representing a usb/tcp connection).
-static void *write_transport_thread(void *_t)
-{
+static void write_transport_thread(void* _t) {
atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
int active = 0;
@@ -295,7 +292,6 @@
D("%s: write_transport thread is exiting, fd %d", t->serial, t->fd);
kick_transport(t);
transport_unref(t);
- return 0;
}
static void kick_transport_locked(atransport* t) {
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index d2a375a..e6e699b 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -121,8 +121,7 @@
}
#if ADB_HOST
-static void *client_socket_thread(void *x)
-{
+static void client_socket_thread(void* x) {
adb_thread_setname("client_socket_thread");
D("transport: client_socket_thread() starting");
while (true) {
@@ -135,13 +134,11 @@
}
sleep(1);
}
- return 0;
}
#else // ADB_HOST
-static void *server_socket_thread(void * arg)
-{
+static void server_socket_thread(void* arg) {
int serverfd, fd;
sockaddr_storage ss;
sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss);
@@ -174,7 +171,6 @@
}
}
D("transport: server_socket_thread() exiting");
- return 0;
}
/* This is relevant only for ADB daemon running inside the emulator. */
@@ -220,14 +216,13 @@
* the transport registration is completed. That's why we need to send the
* 'start' request after the transport is registered.
*/
-static void *qemu_socket_thread(void * arg)
-{
-/* 'accept' request to the adb QEMUD service. */
-static const char _accept_req[] = "accept";
-/* 'start' request to the adb QEMUD service. */
-static const char _start_req[] = "start";
-/* 'ok' reply from the adb QEMUD service. */
-static const char _ok_resp[] = "ok";
+static void qemu_socket_thread(void* arg) {
+ /* 'accept' request to the adb QEMUD service. */
+ static const char _accept_req[] = "accept";
+ /* 'start' request to the adb QEMUD service. */
+ static const char _start_req[] = "start";
+ /* 'ok' reply from the adb QEMUD service. */
+ static const char _ok_resp[] = "ok";
const int port = (int) (uintptr_t) arg;
int res, fd;
@@ -247,7 +242,7 @@
* implement adb QEMUD service. Fall back to the old TCP way. */
D("adb service is not available. Falling back to TCP socket.");
adb_thread_create(server_socket_thread, arg);
- return 0;
+ return;
}
for(;;) {
@@ -275,21 +270,21 @@
fd = qemu_pipe_open(con_name);
if (fd < 0) {
D("adb service become unavailable.");
- return 0;
+ return;
}
} else {
D("Unable to send the '%s' request to ADB service.", _accept_req);
- return 0;
+ return;
}
}
D("transport: qemu_socket_thread() exiting");
- return 0;
+ return;
}
#endif // !ADB_HOST
void local_init(int port)
{
- void* (*func)(void *);
+ adb_thread_func_t func;
const char* debug_name = "";
#if ADB_HOST
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index ed5d2d67..500898a 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -571,7 +571,7 @@
register_usb_transport(done_usb, serial.c_str(), dev_path, done_usb->writeable);
}
-static void* device_poll_thread(void* unused) {
+static void device_poll_thread(void*) {
adb_thread_setname("device poll");
D("Created device thread");
while (true) {
@@ -580,7 +580,6 @@
kick_disconnected_devices();
sleep(1);
}
- return nullptr;
}
void usb_init() {
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index a4f1a70..c863ed2 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -232,10 +232,7 @@
},
};
-
-
-static void *usb_adb_open_thread(void *x)
-{
+static void usb_adb_open_thread(void* x) {
struct usb_handle *usb = (struct usb_handle *)x;
int fd;
@@ -270,7 +267,7 @@
}
// never gets here
- return 0;
+ abort();
}
static int usb_adb_write(usb_handle *h, const void *data, int len)
@@ -434,8 +431,7 @@
return;
}
-static void *usb_ffs_open_thread(void *x)
-{
+static void usb_ffs_open_thread(void* x) {
struct usb_handle *usb = (struct usb_handle *)x;
adb_thread_setname("usb ffs open");
@@ -462,7 +458,7 @@
}
// never gets here
- return 0;
+ abort();
}
static int usb_ffs_write(usb_handle* h, const void* data, int len) {
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 148be1d..54d4c6c 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -400,9 +400,7 @@
return NULL;
}
-
-void* RunLoopThread(void* unused)
-{
+static void RunLoopThread(void* unused) {
adb_thread_setname("RunLoop");
InitUSB();
@@ -420,7 +418,6 @@
IONotificationPortDestroy(notificationPort);
LOG(DEBUG) << "RunLoopThread done";
- return NULL;
}
static void usb_cleanup() {
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index e79008f..8ecca37 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -97,7 +97,7 @@
/// Entry point for thread that polls (every second) for new usb interfaces.
/// This routine calls find_devices in infinite loop.
-void* device_poll_thread(void* unused);
+static void device_poll_thread(void*);
/// Initializes this module
void usb_init();
@@ -172,7 +172,7 @@
return 1;
}
-void* device_poll_thread(void* unused) {
+void device_poll_thread(void*) {
adb_thread_setname("Device Poll");
D("Created device thread");
@@ -180,8 +180,6 @@
find_devices();
adb_sleep_ms(1000);
}
-
- return NULL;
}
static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam,
@@ -203,7 +201,7 @@
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
-static void* _power_notification_thread(void* unused) {
+static void _power_notification_thread(void*) {
// This uses a thread with its own window message pump to get power
// notifications. If adb runs from a non-interactive service account, this
// might not work (not sure). If that happens to not work, we could use
@@ -255,8 +253,6 @@
// shutting down. Not a big deal since the whole process will be going away
// soon anyway.
D("Power notification thread exiting");
-
- return NULL;
}
void usb_init() {
diff --git a/base/file.cpp b/base/file.cpp
index bcdfc5e..da1adba 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -29,10 +29,6 @@
#include "cutils/log.h"
#include "utils/Compat.h"
-#if !defined(_WIN32)
-#define O_BINARY 0
-#endif
-
namespace android {
namespace base {
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 486befc..5342d98 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -20,6 +20,10 @@
#include <sys/stat.h>
#include <string>
+#if !defined(_WIN32) && !defined(O_BINARY)
+#define O_BINARY 0
+#endif
+
namespace android {
namespace base {
diff --git a/base/logging.cpp b/base/logging.cpp
index a385902..1741871 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -68,7 +68,13 @@
#include <windows.h>
#endif
-static pid_t GetThreadId() {
+#if defined(_WIN32)
+typedef uint32_t thread_id;
+#else
+typedef pid_t thread_id;
+#endif
+
+static thread_id GetThreadId() {
#if defined(__BIONIC__)
return gettid();
#elif defined(__APPLE__)
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 337ba7c..635af6c 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -16,7 +16,6 @@
#include "android-base/logging.h"
#include "android-base/test_utils.h"
-#include "utils/Compat.h" // For OS_PATH_SEPARATOR.
#include <fcntl.h>
#include <stdio.h>
@@ -27,6 +26,9 @@
#if defined(_WIN32)
#include <windows.h>
#include <direct.h>
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
#endif
#include <string>
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 22a67bb..8282b40 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -50,7 +50,7 @@
SetStorePath(BOOTSTAT_DATA_DIR);
}
-void BootEventRecordStore::AddBootEvent(const std::string& name) {
+void BootEventRecordStore::AddBootEvent(const std::string& event) {
std::string uptime_str;
if (!android::base::ReadFileToString("/proc/uptime", &uptime_str)) {
LOG(ERROR) << "Failed to read /proc/uptime";
@@ -58,15 +58,15 @@
// Cast intentionally rounds down.
int32_t uptime = static_cast<int32_t>(strtod(uptime_str.c_str(), NULL));
- AddBootEventWithValue(name, uptime);
+ AddBootEventWithValue(event, uptime);
}
// The implementation of AddBootEventValue makes use of the mtime file
// attribute to store the value associated with a boot event in order to
// optimize on-disk size requirements and small-file thrashing.
void BootEventRecordStore::AddBootEventWithValue(
- const std::string& name, int32_t value) {
- std::string record_path = GetBootEventPath(name);
+ const std::string& event, int32_t value) {
+ std::string record_path = GetBootEventPath(event);
if (creat(record_path.c_str(), S_IRUSR | S_IWUSR) == -1) {
PLOG(ERROR) << "Failed to create " << record_path;
}
@@ -86,6 +86,22 @@
}
}
+bool BootEventRecordStore::GetBootEvent(
+ const std::string& event, BootEventRecord* record) const {
+ CHECK_NE(static_cast<BootEventRecord*>(nullptr), record);
+ CHECK(!event.empty());
+
+ const std::string record_path = GetBootEventPath(event);
+ int32_t uptime;
+ if (!ParseRecordEventTime(record_path, &uptime)) {
+ LOG(ERROR) << "Failed to parse boot time record: " << record_path;
+ return false;
+ }
+
+ *record = std::make_pair(event, uptime);
+ return true;
+}
+
std::vector<BootEventRecordStore::BootEventRecord> BootEventRecordStore::
GetAllBootEvents() const {
std::vector<BootEventRecord> events;
@@ -104,14 +120,13 @@
}
const std::string event = entry->d_name;
- const std::string record_path = GetBootEventPath(event);
- int32_t uptime;
- if (!ParseRecordEventTime(record_path, &uptime)) {
- LOG(ERROR) << "Failed to parse boot time record: " << record_path;
+ BootEventRecord record;
+ if (!GetBootEvent(event, &record)) {
+ LOG(ERROR) << "Failed to parse boot time event: " << event;
continue;
}
- events.push_back(std::make_pair(event, uptime));
+ events.push_back(record);
}
return events;
diff --git a/bootstat/boot_event_record_store.h b/bootstat/boot_event_record_store.h
index d1b7835..4d5deee 100644
--- a/bootstat/boot_event_record_store.h
+++ b/bootstat/boot_event_record_store.h
@@ -34,12 +34,16 @@
BootEventRecordStore();
- // Persists the boot event named |name| in the record store.
- void AddBootEvent(const std::string& name);
+ // Persists the boot |event| in the record store.
+ void AddBootEvent(const std::string& event);
- // Persists the boot event named |name| with the associated |value| in the
- // record store.
- void AddBootEventWithValue(const std::string& name, int32_t value);
+ // Persists the boot |event| with the associated |value| in the record store.
+ void AddBootEventWithValue(const std::string& event, int32_t value);
+
+ // Queries the named boot |event|. |record| must be non-null. |record|
+ // contains the boot event data on success. Returns true iff the query is
+ // successful.
+ bool GetBootEvent(const std::string& event, BootEventRecord* record) const;
// Returns a list of all of the boot events persisted in the record store.
std::vector<BootEventRecord> GetAllBootEvents() const;
@@ -50,6 +54,7 @@
FRIEND_TEST(BootEventRecordStoreTest, AddSingleBootEvent);
FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents);
FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue);
+ FRIEND_TEST(BootEventRecordStoreTest, GetBootEvent);
// Sets the filesystem path of the record store.
void SetStorePath(const std::string& path);
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 3e6d706..0d7bbb0 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -165,4 +165,27 @@
ASSERT_EQ(1U, events.size());
EXPECT_EQ("permian", events[0].first);
EXPECT_EQ(42, events[0].second);
+}
+
+TEST_F(BootEventRecordStoreTest, GetBootEvent) {
+ BootEventRecordStore store;
+ store.SetStorePath(GetStorePathForTesting());
+
+ // Event does not exist.
+ BootEventRecordStore::BootEventRecord record;
+ bool result = store.GetBootEvent("nonexistent", &record);
+ EXPECT_EQ(false, result);
+
+ // Empty path.
+ EXPECT_DEATH(store.GetBootEvent(std::string(), &record), std::string());
+
+ // Success case.
+ store.AddBootEventWithValue("carboniferous", 314);
+ result = store.GetBootEvent("carboniferous", &record);
+ EXPECT_EQ(true, result);
+ EXPECT_EQ("carboniferous", record.first);
+ EXPECT_EQ(314, record.second);
+
+ // Null |record|.
+ EXPECT_DEATH(store.GetBootEvent("carboniferous", nullptr), std::string());
}
\ No newline at end of file
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 1d16f69..0c49f82 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <cstddef>
#include <cstdio>
+#include <ctime>
#include <map>
#include <memory>
#include <string>
@@ -155,6 +156,32 @@
boot_event_store.AddBootEventWithValue("boot_reason", boot_reason);
}
+// Records two metrics related to the user resetting a device: the time at
+// which the device is reset, and the time since the user last reset the
+// device. The former is only set once per-factory reset.
+void RecordFactoryReset() {
+ BootEventRecordStore boot_event_store;
+ BootEventRecordStore::BootEventRecord record;
+
+ time_t current_time_utc = time(nullptr);
+
+ // The factory_reset boot event does not exist after the device is reset, so
+ // use this signal to mark the time of the factory reset.
+ if (!boot_event_store.GetBootEvent("factory_reset", &record)) {
+ boot_event_store.AddBootEventWithValue("factory_reset", current_time_utc);
+ boot_event_store.AddBootEventWithValue("time_since_factory_reset", 0);
+ return;
+ }
+
+ // Calculate and record the difference in time between now and the
+ // factory_reset time.
+ time_t factory_reset_utc = record.second;
+ time_t time_since_factory_reset = difftime(current_time_utc,
+ factory_reset_utc);
+ boot_event_store.AddBootEventWithValue("time_since_factory_reset",
+ time_since_factory_reset);
+}
+
} // namespace
int main(int argc, char **argv) {
@@ -165,12 +192,14 @@
int option_index = 0;
static const char boot_reason_str[] = "record_boot_reason";
+ static const char factory_reset_str[] = "record_factory_reset";
static const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "log", no_argument, NULL, 'l' },
{ "print", no_argument, NULL, 'p' },
{ "record", required_argument, NULL, 'r' },
{ boot_reason_str, no_argument, NULL, 0 },
+ { factory_reset_str, no_argument, NULL, 0 },
{ NULL, 0, NULL, 0 }
};
@@ -182,6 +211,8 @@
const std::string option_name = long_options[option_index].name;
if (option_name == boot_reason_str) {
RecordBootReason();
+ } else if (option_name == factory_reset_str) {
+ RecordFactoryReset();
} else {
LOG(ERROR) << "Invalid option: " << option_name;
}
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
index c73045d..853bf0b 100644
--- a/fs_mgr/fs_mgr_format.c
+++ b/fs_mgr/fs_mgr_format.c
@@ -33,7 +33,7 @@
static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
{
- unsigned int nr_sec;
+ uint64_t dev_sz;
int fd, rc = 0;
if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
@@ -41,7 +41,7 @@
return -1;
}
- if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
+ if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) {
ERROR("Cannot get block device size. %s\n", strerror(errno));
close(fd);
return -1;
@@ -49,7 +49,7 @@
/* Format the partition using the calculated length */
reset_ext4fs_info();
- info.len = ((off64_t)nr_sec * 512);
+ info.len = (off64_t)dev_sz;
/* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 27c985c..5d207e3 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -10,13 +10,23 @@
include $(CLEAR_VARS)
+ifeq ($(strip $(BOARD_CHARGER_NO_UI)),true)
+LOCAL_CHARGER_NO_UI := true
+endif
+ifdef BRILLO
+LOCAL_CHARGER_NO_UI := true
+endif
+
LOCAL_SRC_FILES := \
healthd.cpp \
healthd_mode_android.cpp \
- healthd_mode_charger.cpp \
BatteryMonitor.cpp \
BatteryPropertiesRegistrar.cpp
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_SRC_FILES += healthd_mode_charger.cpp
+endif
+
LOCAL_MODULE := healthd
LOCAL_MODULE_TAGS := optional
LOCAL_FORCE_STATIC_EXECUTABLE := true
@@ -33,9 +43,19 @@
LOCAL_CFLAGS += -DCHARGER_ENABLE_SUSPEND
endif
+ifeq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_CFLAGS += -DCHARGER_NO_UI
+endif
+
LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_STATIC_LIBRARIES := libbatteryservice libbinder libminui libpng libz libutils libcutils liblog libm libc
+LOCAL_STATIC_LIBRARIES := libbatteryservice libbinder
+
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
+LOCAL_STATIC_LIBRARIES += libminui libpng libz
+endif
+
+LOCAL_STATIC_LIBRARIES += libutils libcutils liblog libm libc
ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true)
LOCAL_STATIC_LIBRARIES += libsuspend
@@ -50,6 +70,7 @@
include $(BUILD_EXECUTABLE)
+ifneq ($(strip $(LOCAL_CHARGER_NO_UI)),true)
define _add-charger-image
include $$(CLEAR_VARS)
LOCAL_MODULE := system_core_charger_$(notdir $(1))
@@ -75,3 +96,4 @@
_add-charger-image :=
_img_modules :=
+endif # LOCAL_CHARGER_NO_UI
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 6aa360b..11ddd3e 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -56,6 +56,28 @@
return -1;
}
+static void initBatteryProperties(BatteryProperties* props) {
+ props->chargerAcOnline = false;
+ props->chargerUsbOnline = false;
+ props->chargerWirelessOnline = false;
+ props->maxChargingCurrent = 0;
+ props->batteryStatus = BATTERY_STATUS_UNKNOWN;
+ props->batteryHealth = BATTERY_HEALTH_UNKNOWN;
+ props->batteryPresent = false;
+ props->batteryLevel = 0;
+ props->batteryVoltage = 0;
+ props->batteryTemperature = 0;
+ props->batteryCurrent = 0;
+ props->batteryCycleCount = 0;
+ props->batteryFullCharge = 0;
+ props->batteryTechnology.clear();
+}
+
+BatteryMonitor::BatteryMonitor() : mHealthdConfig(nullptr), mBatteryDevicePresent(false),
+ mAlwaysPluggedDevice(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0) {
+ initBatteryProperties(&props);
+}
+
int BatteryMonitor::getBatteryStatus(const char* status) {
int ret;
struct sysfsStringEnumMap batteryStatusMap[] = {
@@ -184,12 +206,7 @@
bool BatteryMonitor::update(void) {
bool logthis;
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- props.chargerWirelessOnline = false;
- props.batteryStatus = BATTERY_STATUS_UNKNOWN;
- props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
- props.maxChargingCurrent = 0;
+ initBatteryProperties(&props);
if (!mHealthdConfig->batteryPresentPath.isEmpty())
props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
diff --git a/healthd/BatteryMonitor.h b/healthd/BatteryMonitor.h
index a61171f..6001073 100644
--- a/healthd/BatteryMonitor.h
+++ b/healthd/BatteryMonitor.h
@@ -37,6 +37,7 @@
ANDROID_POWER_SUPPLY_TYPE_BATTERY
};
+ BatteryMonitor();
void init(struct healthd_config *hc);
bool update(void);
status_t getProperty(int id, struct BatteryProperty *val);
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 85888c3..9b47334 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -109,10 +109,17 @@
};
static struct healthd_mode_ops charger_ops = {
+#ifdef CHARGER_NO_UI
+ .init = healthd_mode_nop_init,
+ .preparetowait = healthd_mode_nop_preparetowait,
+ .heartbeat = healthd_mode_nop_heartbeat,
+ .battery_update = healthd_mode_nop_battery_update,
+#else
.init = healthd_mode_charger_init,
.preparetowait = healthd_mode_charger_preparetowait,
.heartbeat = healthd_mode_charger_heartbeat,
.battery_update = healthd_mode_charger_battery_update,
+#endif
};
static struct healthd_mode_ops recovery_ops = {
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 9a67c7a..50ac6d0 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -62,9 +62,9 @@
explicit String16(const char* o, size_t len);
~String16();
-
+
inline const char16_t* string() const;
-
+
size_t size() const;
void setTo(const String16& other);
status_t setTo(const char16_t* other);
@@ -72,12 +72,12 @@
status_t setTo(const String16& other,
size_t len,
size_t begin=0);
-
+
status_t append(const String16& other);
status_t append(const char16_t* other, size_t len);
-
+
inline String16& operator=(const String16& other);
-
+
inline String16& operator+=(const String16& other);
inline String16 operator+(const String16& other) const;
@@ -90,7 +90,7 @@
bool startsWith(const String16& prefix) const;
bool startsWith(const char16_t* prefix) const;
-
+
status_t makeLower();
status_t replaceAll(char16_t replaceThis,
@@ -106,16 +106,16 @@
inline bool operator!=(const String16& other) const;
inline bool operator>=(const String16& other) const;
inline bool operator>(const String16& other) const;
-
+
inline bool operator<(const char16_t* other) const;
inline bool operator<=(const char16_t* other) const;
inline bool operator==(const char16_t* other) const;
inline bool operator!=(const char16_t* other) const;
inline bool operator>=(const char16_t* other) const;
inline bool operator>(const char16_t* other) const;
-
+
inline operator const char16_t*() const;
-
+
private:
const char16_t* mString;
};
diff --git a/include/utils/ThreadDefs.h b/include/utils/ThreadDefs.h
index 9711c13..ae091e4 100644
--- a/include/utils/ThreadDefs.h
+++ b/include/utils/ThreadDefs.h
@@ -29,7 +29,11 @@
extern "C" {
#endif
+#ifdef _WIN32
+typedef uint32_t android_thread_id_t;
+#else
typedef void* android_thread_id_t;
+#endif
typedef int (*android_thread_func_t)(void*);
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index ee56a5e..397dfda 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -71,14 +71,22 @@
build_type := host
libbacktrace_multilib := both
include $(LOCAL_PATH)/Android.build.mk
+
+libbacktrace_shared_libraries :=
+
libbacktrace_static_libraries := \
libbase \
liblog \
libunwind \
+ liblzma \
+module := libbacktrace
+build_type := target
build_target := STATIC_LIBRARY
include $(LOCAL_PATH)/Android.build.mk
-libbacktrace_static_libraries :=
+build_type := host
+libbacktrace_multilib := both
+include $(LOCAL_PATH)/Android.build.mk
#-------------------------------------------------------------------------
# The libbacktrace_offline shared library.
@@ -106,7 +114,6 @@
libLLVMSupport \
module := libbacktrace_offline
-module_tag := optional
build_type := target
build_target := SHARED_LIBRARY
include $(LOCAL_PATH)/Android.build.mk
@@ -114,6 +121,26 @@
libbacktrace_multilib := both
include $(LOCAL_PATH)/Android.build.mk
+libbacktrace_offline_shared_libraries :=
+libbacktrace_offline_static_libraries := \
+ libbacktrace \
+ libbase \
+ libcutils \
+ liblog \
+ libunwind \
+ liblzma \
+ libLLVMObject \
+ libLLVMBitReader \
+ libLLVMMC \
+ libLLVMMCParser \
+ libLLVMCore \
+ libLLVMSupport \
+
+module := libbacktrace_offline
+build_type := target
+build_target := STATIC_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+
#-------------------------------------------------------------------------
# The libbacktrace_test library needed by backtrace_test.
#-------------------------------------------------------------------------
diff --git a/libcutils/tests/PropertiesTest.cpp b/libcutils/tests/PropertiesTest.cpp
index 659821c..22ca706 100644
--- a/libcutils/tests/PropertiesTest.cpp
+++ b/libcutils/tests/PropertiesTest.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "Properties_test"
-#include <utils/Log.h>
+#include <cutils/log.h>
#include <gtest/gtest.h>
#include <cutils/properties.h>
diff --git a/libdiskconfig/Android.mk b/libdiskconfig/Android.mk
index 624e385..a49ce58 100644
--- a/libdiskconfig/Android.mk
+++ b/libdiskconfig/Android.mk
@@ -13,6 +13,8 @@
LOCAL_MODULE_TAGS := optional
LOCAL_SYSTEM_SHARED_LIBRARIES := libcutils liblog libc
LOCAL_CFLAGS := -Werror
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
ifeq ($(HOST_OS),linux)
@@ -21,5 +23,7 @@
LOCAL_MODULE := libdiskconfig_host
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -O2 -g -W -Wall -Werror -D_LARGEFILE64_SOURCE
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_HOST_STATIC_LIBRARY)
endif # HOST_OS == linux
diff --git a/include/diskconfig/diskconfig.h b/libdiskconfig/include/diskconfig/diskconfig.h
similarity index 100%
rename from include/diskconfig/diskconfig.h
rename to libdiskconfig/include/diskconfig/diskconfig.h
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index cb80ee6..4942c08 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -69,7 +69,7 @@
int fakeFd;
/* a printable name for this fake device */
- char *debugName;
+ char debugName[sizeof("/dev/log/security")];
/* nonzero if this is a binary log */
int isBinary;
@@ -123,8 +123,8 @@
* File descriptor management.
*/
#define FAKE_FD_BASE 10000
-#define MAX_OPEN_LOGS 16
-static LogState *openLogTable[MAX_OPEN_LOGS];
+#define MAX_OPEN_LOGS 8
+static LogState openLogTable[MAX_OPEN_LOGS];
/*
* Allocate an fd and associate a new LogState with it.
@@ -134,11 +134,10 @@
{
size_t i;
- for (i = 0; i < sizeof(openLogTable); i++) {
- if (openLogTable[i] == NULL) {
- openLogTable[i] = calloc(1, sizeof(LogState));
- openLogTable[i]->fakeFd = FAKE_FD_BASE + i;
- return openLogTable[i];
+ for (i = 0; i < (sizeof(openLogTable) / sizeof(openLogTable[0])); i++) {
+ if (openLogTable[i].fakeFd == 0) {
+ openLogTable[i].fakeFd = FAKE_FD_BASE + i;
+ return &openLogTable[i];
}
}
return NULL;
@@ -150,7 +149,7 @@
static LogState *fdToLogState(int fd)
{
if (fd >= FAKE_FD_BASE && fd < FAKE_FD_BASE + MAX_OPEN_LOGS) {
- return openLogTable[fd - FAKE_FD_BASE];
+ return &openLogTable[fd - FAKE_FD_BASE];
}
return NULL;
}
@@ -166,9 +165,7 @@
ls = fdToLogState(fd);
if (ls != NULL) {
- openLogTable[fd - FAKE_FD_BASE] = NULL;
- free(ls->debugName);
- free(ls);
+ memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0]));
}
unlock();
@@ -191,10 +188,12 @@
{
static const int kDevLogLen = sizeof("/dev/log/") - 1;
- logState->debugName = strdup(pathName);
+ strncpy(logState->debugName, pathName, sizeof(logState->debugName));
+ logState->debugName[sizeof(logState->debugName) - 1] = '\0';
/* identify binary logs */
- if (strcmp(pathName + kDevLogLen, "events") == 0) {
+ if (!strcmp(pathName + kDevLogLen, "events") ||
+ !strcmp(pathName + kDevLogLen, "security")) {
logState->isBinary = 1;
}
@@ -218,8 +217,7 @@
i = 0;
while (*tags != '\0' && !isspace(*tags) && *tags != ':' &&
- i < kMaxTagLen)
- {
+ i < kMaxTagLen) {
tagName[i++] = *tags++;
}
if (i == kMaxTagLen) {
@@ -320,9 +318,9 @@
};
int idx;
- idx = (int) priority - (int) ANDROID_LOG_VERBOSE;
+ idx = (int)priority - (int)ANDROID_LOG_VERBOSE;
if (idx < 0 ||
- idx >= (int) (sizeof(priorityStrings) / sizeof(priorityStrings[0])))
+ idx >= (int)(sizeof(priorityStrings) / sizeof(priorityStrings[0])))
return "?unknown?";
return priorityStrings[idx];
}
@@ -367,7 +365,11 @@
char prefixBuf[128], suffixBuf[128];
char priChar;
time_t when;
+#if !defined(_WIN32)
pid_t pid, tid;
+#else
+ uint32_t pid, tid;
+#endif
TRACE("LOG %d: %s %s", logPrio, tag, msg);
@@ -450,13 +452,15 @@
while (p < end) {
if (*p++ == '\n') numLines++;
}
- if (p > msg && *(p-1) != '\n') numLines++;
+ if (p > msg && *(p-1) != '\n') {
+ numLines++;
+ }
/*
* Create an array of iovecs large enough to write all of
* the lines with a prefix and a suffix.
*/
- const size_t INLINE_VECS = 6;
+ const size_t INLINE_VECS = 64;
const size_t MAX_LINES = ((size_t)~0)/(3*sizeof(struct iovec*));
struct iovec stackVec[INLINE_VECS];
struct iovec* vec = stackVec;
@@ -490,7 +494,9 @@
v++;
}
const char* start = p;
- while (p < end && *p != '\n') p++;
+ while (p < end && *p != '\n') {
+ p++;
+ }
if ((p-start) > 0) {
v->iov_base = (void*)start;
v->iov_len = p-start;
@@ -685,6 +691,17 @@
return redirectOpen(pathName, flags);
}
+/*
+ * The logger API has no means or need to 'stop' or 'close' using the logs,
+ * and as such, there is no way for that 'stop' or 'close' to translate into
+ * a close operation to the fake log handler. fakeLogClose is provided for
+ * completeness only.
+ *
+ * We have no intention of adding a log close operation as it would complicate
+ * every user of the logging API with no gain since the only valid place to
+ * call is in the exit handler. Logging can continue in the exit handler to
+ * help debug HOST tools ...
+ */
int fakeLogClose(int fd)
{
/* Assume that open() was called first. */
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 4946073..b173d1a 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -125,7 +125,7 @@
#if FAKE_LOG_DEVICE
for (i = 0; i < LOG_ID_MAX; i++) {
- char buf[sizeof("/dev/log_system")];
+ char buf[sizeof("/dev/log_security")];
snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));
log_fds[i] = fakeLogOpen(buf, O_WRONLY);
}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 8517c9f..f8d4c4c 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -173,7 +173,7 @@
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
-TEST(liblog, __android_log_bswrite) {
+static void bswrite_test(const char *message) {
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -181,10 +181,30 @@
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
- static const char buffer[] = "Hello World";
log_time ts(android_log_clockid());
- ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ ASSERT_LT(0, __android_log_bswrite(0, message));
+ size_t num_lines = 1, size = 0, length = 0, total = 0;
+ const char *cp = message;
+ while (*cp) {
+ if (*cp == '\n') {
+ if (cp[1]) {
+ ++num_lines;
+ }
+ } else {
+ ++size;
+ }
+ ++cp;
+ ++total;
+ ++length;
+ if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) {
+ break;
+ }
+ }
+ while (*cp) {
+ ++cp;
+ ++total;
+ }
usleep(1000000);
int count = 0;
@@ -199,7 +219,7 @@
if ((log_msg.entry.sec < (ts.tv_sec - 1))
|| ((ts.tv_sec + 1) < log_msg.entry.sec)
- || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
+ || ((size_t)log_msg.entry.len != (4 + 1 + 4 + length))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
@@ -210,21 +230,22 @@
continue;
}
- int len = get4LE(eventData + 4 + 1);
- if (len == (sizeof(buffer) - 1)) {
+ size_t len = get4LE(eventData + 4 + 1);
+ if (len == total) {
++count;
AndroidLogFormat *logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
char msgBuf[1024];
- EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
- &entry,
- NULL,
- msgBuf,
- sizeof(msgBuf)));
- fflush(stderr);
- EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
+ int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
+ &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
+ EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
+ if (processBinaryLogBuffer == 0) {
+ fflush(stderr);
+ EXPECT_EQ((int)((20 * num_lines) + size),
+ android_log_printLogLine(logformat, fileno(stderr), &entry));
+ }
android_log_format_free(logformat);
}
}
@@ -234,18 +255,55 @@
android_logger_list_close(logger_list);
}
-TEST(liblog, __android_log_bswrite__empty_string) {
+TEST(liblog, __android_log_bswrite_and_print) {
+ bswrite_test("Hello World");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__empty_string) {
+ bswrite_test("");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__newline_prefix) {
+ bswrite_test("\nHello World\n");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__newline_space_prefix) {
+ bswrite_test("\n Hello World \n");
+}
+
+TEST(liblog, __android_log_bswrite_and_print__multiple_newline) {
+ bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten");
+}
+
+static void buf_write_test(const char *message) {
struct logger_list *logger_list;
pid_t pid = getpid();
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+ LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
- static const char buffer[] = "";
+ static const char tag[] = "TEST__android_log_buf_write";
log_time ts(android_log_clockid());
- ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
+ tag, message));
+ size_t num_lines = 1, size = 0, length = 0;
+ const char *cp = message;
+ while (*cp) {
+ if (*cp == '\n') {
+ if (cp[1]) {
+ ++num_lines;
+ }
+ } else {
+ ++size;
+ }
+ ++length;
+ if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) {
+ break;
+ }
+ ++cp;
+ }
usleep(1000000);
int count = 0;
@@ -260,34 +318,25 @@
if ((log_msg.entry.sec < (ts.tv_sec - 1))
|| ((ts.tv_sec + 1) < log_msg.entry.sec)
- || (log_msg.entry.len != (4 + 1 + 4))
- || (log_msg.id() != LOG_ID_EVENTS)) {
+ || ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2))
+ || (log_msg.id() != LOG_ID_MAIN)) {
continue;
}
- char *eventData = log_msg.msg();
+ ++count;
- if (eventData[4] != EVENT_TYPE_STRING) {
- continue;
- }
-
- int len = get4LE(eventData + 4 + 1);
- if (len == 0) {
- ++count;
-
- AndroidLogFormat *logformat = android_log_format_new();
- EXPECT_TRUE(NULL != logformat);
- AndroidLogEntry entry;
- char msgBuf[1024];
- EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
- &entry,
- NULL,
- msgBuf,
- sizeof(msgBuf)));
+ AndroidLogFormat *logformat = android_log_format_new();
+ EXPECT_TRUE(NULL != logformat);
+ AndroidLogEntry entry;
+ int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
+ &entry);
+ EXPECT_EQ(0, processLogBuffer);
+ if (processLogBuffer == 0) {
fflush(stderr);
- EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
- android_log_format_free(logformat);
+ EXPECT_EQ((int)(((11 + sizeof(tag)) * num_lines) + size),
+ android_log_printLogLine(logformat, fileno(stderr), &entry));
}
+ android_log_format_free(logformat);
}
EXPECT_EQ(1, count);
@@ -295,6 +344,18 @@
android_logger_list_close(logger_list);
}
+TEST(liblog, __android_log_buf_write_and_print__empty) {
+ buf_write_test("");
+}
+
+TEST(liblog, __android_log_buf_write_and_print__newline_prefix) {
+ buf_write_test("\nHello World\n");
+}
+
+TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) {
+ buf_write_test("\n Hello World \n");
+}
+
TEST(liblog, __security) {
static const char persist_key[] = "persist.logd.security";
static const char readonly_key[] = "ro.device_owner";
@@ -609,7 +670,7 @@
EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
}
-static const char max_payload_tag[] = "TEST_max_payload_XXXX";
+static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
sizeof(max_payload_tag) - 1)
static const char max_payload_buf[] = "LEONATO\n\
@@ -1576,6 +1637,14 @@
android_logger_list_close(logger_list);
}
+TEST(liblog, __android_log_bswrite_and_print___max) {
+ bswrite_test(max_payload_buf);
+}
+
+TEST(liblog, __android_log_buf_write_and_print__max) {
+ buf_write_test(max_payload_buf);
+}
+
TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
const int TAG = 123456785;
const char SUBTAG[] = "test-subtag";
diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk
index 7b170f5..ffc7244 100644
--- a/libmemtrack/Android.mk
+++ b/libmemtrack/Android.mk
@@ -5,6 +5,8 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := memtrack.c
LOCAL_MODULE := libmemtrack
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += hardware/libhardware/include
LOCAL_SHARED_LIBRARIES := libhardware liblog
LOCAL_CFLAGS := -Wall -Werror
diff --git a/include/memtrack/memtrack.h b/libmemtrack/include/memtrack/memtrack.h
similarity index 98%
rename from include/memtrack/memtrack.h
rename to libmemtrack/include/memtrack/memtrack.h
index 3917300..8c0ab89 100644
--- a/include/memtrack/memtrack.h
+++ b/libmemtrack/include/memtrack/memtrack.h
@@ -19,7 +19,6 @@
#include <sys/types.h>
#include <stddef.h>
-#include <cutils/compiler.h>
#ifdef __cplusplus
extern "C" {
diff --git a/libnativeloader/Android.mk b/libnativeloader/Android.mk
index 5e65c4c..6c064c7 100644
--- a/libnativeloader/Android.mk
+++ b/libnativeloader/Android.mk
@@ -17,7 +17,8 @@
LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
LOCAL_LDFLAGS := -ldl
LOCAL_MULTILIB := both
-
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
# Shared library for host
@@ -34,7 +35,8 @@
LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
LOCAL_LDFLAGS := -ldl
LOCAL_MULTILIB := both
-
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_HOST_SHARED_LIBRARY)
# Static library for host
@@ -50,5 +52,6 @@
LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
LOCAL_LDFLAGS := -ldl
LOCAL_MULTILIB := both
-
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
similarity index 100%
rename from include/nativeloader/native_loader.h
rename to libnativeloader/include/nativeloader/native_loader.h
diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk
index 2060df4..281b6c8 100644
--- a/libnetutils/Android.mk
+++ b/libnetutils/Android.mk
@@ -16,6 +16,9 @@
LOCAL_CFLAGS := -Werror
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/include/netutils/dhcp.h b/libnetutils/include/netutils/dhcp.h
similarity index 100%
rename from include/netutils/dhcp.h
rename to libnetutils/include/netutils/dhcp.h
diff --git a/include/netutils/ifc.h b/libnetutils/include/netutils/ifc.h
similarity index 100%
rename from include/netutils/ifc.h
rename to libnetutils/include/netutils/ifc.h
diff --git a/libpackagelistparser/packagelistparser.c b/libpackagelistparser/packagelistparser.c
index 16052e2..e309027 100644
--- a/libpackagelistparser/packagelistparser.c
+++ b/libpackagelistparser/packagelistparser.c
@@ -27,7 +27,7 @@
#include <sys/limits.h>
#define LOG_TAG "packagelistparser"
-#include <utils/Log.h>
+#include <cutils/log.h>
#include <packagelistparser/packagelistparser.h>
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 8c4fd15..9e0d0ac 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -22,7 +22,6 @@
Log.cpp \
NativeHandle.cpp \
Printer.cpp \
- ProcessCallStack.cpp \
PropertyMap.cpp \
RefBase.cpp \
SharedBuffer.cpp \
@@ -44,7 +43,7 @@
# =====================================================
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= $(commonSources)
-LOCAL_SRC_FILES_linux := Looper.cpp
+LOCAL_SRC_FILES_linux := Looper.cpp ProcessCallStack.cpp
LOCAL_CFLAGS_darwin := -Wno-unused-parameter
LOCAL_MODULE:= libutils
LOCAL_STATIC_LIBRARIES := liblog
@@ -67,6 +66,7 @@
$(commonSources) \
BlobCache.cpp \
Looper.cpp \
+ ProcessCallStack.cpp \
Trace.cpp
ifeq ($(TARGET_ARCH),mips)
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index 011c302..cdb586d 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -146,7 +146,6 @@
clear();
// Get current time.
-#ifndef USE_MINGW
{
time_t t = time(NULL);
struct tm tm;
@@ -199,7 +198,6 @@
ALOGE("%s: Failed to readdir from %s: %s",
__FUNCTION__, PATH_SELF_TASK, strerror(code));
}
-#endif
closedir(dp);
}
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index 6a5273f..449fb20 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -77,7 +77,7 @@
//printf("Created UTF-16 string from UTF-8 \"%s\":", in);
//printHexData(1, str, buf->size(), 16, 1);
//printf("\n");
-
+
return u16str;
}
@@ -127,7 +127,7 @@
mString = str;
return;
}
-
+
mString = getEmptyString();
}
@@ -142,7 +142,7 @@
mString = str;
return;
}
-
+
mString = getEmptyString();
}
@@ -228,7 +228,7 @@
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
@@ -249,7 +249,7 @@
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 056b3e1..3cd8b87 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -95,13 +95,12 @@
LOCAL_CFLAGS := $(libziparchive_common_c_flags)
LOCAL_CPPFLAGS := -Wno-unnamed-type-template-args $(libziparchive_common_cpp_flags)
LOCAL_SRC_FILES := $(libziparchive_test_files)
-LOCAL_SHARED_LIBRARIES := \
- libziparchive-host \
- liblog \
- libbase \
-
LOCAL_STATIC_LIBRARIES := \
- libutils \
+ libziparchive-host \
libz \
+ libbase \
+ libutils \
+ liblog \
+LOCAL_MODULE_HOST_OS := darwin linux windows
include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 3b1e972..a2d6fcc 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -224,9 +224,7 @@
strerror(errno));
return kIoError;
}
- ssize_t actual = TEMP_FAILURE_RETRY(
- read(fd, scan_buffer, static_cast<size_t>(read_amount)));
- if (actual != static_cast<ssize_t>(read_amount)) {
+ if (!android::base::ReadFully(fd, scan_buffer, static_cast<size_t>(read_amount))) {
ALOGW("Zip: read %" PRId64 " failed: %s", static_cast<int64_t>(read_amount),
strerror(errno));
return kIoError;
@@ -481,8 +479,7 @@
static int32_t UpdateEntryFromDataDescriptor(int fd,
ZipEntry *entry) {
uint8_t ddBuf[sizeof(DataDescriptor) + sizeof(DataDescriptor::kOptSignature)];
- ssize_t actual = TEMP_FAILURE_RETRY(read(fd, ddBuf, sizeof(ddBuf)));
- if (actual != sizeof(ddBuf)) {
+ if (!android::base::ReadFully(fd, ddBuf, sizeof(ddBuf))) {
return kIoError;
}
@@ -498,26 +495,14 @@
}
// Attempts to read |len| bytes into |buf| at offset |off|.
-//
-// This method uses pread64 on platforms that support it and
-// lseek64 + read on platforms that don't. This implies that
-// callers should not rely on the |fd| offset being incremented
+// Callers should not rely on the |fd| offset being incremented
// as a side effect of this call.
-static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len,
- off64_t off) {
-#if !defined(_WIN32)
- return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));
-#else
- // The only supported platform that doesn't support pread at the moment
- // is Windows. Only recent versions of windows support unix like forks,
- // and even there the semantics are quite different.
+static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) {
if (lseek64(fd, off, SEEK_SET) != off) {
ALOGW("Zip: failed seek to offset %" PRId64, off);
- return kIoError;
+ return false;
}
-
- return TEMP_FAILURE_RETRY(read(fd, buf, len));
-#endif
+ return android::base::ReadFully(fd, buf, len);
}
static int32_t FindEntry(const ZipArchive* archive, const int ent,
@@ -567,9 +552,7 @@
}
uint8_t lfh_buf[sizeof(LocalFileHeader)];
- ssize_t actual = ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf),
- local_header_offset);
- if (actual != sizeof(lfh_buf)) {
+ if (!ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf), local_header_offset)) {
ALOGW("Zip: failed reading lfh name from offset %" PRId64,
static_cast<int64_t>(local_header_offset));
return kIoError;
@@ -610,10 +593,7 @@
}
uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen));
- ssize_t actual = ReadAtOffset(archive->fd, name_buf, nameLen,
- name_offset);
-
- if (actual != nameLen) {
+ if (!ReadAtOffset(archive->fd, name_buf, nameLen, name_offset)) {
ALOGW("Zip: failed reading lfh name from offset %" PRId64, static_cast<int64_t>(name_offset));
free(name_buf);
return kIoError;
@@ -942,10 +922,9 @@
do {
/* read as much as we can */
if (zstream.avail_in == 0) {
- const ZD_TYPE getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
- const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, &read_buf[0], getSize));
- if (actual != getSize) {
- ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize);
+ const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
+ if (!android::base::ReadFully(fd, read_buf.data(), getSize)) {
+ ALOGW("Zip: inflate read failed, getSize = %zu: %s", getSize, strerror(errno));
return kIoError;
}
@@ -1005,11 +984,9 @@
// Safe conversion because kBufSize is narrow enough for a 32 bit signed
// value.
- const ssize_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
- const ssize_t actual = TEMP_FAILURE_RETRY(read(fd, &buf[0], block_size));
-
- if (actual != block_size) {
- ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, block_size);
+ const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining;
+ if (!android::base::ReadFully(fd, buf.data(), block_size)) {
+ ALOGW("CopyFileToFile: copy read failed, block_size = %zu: %s", block_size, strerror(errno));
return kIoError;
}
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index d426dc4..6aee1bb 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -21,9 +21,11 @@
#include <string.h>
#include <unistd.h>
+#include <memory>
#include <vector>
#include <android-base/file.h>
+#include <android-base/test_utils.h>
#include <gtest/gtest.h>
#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_archive_stream_entry.h>
@@ -91,7 +93,7 @@
}
TEST(ziparchive, OpenAssumeFdOwnership) {
- int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+ int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY | O_BINARY);
ASSERT_NE(-1, fd);
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle));
@@ -101,7 +103,7 @@
}
TEST(ziparchive, OpenDoNotAssumeFdOwnership) {
- int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY);
+ int fd = open((test_data_dir + "/" + kValidZip).c_str(), O_RDONLY | O_BINARY);
ASSERT_NE(-1, fd);
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveFd(fd, "OpenWithAssumeFdOwnership", &handle, false));
@@ -373,30 +375,13 @@
static const std::string kAbTxtName("ab.txt");
static const size_t kAbUncompressedSize = 270216;
-static int make_temporary_file(const char* file_name_pattern) {
- char full_path[1024];
- // Account for differences between the host and the target.
- //
- // TODO: Maybe reuse bionic/tests/TemporaryFile.h.
- snprintf(full_path, sizeof(full_path), "/data/local/tmp/%s", file_name_pattern);
- int fd = mkstemp(full_path);
- if (fd == -1) {
- snprintf(full_path, sizeof(full_path), "/tmp/%s", file_name_pattern);
- fd = mkstemp(full_path);
- }
-
- return fd;
-}
-
TEST(ziparchive, EmptyEntries) {
- char temp_file_pattern[] = "empty_entries_test_XXXXXX";
- int fd = make_temporary_file(temp_file_pattern);
- ASSERT_NE(-1, fd);
- const ssize_t file_size = sizeof(kEmptyEntriesZip);
- ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
+ TemporaryFile tmp_file;
+ ASSERT_NE(-1, tmp_file.fd);
+ ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
ZipArchiveHandle handle;
- ASSERT_EQ(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
+ ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EmptyEntriesTest", &handle));
ZipEntry entry;
ZipString empty_name;
@@ -406,27 +391,23 @@
uint8_t buffer[1];
ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));
- char output_file_pattern[] = "empty_entries_output_XXXXXX";
- int output_fd = make_temporary_file(output_file_pattern);
- ASSERT_NE(-1, output_fd);
- ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, output_fd));
+
+ TemporaryFile tmp_output_file;
+ ASSERT_NE(-1, tmp_output_file.fd);
+ ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
struct stat stat_buf;
- ASSERT_EQ(0, fstat(output_fd, &stat_buf));
+ ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));
ASSERT_EQ(0, stat_buf.st_size);
-
- close(fd);
- close(output_fd);
}
TEST(ziparchive, EntryLargerThan32K) {
- char temp_file_pattern[] = "entry_larger_than_32k_test_XXXXXX";
- int fd = make_temporary_file(temp_file_pattern);
- ASSERT_NE(-1, fd);
- ASSERT_TRUE(android::base::WriteFully(fd, reinterpret_cast<const uint8_t*>(kAbZip),
+ TemporaryFile tmp_file;
+ ASSERT_NE(-1, tmp_file.fd);
+ ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, reinterpret_cast<const uint8_t*>(kAbZip),
sizeof(kAbZip) - 1));
ZipArchiveHandle handle;
- ASSERT_EQ(0, OpenArchiveFd(fd, "EntryLargerThan32KTest", &handle));
+ ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EntryLargerThan32KTest", &handle));
ZipEntry entry;
ZipString ab_name;
@@ -439,21 +420,21 @@
ASSERT_EQ(0, ExtractToMemory(handle, &entry, &buffer[0], buffer.size()));
// Extract the entry to a file.
- char output_file_pattern[] = "entry_larger_than_32k_test_output_XXXXXX";
- int output_fd = make_temporary_file(output_file_pattern);
- ASSERT_NE(-1, output_fd);
- ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, output_fd));
+ TemporaryFile tmp_output_file;
+ ASSERT_NE(-1, tmp_output_file.fd);
+ ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
// Make sure the extracted file size is as expected.
struct stat stat_buf;
- ASSERT_EQ(0, fstat(output_fd, &stat_buf));
+ ASSERT_EQ(0, fstat(tmp_output_file.fd, &stat_buf));
ASSERT_EQ(kAbUncompressedSize, static_cast<size_t>(stat_buf.st_size));
// Read the file back to a buffer and make sure the contents are
// the same as the memory buffer we extracted directly to.
std::vector<uint8_t> file_contents(kAbUncompressedSize);
- ASSERT_EQ(0, lseek64(output_fd, 0, SEEK_SET));
- ASSERT_TRUE(android::base::ReadFully(output_fd, &file_contents[0], file_contents.size()));
+ ASSERT_EQ(0, lseek64(tmp_output_file.fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0],
+ file_contents.size()));
ASSERT_EQ(file_contents, buffer);
for (int i = 0; i < 90072; ++i) {
@@ -462,35 +443,28 @@
ASSERT_EQ('b', line[1]);
ASSERT_EQ('\n', line[2]);
}
-
- close(fd);
- close(output_fd);
}
TEST(ziparchive, TrailerAfterEOCD) {
- char temp_file_pattern[] = "trailer_after_eocd_test_XXXXXX";
- int fd = make_temporary_file(temp_file_pattern);
- ASSERT_NE(-1, fd);
+ TemporaryFile tmp_file;
+ ASSERT_NE(-1, tmp_file.fd);
// Create a file with 8 bytes of random garbage.
static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };
- const ssize_t file_size = sizeof(kEmptyEntriesZip);
- const ssize_t trailer_size = sizeof(trailer);
- ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
- ASSERT_EQ(trailer_size, TEMP_FAILURE_RETRY(write(fd, trailer, trailer_size)));
+ ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
+ ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, trailer, sizeof(trailer)));
ZipArchiveHandle handle;
- ASSERT_GT(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
+ ASSERT_GT(0, OpenArchiveFd(tmp_file.fd, "EmptyEntriesTest", &handle));
}
TEST(ziparchive, ExtractToFile) {
- char kTempFilePattern[] = "zip_archive_input_XXXXXX";
- int fd = make_temporary_file(kTempFilePattern);
- ASSERT_NE(-1, fd);
+ TemporaryFile tmp_file;
+ ASSERT_NE(-1, tmp_file.fd);
const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };
- const ssize_t data_size = sizeof(data);
+ const size_t data_size = sizeof(data);
- ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(write(fd, data, data_size)));
+ ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, data, data_size));
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
@@ -499,28 +473,25 @@
ZipString name;
SetZipString(&name, kATxtName);
ASSERT_EQ(0, FindEntry(handle, name, &entry));
- ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, fd));
+ ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_file.fd));
// Assert that the first 8 bytes of the file haven't been clobbered.
uint8_t read_buffer[data_size];
- ASSERT_EQ(0, lseek64(fd, 0, SEEK_SET));
- ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(read(fd, read_buffer, data_size)));
+ ASSERT_EQ(0, lseek64(tmp_file.fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, read_buffer, data_size));
ASSERT_EQ(0, memcmp(read_buffer, data, data_size));
// Assert that the remainder of the file contains the incompressed data.
std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);
- ASSERT_EQ(static_cast<ssize_t>(entry.uncompressed_length),
- TEMP_FAILURE_RETRY(
- read(fd, &uncompressed_data[0], entry.uncompressed_length)));
+ ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, uncompressed_data.data(),
+ entry.uncompressed_length));
ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(),
kATxtContents.size()));
// Assert that the total length of the file is sane
- ASSERT_EQ(data_size + static_cast<ssize_t>(kATxtContents.size()),
- lseek64(fd, 0, SEEK_END));
-
- close(fd);
+ ASSERT_EQ(static_cast<ssize_t>(data_size + kATxtContents.size()),
+ lseek64(tmp_file.fd, 0, SEEK_END));
}
static void ZipArchiveStreamTest(
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index fe0846d..16a574d 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -154,12 +154,22 @@
tm->tm_mday = (zip_time >> 16) & 0x1f;
}
+static struct tm MakeTm() {
+ struct tm tm;
+ memset(&tm, 0, sizeof(struct tm));
+ tm.tm_year = 2001 - 1900;
+ tm.tm_mon = 1;
+ tm.tm_mday = 12;
+ tm.tm_hour = 18;
+ tm.tm_min = 30;
+ tm.tm_sec = 20;
+ return tm;
+}
+
TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlagAndTime) {
ZipWriter writer(file_);
- struct tm tm;
- memset(&tm, 0, sizeof(struct tm));
- ASSERT_TRUE(strptime("18:30:20 1/12/2001", "%H:%M:%S %d/%m/%Y", &tm) != nullptr);
+ struct tm tm = MakeTm();
time_t time = mktime(&tm);
ASSERT_EQ(0, writer.StartEntryWithTime("align.txt", ZipWriter::kAlign32, time));
ASSERT_EQ(0, writer.WriteBytes("he", 2));
@@ -210,9 +220,7 @@
TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValueAndTime) {
ZipWriter writer(file_);
- struct tm tm;
- memset(&tm, 0, sizeof(struct tm));
- ASSERT_TRUE(strptime("18:30:20 1/12/2001", "%H:%M:%S %d/%m/%Y", &tm) != nullptr);
+ struct tm tm = MakeTm();
time_t time = mktime(&tm);
ASSERT_EQ(0, writer.StartAlignedEntryWithTime("align.txt", 0, time, 4096));
ASSERT_EQ(0, writer.WriteBytes("he", 2));
diff --git a/logcat/logpersist b/logcat/logpersist
index dab466d..8762ff1 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -1,8 +1,8 @@
#! /system/bin/sh
# logpersist cat start and stop handlers
progname="${0##*/}"
-case `getprop ro.build.type` in
-userdebug|eng) ;;
+case `getprop ro.debuggable` in
+1) ;;
*) echo "${progname} - Permission denied"
exit 1
;;
diff --git a/logd/Android.mk b/logd/Android.mk
index feca8d5..203943c 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -42,6 +42,10 @@
LOCAL_CFLAGS := -Werror $(event_flag)
+ifeq ($(TARGET_BUILD_VARIANT),user)
+LOCAL_CFLAGS += -DAUDITD_ENFORCE_INTEGRITY=true
+endif
+
include $(BUILD_EXECUTABLE)
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 143fb04..fffc9ba 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -24,6 +24,7 @@
#include <sys/uio.h>
#include <syslog.h>
+#include <cutils/properties.h>
#include <log/logger.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
@@ -32,6 +33,10 @@
#include "LogAudit.h"
#include "LogKlog.h"
+#ifndef AUDITD_ENFORCE_INTEGRITY
+#define AUDITD_ENFORCE_INTEGRITY false
+#endif
+
#define KMSG_PRIORITY(PRI) \
'<', \
'0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) / 10, \
@@ -43,11 +48,10 @@
logbuf(buf),
reader(reader),
fdDmesg(fdDmesg),
+ policyLoaded(false),
+ rebootToSafeMode(false),
initialized(false) {
- static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
- 'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':',
- ' ', 's', 't', 'a', 'r', 't', '\n' };
- write(fdDmesg, auditd_message, sizeof(auditd_message));
+ logToDmesg("start");
}
bool LogAudit::onDataAvailable(SocketClient *cli) {
@@ -73,6 +77,46 @@
return true;
}
+void LogAudit::logToDmesg(const std::string& str)
+{
+ static const char prefix[] = { KMSG_PRIORITY(LOG_INFO),
+ 'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':',
+ ' ', '\0' };
+ std::string message = prefix + str + "\n";
+ write(fdDmesg, message.c_str(), message.length());
+}
+
+std::string LogAudit::getProperty(const std::string& name)
+{
+ char value[PROP_VALUE_MAX] = {0};
+ property_get(name.c_str(), value, "");
+ return value;
+}
+
+void LogAudit::enforceIntegrity() {
+ if (!AUDITD_ENFORCE_INTEGRITY) {
+ logToDmesg("integrity enforcement suppressed; not rebooting");
+ } else if (rebootToSafeMode) {
+ if (getProperty("persist.sys.safemode") == "1") {
+ logToDmesg("integrity enforcement suppressed; in safe mode");
+ return;
+ }
+
+ logToDmesg("enforcing integrity; rebooting to safe mode");
+ property_set("persist.sys.safemode", "1");
+
+ std::string buildDate = getProperty("ro.build.date.utc");
+ if (!buildDate.empty()) {
+ property_set("persist.sys.audit_safemode", buildDate.c_str());
+ }
+
+ property_set("sys.powerctl", "reboot");
+ } else {
+ logToDmesg("enforcing integrity: rebooting to recovery");
+ property_set("sys.powerctl", "reboot,recovery");
+ }
+}
+
int LogAudit::logPrint(const char *fmt, ...) {
if (fmt == NULL) {
return -EINVAL;
@@ -94,7 +138,27 @@
memmove(cp, cp + 1, strlen(cp + 1) + 1);
}
- bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
+ bool loaded = strstr(str, " policy loaded ");
+
+ if (loaded) {
+ if (policyLoaded) {
+ // SELinux policy changes are not allowed
+ enforceIntegrity();
+ } else {
+ logToDmesg("policy loaded");
+ policyLoaded = true;
+ }
+ }
+
+ bool permissive = strstr(str, " enforcing=0") ||
+ strstr(str, " permissive=1");
+
+ if (permissive) {
+ // SELinux in permissive mode is not allowed
+ enforceIntegrity();
+ }
+
+ bool info = loaded || permissive;
if ((fdDmesg >= 0) && initialized) {
struct iovec iov[3];
static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 8a82630..455ed58 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -24,12 +24,15 @@
LogBuffer *logbuf;
LogReader *reader;
int fdDmesg;
+ bool policyLoaded;
+ bool rebootToSafeMode;
bool initialized;
public:
LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg);
int log(char *buf, size_t len);
bool isMonotonic() { return logbuf->isMonotonic(); }
+ void allowSafeMode(bool allow = true) { rebootToSafeMode = allow; }
protected:
virtual bool onDataAvailable(SocketClient *cli);
@@ -38,6 +41,9 @@
static int getLogSocket();
int logPrint(const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
+ void logToDmesg(const std::string& str);
+ std::string getProperty(const std::string& name);
+ void enforceIntegrity();
};
#endif
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index fd4800e..aa4b6e1 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -17,6 +17,7 @@
#ifndef _LOGD_LOG_UTILS_H__
#define _LOGD_LOG_UTILS_H__
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <log/log.h>
@@ -29,6 +30,7 @@
// Furnished in main.cpp. Caller must own and free returned value
char *uidToName(uid_t uid);
+void prdebug(const char *fmt, ...) __printflike(1, 2);
// Furnished in LogStatistics.cpp. Caller must own and free returned value
char *pidToName(pid_t pid);
diff --git a/logd/README.property b/logd/README.property
index 22f86b9..4bc5541 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -1,14 +1,13 @@
The properties that logd responds to are:
name type default description
-ro.logd.auditd bool true Enable selinux audit daemon
ro.logd.auditd.dmesg bool true selinux audit messages duplicated and
sent on to dmesg log
persist.logd.security bool false Enable security buffer.
ro.device_owner bool false Override persist.logd.security to false
ro.logd.kernel bool+ svelte+ Enable klogd daemon
ro.logd.statistics bool+ svelte+ Enable logcat -S statistics.
-ro.build.type string if user, logd.statistics &
+ro.debuggable number if not "1", logd.statistics &
ro.logd.kernel default false.
persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
turns on logcat -f in logd context
@@ -46,10 +45,10 @@
NB:
- bool+ - "true", "false" and comma separated list of "eng" (forced false if
- ro.build.type is "user") or "svelte" (forced false if ro.config.low_ram is
+ ro.debuggable is not "1") or "svelte" (forced false if ro.config.low_ram is
true).
- svelte - see ro.config.low_ram for details.
-- svelte+ - see ro.config.low_ram and ro.build.type for details.
+- svelte+ - see ro.config.low_ram and ro.debuggable for details.
- ro - <base property> temporary override, ro.<base property> platform default.
- persist - <base property> override, persist.<base property> platform default.
- build - VERBOSE for native, DEBUG for jvm isLoggable, or developer option.
diff --git a/logd/main.cpp b/logd/main.cpp
index ba56e57..f4d7464 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -202,8 +202,8 @@
return false;
}
if (flag & BOOL_DEFAULT_FLAG_ENG) {
- property_get("ro.build.type", property, "");
- if (!strcmp(property, "user")) {
+ property_get("ro.debuggable", property, "");
+ if (strcmp(property, "1")) {
return false;
}
}
@@ -211,10 +211,32 @@
return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
}
-// Remove the static, and use this variable
-// globally for debugging if necessary. eg:
-// write(fdDmesg, "I am here\n", 10);
static int fdDmesg = -1;
+void inline android::prdebug(const char *fmt, ...) {
+ if (fdDmesg < 0) {
+ return;
+ }
+
+ static const char message[] = {
+ KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' '
+ };
+ char buffer[256];
+ memcpy(buffer, message, sizeof(message));
+
+ va_list ap;
+ va_start(ap, fmt);
+ int n = vsnprintf(buffer + sizeof(message),
+ sizeof(buffer) - sizeof(message), fmt, ap);
+ va_end(ap);
+ if (n > 0) {
+ buffer[sizeof(buffer) - 1] = '\0';
+ if (!strchr(buffer, '\n')) {
+ buffer[sizeof(buffer) - 2] = '\0';
+ strlcat(buffer, "\n", sizeof(buffer));
+ }
+ write(fdDmesg, buffer, strlen(buffer));
+ }
+}
static sem_t uidName;
static uid_t uid;
@@ -223,6 +245,7 @@
static sem_t reinit;
static bool reinit_running = false;
static LogBuffer *logBuf = NULL;
+static LogAudit *logAudit = NULL;
static bool package_list_parser_cb(pkg_info *info, void * /* userdata */) {
@@ -270,6 +293,10 @@
logBuf->init();
logBuf->initPrune(NULL);
}
+
+ if (logAudit) {
+ logAudit->allowSafeMode();
+ }
}
return NULL;
@@ -490,25 +517,19 @@
// initiated log messages. New log entries are added to LogBuffer
// and LogReader is notified to send updates to connected clients.
- bool auditd = property_get_bool("logd.auditd",
- BOOL_DEFAULT_TRUE |
- BOOL_DEFAULT_FLAG_PERSIST);
- LogAudit *al = NULL;
- if (auditd) {
- al = new LogAudit(logBuf, reader,
- property_get_bool("logd.auditd.dmesg",
- BOOL_DEFAULT_TRUE |
- BOOL_DEFAULT_FLAG_PERSIST)
- ? fdDmesg
- : -1);
- }
+ logAudit = new LogAudit(logBuf, reader,
+ property_get_bool("logd.auditd.dmesg",
+ BOOL_DEFAULT_TRUE |
+ BOOL_DEFAULT_FLAG_PERSIST)
+ ? fdDmesg
+ : -1);
LogKlog *kl = NULL;
if (klogd) {
- kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL);
+ kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, logAudit != NULL);
}
- readDmesg(al, kl);
+ readDmesg(logAudit, kl);
// failure is an option ... messages are in dmesg (required by standard)
@@ -516,8 +537,9 @@
delete kl;
}
- if (al && al->startListener()) {
- delete al;
+ if (logAudit && logAudit->startListener()) {
+ delete logAudit;
+ logAudit = NULL;
}
TEMP_FAILURE_RETRY(pause());
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index 28d6de7..ccbe0bf 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -408,7 +408,7 @@
if (poll_fds[0].revents & POLLHUP) {
int ret;
- ret = waitpid(pid, &status, WNOHANG);
+ ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
if (ret < 0) {
rc = errno;
ALOG(LOG_ERROR, "logwrap", "waitpid failed with %s\n", strerror(errno));
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
deleted file mode 100644
index c98efc2..0000000
--- a/metricsd/.clang-format
+++ /dev/null
@@ -1,10 +0,0 @@
-BasedOnStyle: Google
-AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-BinPackArguments: false
-BinPackParameters: false
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-PointerAlignment: Left
-TabWidth: 2
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
new file mode 120000
index 0000000..f9066d4
--- /dev/null
+++ b/metricsd/.clang-format
@@ -0,0 +1 @@
+../../../build/tools/brillo-clang-format
\ No newline at end of file
diff --git a/metricsd/uploader/upload_service_test.cc b/metricsd/uploader/upload_service_test.cc
index 70112f4..0f77fe4 100644
--- a/metricsd/uploader/upload_service_test.cc
+++ b/metricsd/uploader/upload_service_test.cc
@@ -304,6 +304,8 @@
upload_service_->PersistToDisk();
EXPECT_EQ(
1, upload_service_->current_log_->uma_proto()->histogram_event().size());
+ // Destroy the old service before creating a new one.
+ upload_service_.reset();
upload_service_.reset(new UploadService(
"", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
upload_service_->InitForTest(nullptr);
@@ -325,6 +327,8 @@
// Write a bogus saved log.
EXPECT_EQ(5, base::WriteFile(upload_service_->saved_log_path_, "hello", 5));
+ // Destroy the old service before creating a new one.
+ upload_service_.reset();
upload_service_.reset(new UploadService(
"", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
diff --git a/sdcard/Android.mk b/sdcard/Android.mk
index c5f3d1d..2d04a7f 100644
--- a/sdcard/Android.mk
+++ b/sdcard/Android.mk
@@ -5,6 +5,6 @@
LOCAL_SRC_FILES := sdcard.c
LOCAL_MODULE := sdcard
LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
-LOCAL_SHARED_LIBRARIES := libcutils libpackagelistparser
+LOCAL_SHARED_LIBRARIES := liblog libcutils libpackagelistparser
include $(BUILD_EXECUTABLE)
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 9ade759..fc2898e 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -55,6 +55,7 @@
LOCAL_CONLYFLAGS += -std=gnu99
LOCAL_SHARED_LIBRARIES := \
+ liblog \
libcutils \
libselinux \