Merge changes from topic "health_cleanup" into stage-aosp-master
* changes:
healthd: add missing libbatteryservice_headers dep
storaged: fix headers.
diff --git a/adb/Android.bp b/adb/Android.bp
index c0e4c57..2a9a579 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -299,6 +299,10 @@
"libqemu_pipe",
"libbase",
],
+
+ export_include_dirs: [
+ "daemon/include",
+ ],
}
cc_binary {
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 46c3f58..10b6090 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -589,7 +589,7 @@
int rc = perform_usb_transfer(h, info, std::move(lock));
LOG(DEBUG) << "usb_write(" << len << ") = " << rc;
- return rc;
+ return info->transfer->actual_length;
}
int usb_read(usb_handle* h, void* d, int len) {
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
index 76f5d78..869e858 100644
--- a/adb/client/usb_linux.cpp
+++ b/adb/client/usb_linux.cpp
@@ -418,11 +418,11 @@
if (h->zero_mask && !(len & h->zero_mask)) {
// If we need 0-markers and our transfer is an even multiple of the packet size,
// then send a zero marker.
- return usb_bulk_write(h, _data, 0);
+ return usb_bulk_write(h, _data, 0) == 0 ? n : -1;
}
D("-- usb_write --");
- return 0;
+ return n;
}
int usb_read(usb_handle *h, void *_data, int len)
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
index 8a95a19..49baf36 100644
--- a/adb/client/usb_osx.cpp
+++ b/adb/client/usb_osx.cpp
@@ -497,8 +497,8 @@
}
}
- if (0 == result)
- return 0;
+ if (!result)
+ return len;
LOG(ERROR) << "usb_write failed with status: " << std::hex << result;
return -1;
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
index 026703d..e928377 100644
--- a/adb/client/usb_windows.cpp
+++ b/adb/client/usb_windows.cpp
@@ -365,7 +365,7 @@
}
}
- return 0;
+ return written;
fail:
// Any failure should cause us to kick the device instead of leaving it a
diff --git a/adb/daemon/usb.h b/adb/daemon/include/adbd/usb.h
similarity index 92%
rename from adb/daemon/usb.h
rename to adb/daemon/include/adbd/usb.h
index 15a7f65..7905d9d 100644
--- a/adb/daemon/usb.h
+++ b/adb/daemon/include/adbd/usb.h
@@ -19,6 +19,7 @@
#include <atomic>
#include <condition_variable>
#include <mutex>
+#include <vector>
#include <asyncio/AsyncIO.h>
@@ -54,5 +55,9 @@
// read and write threads.
struct aio_block read_aiob;
struct aio_block write_aiob;
+
+ bool reads_zero_packets;
+ size_t io_size;
};
+usb_handle *create_usb_handle(unsigned num_bufs, unsigned io_size);
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 51ad5f5..c79d6fc 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -41,7 +41,7 @@
#include <android-base/properties.h>
#include "adb.h"
-#include "daemon/usb.h"
+#include "adbd/usb.h"
#include "transport.h"
using namespace std::chrono_literals;
@@ -53,7 +53,7 @@
#define USB_FFS_BULK_SIZE 16384
// Number of buffers needed to fit MAX_PAYLOAD, with an extra for ZLPs.
-#define USB_FFS_NUM_BUFS ((MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1)
+#define USB_FFS_NUM_BUFS ((4 * MAX_PAYLOAD / USB_FFS_BULK_SIZE) + 1)
#define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x)
@@ -226,16 +226,16 @@
},
};
-static void aio_block_init(aio_block* aiob) {
- aiob->iocb.resize(USB_FFS_NUM_BUFS);
- aiob->iocbs.resize(USB_FFS_NUM_BUFS);
- aiob->events.resize(USB_FFS_NUM_BUFS);
+static void aio_block_init(aio_block* aiob, unsigned num_bufs) {
+ aiob->iocb.resize(num_bufs);
+ aiob->iocbs.resize(num_bufs);
+ aiob->events.resize(num_bufs);
aiob->num_submitted = 0;
- for (unsigned i = 0; i < USB_FFS_NUM_BUFS; i++) {
+ for (unsigned i = 0; i < num_bufs; i++) {
aiob->iocbs[i] = &aiob->iocb[i];
}
memset(&aiob->ctx, 0, sizeof(aiob->ctx));
- if (io_setup(USB_FFS_NUM_BUFS, &aiob->ctx)) {
+ if (io_setup(num_bufs, &aiob->ctx)) {
D("[ aio: got error on io_setup (%d) ]", errno);
}
}
@@ -250,7 +250,7 @@
}
}
-bool init_functionfs(struct usb_handle* h) {
+static bool init_functionfs(struct usb_handle* h) {
LOG(INFO) << "initializing functionfs";
ssize_t ret;
@@ -318,6 +318,7 @@
h->read_aiob.fd = h->bulk_out;
h->write_aiob.fd = h->bulk_in;
+ h->reads_zero_packets = true;
return true;
err:
@@ -336,9 +337,7 @@
return false;
}
-static void usb_ffs_open_thread(void* x) {
- struct usb_handle* usb = (struct usb_handle*)x;
-
+static void usb_ffs_open_thread(usb_handle *usb) {
adb_thread_setname("usb ffs open");
while (true) {
@@ -370,6 +369,7 @@
D("about to write (fd=%d, len=%d)", h->bulk_in, len);
const char* buf = static_cast<const char*>(data);
+ int orig_len = len;
while (len > 0) {
int write_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_write(h->bulk_in, buf, write_len);
@@ -382,13 +382,14 @@
}
D("[ done fd=%d ]", h->bulk_in);
- return 0;
+ return orig_len;
}
static int usb_ffs_read(usb_handle* h, void* data, int len) {
D("about to read (fd=%d, len=%d)", h->bulk_out, len);
char* buf = static_cast<char*>(data);
+ int orig_len = len;
while (len > 0) {
int read_len = std::min(USB_FFS_BULK_SIZE, len);
int n = adb_read(h->bulk_out, buf, read_len);
@@ -401,14 +402,14 @@
}
D("[ done fd=%d ]", h->bulk_out);
- return 0;
+ return orig_len;
}
static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
aio_block* aiob = read ? &h->read_aiob : &h->write_aiob;
bool zero_packet = false;
- int num_bufs = len / USB_FFS_BULK_SIZE + (len % USB_FFS_BULK_SIZE == 0 ? 0 : 1);
+ int num_bufs = len / h->io_size + (len % h->io_size == 0 ? 0 : 1);
const char* cur_data = reinterpret_cast<const char*>(data);
int packet_size = getMaxPacketSize(aiob->fd);
@@ -418,7 +419,7 @@
}
for (int i = 0; i < num_bufs; i++) {
- int buf_len = std::min(len, USB_FFS_BULK_SIZE);
+ int buf_len = std::min(len, static_cast<int>(h->io_size));
io_prep(&aiob->iocb[i], aiob->fd, cur_data, buf_len, 0, read);
len -= buf_len;
@@ -427,7 +428,7 @@
if (len == 0 && buf_len % packet_size == 0 && read) {
// adb does not expect the device to send a zero packet after data transfer,
// but the host *does* send a zero packet for the device to read.
- zero_packet = true;
+ zero_packet = h->reads_zero_packets;
}
}
if (zero_packet) {
@@ -449,6 +450,7 @@
if (num_bufs == 1 && aiob->events[0].res == -EINTR) {
continue;
}
+ int ret = 0;
for (int i = 0; i < num_bufs; i++) {
if (aiob->events[i].res < 0) {
errno = -aiob->events[i].res;
@@ -456,8 +458,9 @@
<< " total bufs " << num_bufs;
return -1;
}
+ ret += aiob->events[i].res;
}
- return 0;
+ return ret;
}
}
@@ -505,9 +508,7 @@
h->notify.notify_one();
}
-static void usb_ffs_init() {
- D("[ usb_init - using FunctionFS ]");
-
+usb_handle *create_usb_handle(unsigned num_bufs, unsigned io_size) {
usb_handle* h = new usb_handle();
if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) {
@@ -518,20 +519,21 @@
} else {
h->write = usb_ffs_aio_write;
h->read = usb_ffs_aio_read;
- aio_block_init(&h->read_aiob);
- aio_block_init(&h->write_aiob);
+ aio_block_init(&h->read_aiob, num_bufs);
+ aio_block_init(&h->write_aiob, num_bufs);
}
+ h->io_size = io_size;
h->kick = usb_ffs_kick;
h->close = usb_ffs_close;
-
- D("[ usb_init - starting thread ]");
- std::thread(usb_ffs_open_thread, h).detach();
+ return h;
}
void usb_init() {
+ D("[ usb_init - using FunctionFS ]");
dummy_fd = adb_open("/dev/null", O_WRONLY);
CHECK_NE(dummy_fd, -1);
- usb_ffs_init();
+
+ std::thread(usb_ffs_open_thread, create_usb_handle(USB_FFS_NUM_BUFS, USB_FFS_BULK_SIZE)).detach();
}
int usb_write(usb_handle* h, const void* data, int len) {
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 94b2e37..602970c 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -122,7 +122,7 @@
// On Android devices, we rely on the kernel to provide buffered read.
// So we can recover automatically from EOVERFLOW.
static int remote_read(apacket* p, usb_handle* usb) {
- if (usb_read(usb, &p->msg, sizeof(amessage))) {
+ if (usb_read(usb, &p->msg, sizeof(amessage)) != sizeof(amessage)) {
PLOG(ERROR) << "remote usb: read terminated (message)";
return -1;
}
@@ -134,7 +134,8 @@
}
p->payload.resize(p->msg.data_length);
- if (usb_read(usb, &p->payload[0], p->payload.size())) {
+ if (usb_read(usb, &p->payload[0], p->payload.size())
+ != static_cast<int>(p->payload.size())) {
PLOG(ERROR) << "remote usb: terminated (data)";
return -1;
}
@@ -154,14 +155,14 @@
}
bool UsbConnection::Write(apacket* packet) {
- unsigned size = packet->msg.data_length;
+ int size = packet->msg.data_length;
- if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != 0) {
+ if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != sizeof(packet->msg)) {
PLOG(ERROR) << "remote usb: 1 - write terminated";
return false;
}
- if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != 0) {
+ if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != size) {
PLOG(ERROR) << "remote usb: 2 - write terminated";
return false;
}
diff --git a/init/Android.bp b/init/Android.bp
index 625fb94..5bbb7a0 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -180,6 +180,7 @@
"service_test.cpp",
"subcontext_test.cpp",
"tokenizer_test.cpp",
+ "ueventd_parser_test.cpp",
"ueventd_test.cpp",
"util_test.cpp",
],
diff --git a/init/devices.h b/init/devices.h
index 9224fcd..0be660f 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -35,6 +35,8 @@
class Permissions {
public:
+ friend void TestPermissions(const Permissions& expected, const Permissions& test);
+
Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid);
bool Match(const std::string& path) const;
@@ -57,6 +59,8 @@
class SysfsPermissions : public Permissions {
public:
+ friend void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test);
+
SysfsPermissions(const std::string& name, const std::string& attribute, mode_t perm, uid_t uid,
gid_t gid)
: Permissions(name, perm, uid, gid), attribute_(attribute) {}
@@ -71,16 +75,24 @@
class Subsystem {
public:
friend class SubsystemParser;
+ friend void TestSubsystems(const Subsystem& expected, const Subsystem& test);
+
+ enum DevnameSource {
+ DEVNAME_UEVENT_DEVNAME,
+ DEVNAME_UEVENT_DEVPATH,
+ };
Subsystem() {}
- Subsystem(std::string name) : name_(std::move(name)) {}
+ Subsystem(const std::string& name) : name_(name) {}
+ Subsystem(const std::string& name, DevnameSource source, const std::string& dir_name)
+ : name_(name), devname_source_(source), dir_name_(dir_name) {}
// Returns the full path for a uevent of a device that is a member of this subsystem,
// according to the rules parsed from ueventd.rc
std::string ParseDevPath(const Uevent& uevent) const {
- std::string devname = devname_source_ == DevnameSource::DEVNAME_UEVENT_DEVNAME
- ? uevent.device_name
- : android::base::Basename(uevent.path);
+ std::string devname = devname_source_ == DEVNAME_UEVENT_DEVNAME
+ ? uevent.device_name
+ : android::base::Basename(uevent.path);
return dir_name_ + "/" + devname;
}
@@ -88,14 +100,9 @@
bool operator==(const std::string& string_name) const { return name_ == string_name; }
private:
- enum class DevnameSource {
- DEVNAME_UEVENT_DEVNAME,
- DEVNAME_UEVENT_DEVPATH,
- };
-
std::string name_;
+ DevnameSource devname_source_ = DEVNAME_UEVENT_DEVNAME;
std::string dir_name_ = "/dev";
- DevnameSource devname_source_;
};
class DeviceHandler {
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index c114ec7..54b0d16 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -117,11 +117,11 @@
Result<Success> SubsystemParser::ParseDevName(std::vector<std::string>&& args) {
if (args[1] == "uevent_devname") {
- subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVNAME;
+ subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVNAME;
return Success();
}
if (args[1] == "uevent_devpath") {
- subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVPATH;
+ subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVPATH;
return Success();
}
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
new file mode 100644
index 0000000..31208b9
--- /dev/null
+++ b/init/ueventd_parser_test.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 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 "ueventd_parser.h"
+
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+#include <private/android_filesystem_config.h>
+
+namespace android {
+namespace init {
+
+void TestSubsystems(const Subsystem& expected, const Subsystem& test) {
+ EXPECT_EQ(expected.name_, test.name_);
+ EXPECT_EQ(expected.devname_source_, test.devname_source_) << expected.name_;
+ EXPECT_EQ(expected.dir_name_, test.dir_name_) << expected.name_;
+}
+
+void TestPermissions(const Permissions& expected, const Permissions& test) {
+ EXPECT_EQ(expected.name_, test.name_);
+ EXPECT_EQ(expected.perm_, test.perm_) << expected.name_;
+ EXPECT_EQ(expected.uid_, test.uid_) << expected.name_;
+ EXPECT_EQ(expected.gid_, test.gid_) << expected.name_;
+ EXPECT_EQ(expected.prefix_, test.prefix_) << expected.name_;
+ EXPECT_EQ(expected.wildcard_, test.wildcard_) << expected.name_;
+}
+
+void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test) {
+ TestPermissions(expected, test);
+ EXPECT_EQ(expected.attribute_, test.attribute_);
+}
+
+template <typename T, typename F>
+void TestVector(const T& expected, const T& test, F function) {
+ ASSERT_EQ(expected.size(), test.size());
+ auto expected_it = expected.begin();
+ auto test_it = test.begin();
+
+ for (; expected_it != expected.end(); ++expected_it, ++test_it) {
+ function(*expected_it, *test_it);
+ }
+}
+
+void TestUeventdFile(const std::string& content, const UeventdConfiguration& expected) {
+ TemporaryFile tf;
+ ASSERT_TRUE(tf.fd != -1);
+ ASSERT_TRUE(android::base::WriteStringToFd(content, tf.fd));
+
+ auto result = ParseConfig({tf.path});
+
+ TestVector(expected.subsystems, result.subsystems, TestSubsystems);
+ TestVector(expected.sysfs_permissions, result.sysfs_permissions, TestSysfsPermissions);
+ TestVector(expected.dev_permissions, result.dev_permissions, TestPermissions);
+ EXPECT_EQ(expected.firmware_directories, result.firmware_directories);
+}
+
+TEST(ueventd_parser, EmptyFile) {
+ TestUeventdFile("", {});
+}
+
+TEST(ueventd_parser, Subsystems) {
+ auto ueventd_file = R"(
+subsystem test_devname
+ devname uevent_devname
+
+subsystem test_devpath_no_dirname
+ devname uevent_devpath
+
+subsystem test_devname2
+ devname uevent_devname
+
+subsystem test_devpath_dirname
+ devname uevent_devpath
+ dirname /dev/graphics
+)";
+
+ auto subsystems = std::vector<Subsystem>{
+ {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
+ {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
+
+ TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}});
+}
+
+TEST(ueventd_parser, Permissions) {
+ auto ueventd_file = R"(
+/dev/rtc0 0640 system system
+/dev/graphics/* 0660 root graphics
+/dev/*/test 0660 root system
+
+/sys/devices/platform/trusty.* trusty_version 0440 root log
+/sys/devices/virtual/input/input enable 0660 root input
+/sys/devices/virtual/*/input poll_delay 0660 root input
+)";
+
+ auto permissions = std::vector<Permissions>{
+ {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
+ {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
+ {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
+ };
+
+ auto sysfs_permissions = std::vector<SysfsPermissions>{
+ {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
+ {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
+ {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
+ };
+
+ TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}});
+}
+
+TEST(ueventd_parser, FirmwareDirectories) {
+ auto ueventd_file = R"(
+firmware_directories /first/ /second /third
+firmware_directories /more
+)";
+
+ auto firmware_directories = std::vector<std::string>{
+ "/first/",
+ "/second",
+ "/third",
+ "/more",
+ };
+
+ TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories});
+}
+
+TEST(ueventd_parser, AllTogether) {
+ auto ueventd_file = R"(
+
+/dev/rtc0 0640 system system
+firmware_directories /first/ /second /third
+/sys/devices/platform/trusty.* trusty_version 0440 root log
+
+subsystem test_devname
+ devname uevent_devname
+
+/dev/graphics/* 0660 root graphics
+
+subsystem test_devpath_no_dirname
+ devname uevent_devpath
+
+/sys/devices/virtual/input/input enable 0660 root input
+
+## this is a comment
+
+subsystem test_devname2
+## another comment
+ devname uevent_devname
+
+subsystem test_devpath_dirname
+ devname uevent_devpath
+ dirname /dev/graphics
+
+/dev/*/test 0660 root system
+/sys/devices/virtual/*/input poll_delay 0660 root input
+firmware_directories /more
+
+#ending comment
+)";
+
+ auto subsystems = std::vector<Subsystem>{
+ {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
+ {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
+
+ auto permissions = std::vector<Permissions>{
+ {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
+ {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
+ {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
+ };
+
+ auto sysfs_permissions = std::vector<SysfsPermissions>{
+ {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
+ {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
+ {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
+ };
+
+ auto firmware_directories = std::vector<std::string>{
+ "/first/",
+ "/second",
+ "/third",
+ "/more",
+ };
+
+ TestUeventdFile(ueventd_file,
+ {subsystems, sysfs_permissions, permissions, firmware_directories});
+}
+
+// All of these lines are ill-formed, so test that there is 0 output.
+TEST(ueventd_parser, ParseErrors) {
+ auto ueventd_file = R"(
+
+/dev/rtc0 badmode baduidbad system
+/dev/rtc0 0640 baduidbad system
+/dev/rtc0 0640 system baduidbad
+firmware_directories #no directory listed
+/sys/devices/platform/trusty.* trusty_version badmode root log
+/sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
+/sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
+
+subsystem #no name
+
+)";
+
+ TestUeventdFile(ueventd_file, {});
+}
+
+} // namespace init
+} // namespace android
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index 15ace0e..0cc4fc0 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -90,7 +90,7 @@
dev_t rdev;
struct stat st;
- if (TEMP_FAILURE_RETRY(fstat(fd, &st)) < 0) {
+ if (fstat(fd, &st) < 0) {
return -1;
}
@@ -135,6 +135,12 @@
return -1;
}
+static int __ashmem_check_failure(int fd, int result)
+{
+ if (result == -1 && errno == ENOTTY) __ashmem_is_ashmem(fd, 1);
+ return result;
+}
+
int ashmem_valid(int fd)
{
return __ashmem_is_ashmem(fd, 0) >= 0;
@@ -182,12 +188,7 @@
int ashmem_set_prot_region(int fd, int prot)
{
- int ret = __ashmem_is_ashmem(fd, 1);
- if (ret < 0) {
- return ret;
- }
-
- return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot));
+ return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot)));
}
int ashmem_pin_region(int fd, size_t offset, size_t len)
@@ -195,12 +196,7 @@
// TODO: should LP64 reject too-large offset/len?
ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
- int ret = __ashmem_is_ashmem(fd, 1);
- if (ret < 0) {
- return ret;
- }
-
- return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin));
+ return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin)));
}
int ashmem_unpin_region(int fd, size_t offset, size_t len)
@@ -208,20 +204,10 @@
// TODO: should LP64 reject too-large offset/len?
ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
- int ret = __ashmem_is_ashmem(fd, 1);
- if (ret < 0) {
- return ret;
- }
-
- return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin));
+ return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin)));
}
int ashmem_get_size_region(int fd)
{
- int ret = __ashmem_is_ashmem(fd, 1);
- if (ret < 0) {
- return ret;
- }
-
- return TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL));
+ return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)));
}