Merge "init: move empty string check to InitTriggers"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 8b6b2b5..3cd50ba 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -30,7 +30,9 @@
#include <sys/time.h>
#include <time.h>
+#include <chrono>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/errors.h>
@@ -51,6 +53,7 @@
#include <sys/capability.h>
#include <sys/mount.h>
#include <android-base/properties.h>
+using namespace std::chrono_literals;
#endif
std::string adb_version() {
@@ -375,7 +378,7 @@
adbd_auth_verified(t);
t->failed_auth_attempts = 0;
} else {
- if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
+ if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
send_auth_request(t);
}
break;
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 919e1c1..0b1ba32 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/stringprintf.h>
@@ -38,6 +39,7 @@
#include "adb_io.h"
#include "adb_utils.h"
#include "socket_spec.h"
+#include "sysdeps/chrono.h"
static TransportType __adb_transport = kTransportAny;
static const char* __adb_serial = NULL;
@@ -188,8 +190,8 @@
} else {
fprintf(stdout,"* daemon started successfully *\n");
}
- /* give the server some time to start properly and detect devices */
- adb_sleep_ms(3000);
+ // Give the server some time to start properly and detect devices.
+ std::this_thread::sleep_for(3s);
// fall through to _adb_connect
} else {
// If a server is already running, check its version matches.
@@ -234,7 +236,7 @@
}
/* XXX can we better detect its death? */
- adb_sleep_ms(2000);
+ std::this_thread::sleep_for(2s);
goto start_server;
}
}
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index ae16834..ca8729e 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -20,6 +20,8 @@
#include <unistd.h>
+#include <thread>
+
#include <android-base/stringprintf.h>
#include "adb.h"
@@ -104,7 +106,7 @@
if (r == -1) {
D("writex: fd=%d error %d: %s", fd, errno, strerror(errno));
if (errno == EAGAIN) {
- adb_sleep_ms(1); // just yield some cpu time
+ std::this_thread::yield();
continue;
} else if (errno == EPIPE) {
D("writex: fd=%d disconnected", fd);
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index e15bcad..a064de2 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -33,6 +33,7 @@
#include <memory>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/file.h>
@@ -59,6 +60,7 @@
#include "file_sync_service.h"
#include "services.h"
#include "shell_service.h"
+#include "sysdeps/chrono.h"
static int install_app(TransportType t, const char* serial, int argc, const char** argv);
static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
@@ -1080,7 +1082,7 @@
// Give adbd some time to kill itself and come back up.
// We can't use wait-for-device because devices (e.g. adb over network) might not come back.
- adb_sleep_ms(3000);
+ std::this_thread::sleep_for(3s);
return true;
}
diff --git a/adb/socket_test.cpp b/adb/socket_test.cpp
index 5e79b5e..f56f7f7 100644
--- a/adb/socket_test.cpp
+++ b/adb/socket_test.cpp
@@ -22,6 +22,7 @@
#include <limits>
#include <queue>
#include <string>
+#include <thread>
#include <vector>
#include <unistd.h>
@@ -31,6 +32,7 @@
#include "fdevent_test.h"
#include "socket.h"
#include "sysdeps.h"
+#include "sysdeps/chrono.h"
struct ThreadArg {
int first_read_fd;
@@ -44,7 +46,7 @@
fdevent_loop();
}
-const size_t SLEEP_FOR_FDEVENT_IN_MS = 100;
+constexpr auto SLEEP_FOR_FDEVENT = 100ms;
TEST_F(LocalSocketTest, smoke) {
// Join two socketpairs with a chain of intermediate socketpairs.
@@ -101,7 +103,7 @@
ASSERT_EQ(0, adb_close(last[1]));
// Wait until the local sockets are closed.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -154,12 +156,12 @@
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -179,9 +181,9 @@
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
// Verify if we can read successfully.
@@ -190,7 +192,7 @@
ASSERT_EQ(true, ReadFdExactly(socket_fd[0], buf.data(), buf.size()));
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -214,11 +216,11 @@
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(2u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
ASSERT_EQ(0, adb_close(socket_fd[0]));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
@@ -229,7 +231,7 @@
std::string error;
int fd = network_loopback_client(5038, SOCK_STREAM, &error);
ASSERT_GE(fd, 0) << error;
- adb_sleep_ms(200);
+ std::this_thread::sleep_for(200ms);
ASSERT_EQ(0, adb_close(fd));
}
@@ -265,13 +267,13 @@
&arg, &thread));
// Wait until the fdevent_loop() starts.
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
EXPECT_EQ(1u + GetAdditionalLocalSocketCount(), fdevent_installed_count());
// Wait until the client closes its socket.
ASSERT_TRUE(adb_thread_join(client_thread));
- adb_sleep_ms(SLEEP_FOR_FDEVENT_IN_MS);
+ std::this_thread::sleep_for(SLEEP_FOR_FDEVENT);
ASSERT_EQ(GetAdditionalLocalSocketCount(), fdevent_installed_count());
TerminateThread(thread);
}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index ad9b9fd..0489d09 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -248,11 +248,6 @@
int unix_isatty(int fd);
#define isatty ___xxx_isatty
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- Sleep( mseconds );
-}
-
int network_loopback_client(int port, int type, std::string* error);
int network_loopback_server(int port, int type, std::string* error);
int network_inaddr_any_server(int port, int type, std::string* error);
@@ -766,11 +761,6 @@
#define poll ___xxx_poll
-static __inline__ void adb_sleep_ms( int mseconds )
-{
- usleep( mseconds*1000 );
-}
-
static __inline__ int adb_mkdir(const std::string& path, int mode)
{
return mkdir(path.c_str(), mode);
diff --git a/adb/sysdeps/chrono.h b/adb/sysdeps/chrono.h
new file mode 100644
index 0000000..c73a638
--- /dev/null
+++ b/adb/sysdeps/chrono.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <chrono>
+
+#if defined(_WIN32)
+// We don't have C++14 on Windows yet.
+// Reimplement std::chrono_literals ourselves until we do.
+
+// Silence the following warning (which gets promoted to an error):
+// error: literal operator suffixes not preceded by ‘_’ are reserved for future standardization
+#pragma GCC system_header
+
+constexpr std::chrono::seconds operator"" s(unsigned long long s) {
+ return std::chrono::seconds(s);
+}
+
+constexpr std::chrono::duration<long double> operator"" s(long double s) {
+ return std::chrono::duration<long double>(s);
+}
+
+constexpr std::chrono::milliseconds operator"" ms(unsigned long long ms) {
+ return std::chrono::milliseconds(ms);
+}
+
+constexpr std::chrono::duration<long double, std::milli> operator"" ms(long double ms) {
+ return std::chrono::duration<long double, std::milli>(ms);
+}
+#else
+using namespace std::chrono_literals;
+#endif
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
index 9f77942..9007e75 100644
--- a/adb/sysdeps_test.cpp
+++ b/adb/sysdeps_test.cpp
@@ -16,14 +16,17 @@
#include <gtest/gtest.h>
#include <unistd.h>
+
#include <atomic>
#include <condition_variable>
+#include <thread>
#include "adb_io.h"
#include "sysdeps.h"
+#include "sysdeps/chrono.h"
static void increment_atomic_int(void* c) {
- sleep(1);
+ std::this_thread::sleep_for(1s);
reinterpret_cast<std::atomic<int>*>(c)->fetch_add(1);
}
@@ -34,7 +37,7 @@
ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter));
}
- sleep(2);
+ std::this_thread::sleep_for(2s);
ASSERT_EQ(100, counter.load());
}
@@ -255,15 +258,15 @@
ASSERT_FALSE(m.try_lock());
m.lock();
finished.store(true);
- adb_sleep_ms(200);
+ std::this_thread::sleep_for(200ms);
m.unlock();
}, nullptr);
ASSERT_FALSE(finished.load());
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
ASSERT_FALSE(finished.load());
m.unlock();
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
m.lock();
ASSERT_TRUE(finished.load());
m.unlock();
@@ -279,13 +282,13 @@
adb_thread_create([](void*) {
ASSERT_FALSE(m.try_lock());
m.lock();
- adb_sleep_ms(500);
+ std::this_thread::sleep_for(500ms);
m.unlock();
}, nullptr);
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
m.unlock();
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
ASSERT_FALSE(m.try_lock());
m.lock();
m.unlock();
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index ba2b28d..c17f869 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -27,6 +27,7 @@
#include <condition_variable>
#include <mutex>
+#include <thread>
#include <vector>
#include <android-base/stringprintf.h>
@@ -39,6 +40,7 @@
#include "adb.h"
#include "adb_io.h"
#include "adb_utils.h"
+#include "sysdeps/chrono.h"
#if ADB_HOST
@@ -144,7 +146,7 @@
// Retry the disconnected local port for 60 times, and sleep 1 second between two retries.
constexpr uint32_t LOCAL_PORT_RETRY_COUNT = 60;
-constexpr uint32_t LOCAL_PORT_RETRY_INTERVAL_IN_MS = 1000;
+constexpr auto LOCAL_PORT_RETRY_INTERVAL = 1s;
struct RetryPort {
int port;
@@ -173,7 +175,7 @@
// Sleep here instead of the end of loop, because if we immediately try to reconnect
// the emulator just kicked, the adbd on the emulator may not have time to remove the
// just kicked transport.
- adb_sleep_ms(LOCAL_PORT_RETRY_INTERVAL_IN_MS);
+ std::this_thread::sleep_for(LOCAL_PORT_RETRY_INTERVAL);
// Try connecting retry ports.
std::vector<RetryPort> next_ports;
@@ -214,7 +216,7 @@
serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
if(serverfd < 0) {
D("server: cannot bind socket yet: %s", error.c_str());
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
continue;
}
close_on_exec(serverfd);
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index 3e5028d..e7f1338 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -38,6 +38,7 @@
#include <list>
#include <mutex>
#include <string>
+#include <thread>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
@@ -46,6 +47,7 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
using namespace std::literals;
/* usb scan debugging is waaaay too verbose */
@@ -577,7 +579,7 @@
// TODO: Use inotify.
find_usb_device("/dev/bus/usb", register_device);
kick_disconnected_devices();
- sleep(1);
+ std::this_thread::sleep_for(1s);
}
}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 6de10f5..1cc7f68 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -31,8 +31,10 @@
#include <algorithm>
#include <atomic>
+#include <chrono>
#include <condition_variable>
#include <mutex>
+#include <thread>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -40,6 +42,8 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
+
#define MAX_PACKET_SIZE_FS 64
#define MAX_PACKET_SIZE_HS 512
#define MAX_PACKET_SIZE_SS 1024
@@ -268,7 +272,7 @@
fd = unix_open("/dev/android", O_RDWR);
}
if (fd < 0) {
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
} while (fd < 0);
D("[ opening device succeeded ]");
@@ -476,7 +480,7 @@
if (init_functionfs(usb)) {
break;
}
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
android::base::SetProperty("sys.usb.ffs.ready", "1");
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 2ee2aae..e541f6e 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -30,8 +30,10 @@
#include <stdio.h>
#include <atomic>
+#include <chrono>
#include <memory>
#include <mutex>
+#include <thread>
#include <vector>
#include <android-base/logging.h>
@@ -40,6 +42,8 @@
#include "adb.h"
#include "transport.h"
+using namespace std::chrono_literals;
+
struct usb_handle
{
UInt8 bulkIn;
@@ -411,7 +415,7 @@
}
// Signal the parent that we are running
usb_inited_flag = true;
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
VLOG(USB) << "RunLoopThread done";
}
@@ -436,7 +440,7 @@
// Wait for initialization to finish
while (!usb_inited_flag) {
- adb_sleep_ms(100);
+ std::this_thread::sleep_for(100ms);
}
initialized = true;
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index 755f07e..640e91e 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -28,12 +28,14 @@
#include <stdlib.h>
#include <mutex>
+#include <thread>
#include <adb_api.h>
#include <android-base/errors.h>
#include "adb.h"
+#include "sysdeps/chrono.h"
#include "transport.h"
/** Structure usb_handle describes our connection to the usb device via
@@ -176,9 +178,9 @@
adb_thread_setname("Device Poll");
D("Created device thread");
- while(1) {
+ while (true) {
find_devices();
- adb_sleep_ms(1000);
+ std::this_thread::sleep_for(1s);
}
}
diff --git a/include/cutils/files.h b/include/cutils/android_get_control_file.h
similarity index 87%
rename from include/cutils/files.h
rename to include/cutils/android_get_control_file.h
index 0210e30..ed8fbf8 100644
--- a/include/cutils/files.h
+++ b/include/cutils/android_get_control_file.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef __CUTILS_FILES_H
-#define __CUTILS_FILES_H
+#ifndef __CUTILS_ANDROID_GET_CONTROL_FILE_H
+#define __CUTILS_ANDROID_GET_CONTROL_FILE_H
#define ANDROID_FILE_ENV_PREFIX "ANDROID_FILE_"
@@ -34,4 +34,4 @@
}
#endif
-#endif /* __CUTILS_FILES_H */
+#endif /* __CUTILS_ANDROID_GET_CONTROL_FILE_H */
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index 4626e7a..d724dd6 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -35,6 +35,7 @@
#else
#include <sys/socket.h>
+#include <netinet/in.h>
typedef int cutils_socket_t;
#define INVALID_SOCKET (-1)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index d10f719..6d58754 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -40,6 +40,7 @@
#include <thread>
+#include <selinux/android.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -904,21 +905,49 @@
static int do_restorecon(const std::vector<std::string>& args) {
int ret = 0;
- for (auto it = std::next(args.begin()); it != args.end(); ++it) {
- if (restorecon(it->c_str()) < 0)
- ret = -errno;
+ struct flag_type {const char* name; int value;};
+ static const flag_type flags[] = {
+ {"--recursive", SELINUX_ANDROID_RESTORECON_RECURSE},
+ {"--skip-ce", SELINUX_ANDROID_RESTORECON_SKIPCE},
+ {"--cross-filesystems", SELINUX_ANDROID_RESTORECON_CROSS_FILESYSTEMS},
+ {0, 0}
+ };
+
+ int flag = 0;
+
+ bool in_flags = true;
+ for (size_t i = 1; i < args.size(); ++i) {
+ if (android::base::StartsWith(args[i], "--")) {
+ if (!in_flags) {
+ LOG(ERROR) << "restorecon - flags must precede paths";
+ return -1;
+ }
+ bool found = false;
+ for (size_t j = 0; flags[j].name; ++j) {
+ if (args[i] == flags[j].name) {
+ flag |= flags[j].value;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ LOG(ERROR) << "restorecon - bad flag " << args[i];
+ return -1;
+ }
+ } else {
+ in_flags = false;
+ if (restorecon(args[i].c_str(), flag) < 0) {
+ ret = -errno;
+ }
+ }
}
return ret;
}
static int do_restorecon_recursive(const std::vector<std::string>& args) {
- int ret = 0;
-
- for (auto it = std::next(args.begin()); it != args.end(); ++it) {
- if (restorecon_recursive(it->c_str()) < 0)
- ret = -errno;
- }
- return ret;
+ std::vector<std::string> non_const_args(args);
+ non_const_args.insert(std::next(non_const_args.begin()), "--recursive");
+ return do_restorecon(non_const_args);
}
static int do_loglevel(const std::vector<std::string>& args) {
diff --git a/init/descriptors.cpp b/init/descriptors.cpp
index 10aae88..429a76e 100644
--- a/init/descriptors.cpp
+++ b/init/descriptors.cpp
@@ -23,7 +23,7 @@
#include <unistd.h>
#include <android-base/stringprintf.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
#include "init.h"
diff --git a/init/devices.cpp b/init/devices.cpp
index 2452c1d..2db24b7 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -190,7 +190,7 @@
if (access(path.c_str(), F_OK) == 0) {
LOG(VERBOSE) << "restorecon_recursive: " << path;
- restorecon_recursive(path.c_str());
+ restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
}
}
diff --git a/init/init.cpp b/init/init.cpp
index cbd46bf..4efcc34 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -657,8 +657,8 @@
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon("/property_contexts");
- restorecon_recursive("/sys");
- restorecon_recursive("/dev/block");
+ restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
+ restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE);
restorecon("/dev/device-mapper");
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
diff --git a/init/property_service.cpp b/init/property_service.cpp
index e7176c6..e198297 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -42,6 +42,7 @@
#include <netinet/in.h>
#include <sys/mman.h>
+#include <selinux/android.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
@@ -175,7 +176,7 @@
if (valuelen >= PROP_VALUE_MAX) return -1;
if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
- if (restorecon_recursive(value) != 0) {
+ if (restorecon(value, SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
LOG(ERROR) << "Failed to restorecon_recursive " << value;
}
}
diff --git a/init/util.cpp b/init/util.cpp
index cb5a094..5205ea0 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -369,14 +369,9 @@
return rc;
}
-int restorecon(const char* pathname)
+int restorecon(const char* pathname, int flags)
{
- return selinux_android_restorecon(pathname, 0);
-}
-
-int restorecon_recursive(const char* pathname)
-{
- return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE);
+ return selinux_android_restorecon(pathname, flags);
}
/*
diff --git a/init/util.h b/init/util.h
index dccec04..d56da39 100644
--- a/init/util.h
+++ b/init/util.h
@@ -68,8 +68,7 @@
void import_kernel_cmdline(bool in_qemu,
const std::function<void(const std::string&, const std::string&, bool)>&);
int make_dir(const char *path, mode_t mode);
-int restorecon(const char *pathname);
-int restorecon_recursive(const char *pathname);
+int restorecon(const char *pathname, int flags = 0);
std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
bool is_dir(const char* pathname);
bool expand_props(const std::string& src, std::string* dst);
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 6ecbf90..e9f164d 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -16,6 +16,7 @@
#include "util.h"
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -23,7 +24,9 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <cutils/android_get_control_file.h>
#include <gtest/gtest.h>
#include <selinux/android.h>
@@ -55,45 +58,48 @@
TEST(util, create_file) {
if (!sehandle) sehandle = selinux_android_file_context_handle();
- static const char path[] = "/data/local/tmp/util.create_file.test";
- static const char key[] = ANDROID_FILE_ENV_PREFIX "_data_local_tmp_util_create_file_test";
- EXPECT_EQ(unsetenv(key), 0);
- unlink(path);
+ TemporaryFile tf;
+ close(tf.fd);
+ EXPECT_GE(unlink(tf.path), 0);
- int fd;
+ std::string key(ANDROID_FILE_ENV_PREFIX);
+ key += tf.path;
+
+ std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; });
+
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+
uid_t uid = decode_uid("logd");
gid_t gid = decode_uid("system");
mode_t perms = S_IRWXU | S_IWGRP | S_IRGRP | S_IROTH;
static const char context[] = "u:object_r:misc_logd_file:s0";
- EXPECT_GE(fd = create_file(path, O_RDWR | O_CREAT, perms, uid, gid, context), 0);
- if (fd < 0) return;
+ EXPECT_GE(tf.fd = create_file(tf.path, O_RDWR | O_CREAT, perms, uid, gid, context), 0);
+ if (tf.fd < 0) return;
static const char hello[] = "hello world\n";
static const ssize_t len = strlen(hello);
- EXPECT_EQ(write(fd, hello, len), len);
- char buffer[sizeof(hello)];
+ EXPECT_EQ(write(tf.fd, hello, len), len);
+ char buffer[sizeof(hello) + 1];
memset(buffer, 0, sizeof(buffer));
- EXPECT_GE(lseek(fd, 0, SEEK_SET), 0);
- EXPECT_EQ(read(fd, buffer, sizeof(buffer)), len);
- EXPECT_EQ(strcmp(hello, buffer), 0);
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(android_get_control_file(path), -1);
- setenv(key, val, true);
- EXPECT_EQ(android_get_control_file(path), fd);
- close(fd);
- EXPECT_EQ(android_get_control_file(path), -1);
- EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_GE(lseek(tf.fd, 0, SEEK_SET), 0);
+ EXPECT_EQ(read(tf.fd, buffer, sizeof(buffer)), len);
+ EXPECT_EQ(std::string(hello), buffer);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), tf.fd);
+ close(tf.fd);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
struct stat st;
- EXPECT_EQ(stat(path, &st), 0);
+ EXPECT_EQ(stat(tf.path, &st), 0);
EXPECT_EQ(st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), perms);
EXPECT_EQ(st.st_uid, uid);
EXPECT_EQ(st.st_gid, gid);
security_context_t con;
- EXPECT_GE(getfilecon(path, &con), 0);
+ EXPECT_GE(getfilecon(tf.path, &con), 0);
EXPECT_NE(con, static_cast<security_context_t>(NULL));
if (con) {
EXPECT_EQ(context, std::string(con));
}
freecon(con);
- EXPECT_EQ(unlink(path), 0);
+ EXPECT_EQ(unlink(tf.path), 0);
}
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index acb963c..2386bf8 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -20,12 +20,14 @@
#include <android-base/unique_fd.h>
namespace android {
+namespace fuse {
-bool FuseBridgeLoop::Start(
- int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoop::Callback* callback) {
+bool StartFuseBridgeLoop(
+ int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoopCallback* callback) {
base::unique_fd dev_fd(raw_dev_fd);
base::unique_fd proxy_fd(raw_proxy_fd);
- fuse::FuseBuffer buffer;
+ FuseBuffer buffer;
+ size_t open_count = 0;
LOG(DEBUG) << "Start fuse loop.";
while (true) {
@@ -71,18 +73,29 @@
return false;
}
- if (opcode == FUSE_INIT) {
- callback->OnMount();
+ switch (opcode) {
+ case FUSE_INIT:
+ callback->OnMount();
+ break;
+ case FUSE_OPEN:
+ if (buffer.response.header.error == fuse::kFuseSuccess) {
+ open_count++;
+ }
+ break;
+ case FUSE_RELEASE:
+ if (open_count != 0) {
+ open_count--;
+ } else {
+ LOG(WARNING) << "Unexpected FUSE_RELEASE before opening a file.";
+ break;
+ }
+ if (open_count == 0) {
+ return true;
+ }
+ break;
}
}
}
-namespace fuse {
-
-bool StartFuseBridgeLoop(
- int raw_dev_fd, int raw_proxy_fd, FuseBridgeLoopCallback* callback) {
- return FuseBridgeLoop().Start(raw_dev_fd, raw_proxy_fd, callback);
-}
-
} // namespace fuse
} // namespace android
diff --git a/libappfuse/include/libappfuse/FuseBridgeLoop.h b/libappfuse/include/libappfuse/FuseBridgeLoop.h
index 38043bc..1f71cf2 100644
--- a/libappfuse/include/libappfuse/FuseBridgeLoop.h
+++ b/libappfuse/include/libappfuse/FuseBridgeLoop.h
@@ -20,23 +20,14 @@
#include "libappfuse/FuseBuffer.h"
namespace android {
-
-// TODO: Remove the class after switching to StartFuseBridgeLoop in the
-// framework code.
-class FuseBridgeLoop final {
- public:
- class Callback {
- public:
- virtual void OnMount() = 0;
- virtual ~Callback() = default;
- };
-
- bool Start(int dev_fd, int proxy_fd, Callback* callback);
-};
-
namespace fuse {
-class FuseBridgeLoopCallback : public FuseBridgeLoop::Callback {};
+class FuseBridgeLoopCallback {
+ public:
+ virtual void OnMount() = 0;
+ virtual ~FuseBridgeLoopCallback() = default;
+};
+
bool StartFuseBridgeLoop(
int dev_fd, int proxy_fd, FuseBridgeLoopCallback* callback);
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index bd503eb..e74d9e7 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -200,11 +200,16 @@
TEST_F(FuseBridgeLoopTest, Proxy) {
CheckProxy(FUSE_LOOKUP);
CheckProxy(FUSE_GETATTR);
- CheckProxy(FUSE_OPEN);
CheckProxy(FUSE_READ);
CheckProxy(FUSE_WRITE);
- CheckProxy(FUSE_RELEASE);
CheckProxy(FUSE_FSYNC);
+
+ // Invoke FUSE_OPEN and FUSE_RELEASE at last as the loop will exit when all files are closed.
+ CheckProxy(FUSE_OPEN);
+ CheckProxy(FUSE_RELEASE);
+
+ // Ensure the loop exits.
+ Close();
}
} // namespace fuse
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index f7b497d..39f8aba 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -18,6 +18,7 @@
// they correspond to features not used by our host development tools
// which are also hard or even impossible to port to native Win32
libcutils_nonwindows_sources = [
+ "android_get_control_file.cpp",
"fs.c",
"multiuser.c",
"socket_inaddr_any_server_unix.c",
@@ -34,7 +35,6 @@
host_supported: true,
srcs: [
"config_utils.c",
- "files.cpp",
"fs_config.c",
"canned_fs_config.c",
"hashmap.c",
diff --git a/include/cutils/files.h b/libcutils/android_get_control_env.h
similarity index 63%
copy from include/cutils/files.h
copy to libcutils/android_get_control_env.h
index 0210e30..638c831 100644
--- a/include/cutils/files.h
+++ b/libcutils/android_get_control_env.h
@@ -14,24 +14,20 @@
* limitations under the License.
*/
-#ifndef __CUTILS_FILES_H
-#define __CUTILS_FILES_H
+#ifndef __CUTILS_ANDROID_GET_CONTROL_ENV_H
+#define __CUTILS_ANDROID_GET_CONTROL_ENV_H
-#define ANDROID_FILE_ENV_PREFIX "ANDROID_FILE_"
+/* To declare library function hidden and internal */
+#define LIBCUTILS_HIDDEN __attribute__((visibility("hidden")))
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * android_get_control_file - simple helper function to get the file
- * descriptor of our init-managed file. `path' is the filename path as
- * given in init.rc. Returns -1 on error.
- */
-int android_get_control_file(const char* path);
-
+LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
+ const char* name);
#ifdef __cplusplus
}
#endif
-#endif /* __CUTILS_FILES_H */
+#endif /* __CUTILS_ANDROID_GET_CONTROL_ENV_H */
diff --git a/libcutils/files.cpp b/libcutils/android_get_control_file.cpp
similarity index 74%
rename from libcutils/files.cpp
rename to libcutils/android_get_control_file.cpp
index bf15b42..780d9f1 100644
--- a/libcutils/files.cpp
+++ b/libcutils/android_get_control_file.cpp
@@ -25,11 +25,6 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-// This file contains files implementation that can be shared between
-// platforms as long as the correct headers are included.
-#define _GNU_SOURCE 1 // for asprintf
-
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -41,17 +36,20 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
-#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define
-#define TEMP_FAILURE_RETRY(exp) (exp)
+#include "android_get_control_env.h"
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation
#endif
-int android_get_control_file(const char* path) {
- if (!path) return -1;
+LIBCUTILS_HIDDEN int __android_get_control_from_env(const char* prefix,
+ const char* name) {
+ if (!prefix || !name) return -1;
char *key = NULL;
- if (asprintf(&key, ANDROID_FILE_ENV_PREFIX "%s", path) < 0) return -1;
+ if (asprintf(&key, "%s%s", prefix, name) < 0) return -1;
if (!key) return -1;
char *cp = key;
@@ -70,29 +68,33 @@
// validity checking
if ((fd < 0) || (fd > INT_MAX)) return -1;
-#if defined(_SC_OPEN_MAX)
- if (fd >= sysconf(_SC_OPEN_MAX)) return -1;
-#elif defined(OPEN_MAX)
- if (fd >= OPEN_MAX) return -1;
-#elif defined(_POSIX_OPEN_MAX)
- if (fd >= _POSIX_OPEN_MAX) return -1;
-#endif
-#if defined(F_GETFD)
+ // Since we are inheriting an fd, it could legitimately exceed _SC_OPEN_MAX
+
+ // Still open?
+#if defined(F_GETFD) // Lowest overhead
if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
-#elif defined(F_GETFL)
+#elif defined(F_GETFL) // Alternate lowest overhead
if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
-#else
+#else // Hail Mary pass
struct stat s;
if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
#endif
+ return static_cast<int>(fd);
+}
+
+int android_get_control_file(const char* path) {
+ int fd = __android_get_control_from_env(ANDROID_FILE_ENV_PREFIX, path);
+
#if defined(__linux__)
+ // Find file path from /proc and make sure it is correct
char *proc = NULL;
- if (asprintf(&proc, "/proc/self/fd/%ld", fd) < 0) return -1;
+ if (asprintf(&proc, "/proc/self/fd/%d", fd) < 0) return -1;
if (!proc) return -1;
size_t len = strlen(path);
+ // readlink() does not guarantee a nul byte, len+2 so we catch truncation.
char *buf = static_cast<char *>(calloc(1, len + 2));
if (!buf) {
free(proc);
@@ -104,8 +106,8 @@
free(buf);
if (ret < 0) return -1;
if (cmp != 0) return -1;
+ // It is what we think it is
#endif
- // It is what we think it is
- return static_cast<int>(fd);
+ return fd;
}
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index 9d823cf..4bad28a 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -24,7 +24,7 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/files.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/klog.h>
static int klog_level = KLOG_DEFAULT_LEVEL;
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
index 63761a2..23a447b 100644
--- a/libcutils/sockets.cpp
+++ b/libcutils/sockets.cpp
@@ -28,33 +28,9 @@
// This file contains socket implementation that can be shared between
// platforms as long as the correct headers are included.
-#define _GNU_SOURCE 1 // For asprintf
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#if !defined(_WIN32)
-#include <netinet/in.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#if !defined(_WIN32)
-#include <sys/un.h>
-#endif
-#include <unistd.h>
-
-#include <string>
#include <cutils/sockets.h>
-#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define
-#define TEMP_FAILURE_RETRY(exp) (exp)
-#endif
-
int socket_get_local_port(cutils_socket_t sock) {
sockaddr_storage addr;
socklen_t addr_size = sizeof(addr);
@@ -65,58 +41,3 @@
}
return -1;
}
-
-int android_get_control_socket(const char* name) {
- char *key = NULL;
- if (asprintf(&key, ANDROID_SOCKET_ENV_PREFIX "%s", name) < 0) return -1;
- if (!key) return -1;
-
- char *cp = key;
- while (*cp) {
- if (!isalnum(*cp)) *cp = '_';
- ++cp;
- }
-
- const char* val = getenv(key);
- free(key);
- if (!val) return -1;
-
- errno = 0;
- long fd = strtol(val, NULL, 10);
- if (errno) return -1;
-
- // validity checking
- if ((fd < 0) || (fd > INT_MAX)) return -1;
-#if defined(_SC_OPEN_MAX)
- if (fd >= sysconf(_SC_OPEN_MAX)) return -1;
-#elif defined(OPEN_MAX)
- if (fd >= OPEN_MAX) return -1;
-#elif defined(_POSIX_OPEN_MAX)
- if (fd >= _POSIX_OPEN_MAX) return -1;
-#endif
-
-#if defined(F_GETFD)
- if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
-#elif defined(F_GETFL)
- if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
-#else
- struct stat s;
- if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
-#endif
-
-#if !defined(_WIN32)
- struct sockaddr_un addr;
- socklen_t addrlen = sizeof(addr);
- int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen));
- if (ret < 0) return -1;
- char *path = NULL;
- if (asprintf(&path, ANDROID_SOCKET_DIR"/%s", name) < 0) return -1;
- if (!path) return -1;
- int cmp = strcmp(addr.sun_path, path);
- free(path);
- if (cmp != 0) return -1;
-#endif
-
- // It is what we think it is
- return static_cast<int>(fd);
-}
diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp
index 3545403..5a14a5c 100644
--- a/libcutils/sockets_unix.cpp
+++ b/libcutils/sockets_unix.cpp
@@ -16,13 +16,25 @@
#define LOG_TAG "socket-unix"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <time.h>
#include <unistd.h>
#include <android/log.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
+#include "android_get_control_env.h"
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) (exp) // KISS implementation
+#endif
+
#if defined(__ANDROID__)
/* For the socket trust (credentials) check */
#include <private/android_filesystem_config.h>
@@ -80,3 +92,24 @@
return writev(sock, iovec_buffers, num_buffers);
}
+
+int android_get_control_socket(const char* name) {
+ int fd = __android_get_control_from_env(ANDROID_SOCKET_ENV_PREFIX, name);
+
+ if (fd < 0) return fd;
+
+ // Compare to UNIX domain socket name, must match!
+ struct sockaddr_un addr;
+ socklen_t addrlen = sizeof(addr);
+ int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen));
+ if (ret < 0) return -1;
+ char *path = NULL;
+ if (asprintf(&path, ANDROID_SOCKET_DIR "/%s", name) < 0) return -1;
+ if (!path) return -1;
+ int cmp = strcmp(addr.sun_path, path);
+ free(path);
+ if (cmp != 0) return -1;
+
+ // It is what we think it is
+ return fd;
+}
diff --git a/libcutils/sockets_windows.cpp b/libcutils/sockets_windows.cpp
index ed6b1a7..3064c70 100644
--- a/libcutils/sockets_windows.cpp
+++ b/libcutils/sockets_windows.cpp
@@ -84,3 +84,7 @@
return -1;
}
+
+int android_get_control_socket(const char* name) {
+ return -1;
+}
diff --git a/libcutils/tests/Android.bp b/libcutils/tests/Android.bp
index bd35412..72e2eac 100644
--- a/libcutils/tests/Android.bp
+++ b/libcutils/tests/Android.bp
@@ -14,7 +14,7 @@
cc_defaults {
name: "libcutils_test_default",
- srcs: ["sockets_test.cpp", "files_test.cpp"],
+ srcs: ["sockets_test.cpp"],
target: {
android: {
@@ -28,7 +28,11 @@
},
not_windows: {
- srcs: ["test_str_parms.cpp"],
+ srcs: [
+ "test_str_parms.cpp",
+ "android_get_control_socket_test.cpp",
+ "android_get_control_file_test.cpp"
+ ],
},
},
diff --git a/libcutils/tests/android_get_control_file_test.cpp b/libcutils/tests/android_get_control_file_test.cpp
new file mode 100644
index 0000000..6c6fd2a
--- /dev/null
+++ b/libcutils/tests/android_get_control_file_test.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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 <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <string>
+
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <cutils/android_get_control_file.h>
+#include <gtest/gtest.h>
+
+TEST(FilesTest, android_get_control_file) {
+ TemporaryFile tf;
+ ASSERT_GE(tf.fd, 0);
+
+ std::string key(ANDROID_FILE_ENV_PREFIX);
+ key += tf.path;
+
+ std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; });
+
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+
+ EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0);
+
+ EXPECT_EQ(android_get_control_file(tf.path), tf.fd);
+ close(tf.fd);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+ EXPECT_EQ(unsetenv(key.c_str()), 0);
+ EXPECT_EQ(android_get_control_file(tf.path), -1);
+}
diff --git a/libcutils/tests/android_get_control_socket_test.cpp b/libcutils/tests/android_get_control_socket_test.cpp
new file mode 100644
index 0000000..e586748
--- /dev/null
+++ b/libcutils/tests/android_get_control_socket_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <time.h>
+
+#include <cutils/sockets.h>
+#include <gtest/gtest.h>
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 0
+#endif
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+
+TEST(SocketsTest, android_get_control_socket) {
+ static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
+ static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
+
+ EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ int fd;
+ ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
+#ifdef F_GETFL
+ int flags;
+ ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
+ ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
+#endif
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
+ unlink(addr.sun_path);
+
+ EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+
+ char val[32];
+ snprintf(val, sizeof(val), "%d", fd);
+ EXPECT_EQ(setenv(key, val, true), 0);
+
+ EXPECT_EQ(android_get_control_socket(name), fd);
+ socket_close(fd);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+ EXPECT_EQ(unlink(addr.sun_path), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+ EXPECT_EQ(unsetenv(key), 0);
+ EXPECT_EQ(android_get_control_socket(name), -1);
+}
diff --git a/libcutils/tests/files_test.cpp b/libcutils/tests/files_test.cpp
deleted file mode 100644
index 1a7d673..0000000
--- a/libcutils/tests/files_test.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include <cutils/files.h>
-#include <gtest/gtest.h>
-
-TEST(FilesTest, android_get_control_file) {
- static const char key[] = ANDROID_FILE_ENV_PREFIX "_dev_kmsg";
- static const char name[] = "/dev/kmsg";
-
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-
- int fd;
- ASSERT_GE(fd = open(name, O_RDONLY | O_CLOEXEC), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(setenv(key, val, true), 0);
-
- EXPECT_EQ(android_get_control_file(name), fd);
- close(fd);
- EXPECT_EQ(android_get_control_file(name), -1);
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_file(name), -1);
-}
diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp
index adfbf4a..0441fb6 100644
--- a/libcutils/tests/sockets_test.cpp
+++ b/libcutils/tests/sockets_test.cpp
@@ -18,11 +18,9 @@
// IPv6 capabilities. These tests assume that no UDP packets are lost, which
// should be the case for loopback communication, but is not guaranteed.
-#include <stdio.h>
-#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/un.h>
#include <time.h>
#include <cutils/sockets.h>
@@ -189,49 +187,3 @@
TEST(SocketsTest, TestSocketSendBuffersFailure) {
EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
}
-
-#ifndef SOCK_NONBLOCK
-#define SOCK_NONBLOCK 0
-#endif
-
-#ifndef SOCK_CLOEXEC
-#define SOCK_CLOEXEC 0
-#endif
-
-TEST(SocketsTest, android_get_control_socket) {
- static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
- static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
-
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- int fd;
- ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
-#ifdef F_GETFL
- int flags;
- ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
- ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
-#endif
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
- unlink(addr.sun_path);
-
- EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-
- char val[32];
- snprintf(val, sizeof(val), "%d", fd);
- EXPECT_EQ(setenv(key, val, true), 0);
-
- EXPECT_EQ(android_get_control_socket(name), fd);
- socket_close(fd);
- EXPECT_EQ(android_get_control_socket(name), -1);
- EXPECT_EQ(unlink(addr.sun_path), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
- EXPECT_EQ(unsetenv(key), 0);
- EXPECT_EQ(android_get_control_socket(name), -1);
-}
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 4ff7e01..da80e36 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -1055,6 +1055,7 @@
outRemaining--;
/* pretend we ate all the data to prevent log stutter */
inCount = 0;
+ if (result > 0) result = 0;
}
/* eat the silly terminating '\n' */
@@ -1078,7 +1079,7 @@
entry->message = messageBuf;
- return 0;
+ return result;
}
/*
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 9c09523..70c7a48 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -328,6 +328,9 @@
EXPECT_TRUE(NULL != logformat);
AndroidLogEntry entry;
char msgBuf[1024];
+ if (length != total) {
+ fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n");
+ }
int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
&log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index d0c693d..41f2280 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -81,6 +81,7 @@
static size_t g_maxCount;
static size_t g_printCount;
static bool g_printItAnyways;
+static bool g_debug;
enum helpType {
HELP_FALSE,
@@ -188,7 +189,7 @@
} else {
err = android_log_processLogBuffer(&buf->entry_v1, &entry);
}
- if (err < 0) {
+ if ((err < 0) && !g_debug) {
goto error;
}
@@ -619,6 +620,7 @@
int option_index = 0;
// list of long-argument only strings for later comparison
static const char pid_str[] = "pid";
+ static const char debug_str[] = "debug";
static const char id_str[] = "id";
static const char wrap_str[] = "wrap";
static const char print_str[] = "print";
@@ -627,6 +629,7 @@
{ "buffer", required_argument, NULL, 'b' },
{ "buffer-size", optional_argument, NULL, 'g' },
{ "clear", no_argument, NULL, 'c' },
+ { debug_str, no_argument, NULL, 0 },
{ "dividers", no_argument, NULL, 'D' },
{ "file", required_argument, NULL, 'f' },
{ "format", required_argument, NULL, 'v' },
@@ -691,6 +694,10 @@
g_printItAnyways = true;
break;
}
+ if (long_options[option_index].name == debug_str) {
+ g_debug = true;
+ break;
+ }
if (long_options[option_index].name == id_str) {
setId = optarg && optarg[0] ? optarg : NULL;
break;
diff --git a/logd/main.cpp b/logd/main.cpp
index d698976..7550c41 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -37,9 +37,9 @@
#include <memory>
#include <android-base/macros.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
-#include <cutils/files.h>
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
#include <packagelistparser/packagelistparser.h>
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 4e766bb..fb53178 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -293,11 +293,8 @@
mount none /mnt/runtime/default /storage slave bind rec
# Make sure /sys/kernel/debug (if present) is labeled properly
- restorecon_recursive /sys/kernel/debug
-
- # On systems with tracefs, tracing is a separate mount, so make sure
- # it too is correctly labeled
- restorecon_recursive /sys/kernel/debug/tracing
+ # Note that tracefs may be mounted under debug, so we need to cross filesystems
+ restorecon --recursive --cross-filesystems /sys/kernel/debug
# We chown/chmod /cache again so because mount is run as root + defaults
chown system cache /cache
@@ -462,7 +459,7 @@
init_user0
# Set SELinux security contexts on upgrade or policy update.
- restorecon_recursive /data
+ restorecon --recursive --skip-ce /data
# Check any timezone data in /data is newer than the copy in /system, delete if not.
exec - system system -- /system/bin/tzdatacheck /system/usr/share/zoneinfo /data/misc/zoneinfo