Merge "Remove dead code."
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/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 612885b..857bcb2 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -257,13 +257,13 @@
static int draw_text(const char *str, int x, int y)
{
- int str_len_px = gr_measure(str);
+ int str_len_px = gr_measure(gr_sys_font(), str);
if (x < 0)
x = (gr_fb_width() - str_len_px) / 2;
if (y < 0)
y = (gr_fb_height() - char_height) / 2;
- gr_text(x, y, str, 0);
+ gr_text(gr_sys_font(), x, y, str, 0);
return y + char_height;
}
@@ -364,7 +364,7 @@
}
gr_init();
- gr_font_size(&char_width, &char_height);
+ gr_font_size(gr_sys_font(), &char_width, &char_height);
#ifndef CHARGER_DISABLE_INIT_BLANK
gr_fb_blank(true);
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/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index fc845a4..54946fc 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -195,7 +195,8 @@
* Uncompress and write an entry to an open file identified by |fd|.
* |entry->uncompressed_length| bytes will be written to the file at
* its current offset, and the file will be truncated at the end of
- * the uncompressed data.
+ * the uncompressed data (no truncation if |fd| references a block
+ * device).
*
* Returns 0 on success and negative values on failure.
*/
diff --git a/init/action.cpp b/init/action.cpp
index ccc18cf..0ea7e14 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -105,7 +105,10 @@
}
void Action::ExecuteOneCommand(std::size_t command) const {
- ExecuteCommand(commands_[command]);
+ // We need a copy here since some Command execution may result in
+ // changing commands_ vector by importing .rc files through parser
+ Command cmd = commands_[command];
+ ExecuteCommand(cmd);
}
void Action::ExecuteAllCommands() const {
@@ -118,14 +121,16 @@
Timer t;
int result = command.InvokeFunc();
- // TODO: this should probably be changed to "if (failed || took a long time)"...
- if (android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
+ double duration_ms = t.duration() * 1000;
+ // Any action longer than 50ms will be warned to user as slow operation
+ if (duration_ms > 50.0 ||
+ android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
std::string trigger_name = BuildTriggersString();
std::string cmd_str = command.BuildCommandString();
std::string source = command.BuildSourceString();
LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << source
- << " returned " << result << " took " << t.duration() << "s";
+ << " returned " << result << " took " << duration_ms << "ms.";
}
}
@@ -152,6 +157,11 @@
bool Action::InitTriggers(const std::vector<std::string>& args, std::string* err) {
const static std::string prop_str("property:");
for (std::size_t i = 0; i < args.size(); ++i) {
+ if (args[i].empty()) {
+ *err = "empty trigger is not valid";
+ return false;
+ }
+
if (i % 2) {
if (args[i] != "&&") {
*err = "&& is the only symbol allowed to concatenate actions";
@@ -181,7 +191,11 @@
bool Action::InitSingleTrigger(const std::string& trigger) {
std::vector<std::string> name_vector{trigger};
std::string err;
- return InitTriggers(name_vector, &err);
+ bool ret = InitTriggers(name_vector, &err);
+ if (!ret) {
+ LOG(ERROR) << "InitSingleTrigger failed due to: " << err;
+ }
+ return ret;
}
// This function checks that all property triggers are satisfied, that is
@@ -247,9 +261,7 @@
result += event_trigger_;
result += ' ';
}
- if (!result.empty()) {
- result.pop_back();
- }
+ result.pop_back();
return result;
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index ebdc8c9..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>
@@ -589,9 +590,9 @@
for (na = args.size() - 1; na > 1; --na) {
if (args[na] == "--early") {
- path_arg_end = na;
- queue_event = false;
- mount_mode = MOUNT_MODE_EARLY;
+ path_arg_end = na;
+ queue_event = false;
+ mount_mode = MOUNT_MODE_EARLY;
} else if (args[na] == "--late") {
path_arg_end = na;
import_rc = false;
@@ -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 5098fb3..2db24b7 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -111,13 +111,18 @@
return -ENOMEM;
node->dp.name = strdup(name);
- if (!node->dp.name)
+ if (!node->dp.name) {
+ free(node);
return -ENOMEM;
+ }
if (attr) {
node->dp.attr = strdup(attr);
- if (!node->dp.attr)
+ if (!node->dp.attr) {
+ free(node->dp.name);
+ free(node);
return -ENOMEM;
+ }
}
node->dp.perm = perm;
@@ -185,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/ueventd.cpp b/init/ueventd.cpp
index e7794ec..361b925 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -95,7 +95,6 @@
int prefix = 0;
int wildcard = 0;
char *endptr;
- char *tmp = 0;
if (nargs == 0)
return;
@@ -129,14 +128,12 @@
perm = strtol(args[1], &endptr, 8);
if (!endptr || *endptr != '\0') {
LOG(ERROR) << "invalid mode '" << args[1] << "'";
- free(tmp);
return;
}
struct passwd* pwd = getpwnam(args[2]);
if (!pwd) {
LOG(ERROR) << "invalid uid '" << args[2] << "'";
- free(tmp);
return;
}
uid = pwd->pw_uid;
@@ -144,11 +141,17 @@
struct group* grp = getgrnam(args[3]);
if (!grp) {
LOG(ERROR) << "invalid gid '" << args[3] << "'";
- free(tmp);
return;
}
gid = grp->gr_gid;
- add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard);
- free(tmp);
+ if (add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard) != 0) {
+ PLOG(ERROR) << "add_dev_perms(name=" << name <<
+ ", attr=" << attr <<
+ ", perm=" << std::oct << perm << std::dec <<
+ ", uid=" << uid << ", gid=" << gid <<
+ ", prefix=" << prefix << ", wildcard=" << wildcard <<
+ ")";
+ return;
+ }
}
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/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 74fe756..3ade31c 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -118,23 +118,18 @@
return;
}
- // We limit ourselves to 15 because we don't handle BATCH_FORGET yet
- size_t response_size = sizeof(fuse_init_out);
+ // We limit ourselves to minor=15 because we don't handle BATCH_FORGET yet.
+ // Thus we need to use FUSE_COMPAT_22_INIT_OUT_SIZE.
#if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
// FUSE_KERNEL_VERSION >= 23.
-
- // If the kernel only works on minor revs older than or equal to 22,
- // then use the older structure size since this code only uses the 7.22
- // version of the structure.
- if (minor <= 22) {
- response_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
- }
+ const size_t response_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
+#else
+ const size_t response_size = sizeof(fuse_init_out);
#endif
response.Reset(response_size, kFuseSuccess, unique);
fuse_init_out* const out = &response.init_out;
out->major = FUSE_KERNEL_VERSION;
- // We limit ourselves to 15 because we don't handle BATCH_FORGET yet.
out->minor = std::min(minor, 15u);
out->max_readahead = max_readahead;
out->flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
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/libappfuse/tests/FuseBufferTest.cc b/libappfuse/tests/FuseBufferTest.cc
index 17f1306..c822135 100644
--- a/libappfuse/tests/FuseBufferTest.cc
+++ b/libappfuse/tests/FuseBufferTest.cc
@@ -164,7 +164,7 @@
buffer.HandleInit();
- ASSERT_EQ(sizeof(fuse_out_header) + sizeof(fuse_init_out),
+ ASSERT_EQ(sizeof(fuse_out_header) + FUSE_COMPAT_22_INIT_OUT_SIZE,
buffer.response.header.len);
EXPECT_EQ(kFuseSuccess, buffer.response.header.error);
EXPECT_EQ(static_cast<unsigned int>(FUSE_KERNEL_VERSION),
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 fb942a1..da80e36 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -632,8 +632,8 @@
size_t len;
int64_t lval;
- if (eventDataLen < 1)
- return -1;
+ if (eventDataLen < 1) return -1;
+
type = *eventData++;
eventDataLen--;
@@ -729,8 +729,7 @@
{
int32_t ival;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
@@ -740,8 +739,7 @@
goto pr_lval;
case EVENT_TYPE_LONG:
/* 64-bit signed long */
- if (eventDataLen < 8)
- return -1;
+ if (eventDataLen < 8) return -1;
lval = get8LE(eventData);
eventData += 8;
eventDataLen -= 8;
@@ -761,8 +759,7 @@
uint32_t ival;
float fval;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
fval = *(float*)&ival;
eventData += 4;
@@ -783,14 +780,12 @@
{
unsigned int strLen;
- if (eventDataLen < 4)
- return -1;
+ if (eventDataLen < 4) return -1;
strLen = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
- if (eventDataLen < strLen)
- return -1;
+ if (eventDataLen < strLen) return -1;
if (cp && (strLen == 0)) {
/* reset the format if no content */
@@ -818,41 +813,32 @@
unsigned char count;
int i;
- if (eventDataLen < 1)
- return -1;
+ if (eventDataLen < 1) return -1;
count = *eventData++;
eventDataLen--;
- if (outBufLen > 0) {
- *outBuf++ = '[';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (outBufLen <= 0) goto no_room;
+
+ *outBuf++ = '[';
+ outBufLen--;
for (i = 0; i < count; i++) {
result = android_log_printBinaryEvent(&eventData, &eventDataLen,
&outBuf, &outBufLen, fmtStr, fmtLen);
- if (result != 0)
- goto bail;
+ if (result != 0) goto bail;
- if (i < count-1) {
- if (outBufLen > 0) {
- *outBuf++ = ',';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (i < (count - 1)) {
+ if (outBufLen <= 0) goto no_room;
+ *outBuf++ = ',';
+ outBufLen--;
}
}
- if (outBufLen > 0) {
- *outBuf++ = ']';
- outBufLen--;
- } else {
- goto no_room;
- }
+ if (outBufLen <= 0) goto no_room;
+
+ *outBuf++ = ']';
+ outBufLen--;
}
break;
default:
@@ -997,8 +983,7 @@
}
}
inCount = buf->len;
- if (inCount < 4)
- return -1;
+ if (inCount < 4) return -1;
tagIndex = get4LE(eventData);
eventData += 4;
inCount -= 4;
@@ -1031,16 +1016,20 @@
/*
* Format the event log data into the buffer.
*/
- char* outBuf = messageBuf;
- size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
- int result;
const char* fmtStr = NULL;
size_t fmtLen = 0;
if (descriptive_output && map) {
fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex);
}
- result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
- &outRemaining, &fmtStr, &fmtLen);
+
+ char* outBuf = messageBuf;
+ size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
+ int result = 0;
+
+ if ((inCount > 0) || fmtLen) {
+ result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
+ &outRemaining, &fmtStr, &fmtLen);
+ }
if ((result == 1) && fmtStr) {
/* We overflowed :-(, let's repaint the line w/o format dressings */
eventData = (const unsigned char*)buf->msg;
@@ -1055,18 +1044,18 @@
}
if (result < 0) {
fprintf(stderr, "Binary log entry conversion failed\n");
- return -1;
- } else if (result == 1) {
- if (outBuf > messageBuf) {
- /* leave an indicator */
- *(outBuf-1) = '!';
- } else {
- /* no room to output anything at all */
- *outBuf++ = '!';
- outRemaining--;
+ }
+ if (result) {
+ if (!outRemaining) {
+ /* make space to leave an indicator */
+ --outBuf;
+ ++outRemaining;
}
- /* pretend we ate all the data */
+ *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */
+ outRemaining--;
+ /* pretend we ate all the data to prevent log stutter */
inCount = 0;
+ if (result > 0) result = 0;
}
/* eat the silly terminating '\n' */
@@ -1090,7 +1079,7 @@
entry->message = messageBuf;
- return 0;
+ return result;
}
/*
@@ -1802,8 +1791,7 @@
outBuffer = android_log_formatLogLine(p_format, defaultBuffer,
sizeof(defaultBuffer), entry, &totalLen);
- if (!outBuffer)
- return -1;
+ if (!outBuffer) return -1;
do {
ret = write(fd, outBuffer, totalLen);
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/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index d36cc3f..e6e0276 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -781,7 +781,8 @@
// Creates a FileWriter for |fd| and prepare to write |entry| to it,
// guaranteeing that the file descriptor is valid and that there's enough
// space on the volume to write out the entry completely and that the file
- // is truncated to the correct length.
+ // is truncated to the correct length (no truncation if |fd| references a
+ // block device).
//
// Returns a valid FileWriter on success, |nullptr| if an error occurred.
static std::unique_ptr<FileWriter> Create(int fd, const ZipEntry* entry) {
@@ -814,13 +815,22 @@
}
#endif // __linux__
- result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
- if (result == -1) {
- ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
- static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ struct stat sb;
+ if (fstat(fd, &sb) == -1) {
+ ALOGW("Zip: unable to fstat file: %s", strerror(errno));
return std::unique_ptr<FileWriter>(nullptr);
}
+ // Block device doesn't support ftruncate(2).
+ if (!S_ISBLK(sb.st_mode)) {
+ result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
+ if (result == -1) {
+ ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
+ return std::unique_ptr<FileWriter>(nullptr);
+ }
+ }
+
return std::unique_ptr<FileWriter>(new FileWriter(fd, declared_length));
}
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/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 18067dc..8d7c04e 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -1255,19 +1255,25 @@
va_end(ap);
char *str = NULL;
- asprintf(&str, "I/%s ( %%d): %s%%c", tag, buffer);
+ asprintf(&str, "I/%s ( %%d):%%c%s%%c", tag, buffer);
std::string expect(str);
free(str);
int count = 0;
pid_t pid = getpid();
std::string lastMatch;
+ int maxMatch = 1;
while (fgets(buffer, sizeof(buffer), fp)) {
+ char space;
char newline;
int p;
- int ret = sscanf(buffer, expect.c_str(), &p, &newline);
- if ((2 == ret) && (p == pid) && (newline == '\n')) ++count;
- else if ((1 == ret) && (p == pid) && (count == 0)) lastMatch = buffer;
+ int ret = sscanf(buffer, expect.c_str(), &p, &space, &newline);
+ if ((ret == 3) && (p == pid) && (space == ' ') && (newline == '\n')) {
+ ++count;
+ } else if ((ret >= maxMatch) && (p == pid) && (count == 0)) {
+ lastMatch = buffer;
+ maxMatch = ret;
+ }
}
pclose(fp);
@@ -1395,4 +1401,10 @@
}
}
+ {
+ static const struct tag sync = { 27501, "notification_panel_hidden" };
+ android_log_event_context ctx(sync.tagNo);
+ ctx.write();
+ EXPECT_TRUE(End_to_End(sync.tagStr, ""));
+ }
}
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
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index d4c51fd..9393846 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -1262,12 +1262,9 @@
#if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
/* FUSE_KERNEL_VERSION >= 23. */
- /* If the kernel only works on minor revs older than or equal to 22,
- * then use the older structure size since this code only uses the 7.22
- * version of the structure. */
- if (req->minor <= 22) {
- fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
- }
+ /* Since we return minor version 15, the kernel does not accept the latest
+ * fuse_init_out size. We need to use FUSE_COMPAT_22_INIT_OUT_SIZE always.*/
+ fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
#endif
out.major = FUSE_KERNEL_VERSION;
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 27ea9e8..d7047e2 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -741,6 +741,7 @@
exit(1);
}
}
+ free(img);
}
return 0;
}