Merge "NFC: Fix potentially uninitialized 'port' variable."
diff --git a/adb/Android.bp b/adb/Android.bp
index 87e4adc..114eb2a 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -26,6 +26,7 @@
"-Wvla",
"-DADB_HOST=1", // overridden by adbd_defaults
"-DALLOW_ADBD_ROOT=0", // overridden by adbd_defaults
+ "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION=1",
],
cpp_std: "experimental",
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index f5cdcb5..bdb8efa 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -34,7 +34,7 @@
#include "adb_utils.h"
#include "sysdeps.h"
-bool SendProtocolString(int fd, std::string_view s) {
+bool SendProtocolString(borrowed_fd fd, std::string_view s) {
unsigned int length = s.size();
if (length > MAX_PAYLOAD - 4) {
errno = EMSGSIZE;
@@ -47,7 +47,7 @@
return WriteFdExactly(fd, str);
}
-bool ReadProtocolString(int fd, std::string* s, std::string* error) {
+bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error) {
char buf[5];
if (!ReadFdExactly(fd, buf, 4)) {
*error = perror_str("protocol fault (couldn't read status length)");
@@ -65,57 +65,57 @@
return true;
}
-bool SendOkay(int fd) {
+bool SendOkay(borrowed_fd fd) {
return WriteFdExactly(fd, "OKAY", 4);
}
-bool SendFail(int fd, std::string_view reason) {
+bool SendFail(borrowed_fd fd, std::string_view reason) {
return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
}
-bool ReadFdExactly(int fd, void* buf, size_t len) {
+bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len) {
char* p = reinterpret_cast<char*>(buf);
size_t len0 = len;
- D("readx: fd=%d wanted=%zu", fd, len);
+ D("readx: fd=%d wanted=%zu", fd.get(), len);
while (len > 0) {
int r = adb_read(fd, p, len);
if (r > 0) {
len -= r;
p += r;
} else if (r == -1) {
- D("readx: fd=%d error %d: %s", fd, errno, strerror(errno));
+ D("readx: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
return false;
} else {
- D("readx: fd=%d disconnected", fd);
+ D("readx: fd=%d disconnected", fd.get());
errno = 0;
return false;
}
}
- VLOG(RWX) << "readx: fd=" << fd << " wanted=" << len0 << " got=" << (len0 - len)
- << " " << dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
+ VLOG(RWX) << "readx: fd=" << fd.get() << " wanted=" << len0 << " got=" << (len0 - len) << " "
+ << dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
return true;
}
-bool WriteFdExactly(int fd, const void* buf, size_t len) {
+bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len) {
const char* p = reinterpret_cast<const char*>(buf);
int r;
- VLOG(RWX) << "writex: fd=" << fd << " len=" << len
- << " " << dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
+ VLOG(RWX) << "writex: fd=" << fd.get() << " len=" << len << " "
+ << dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
while (len > 0) {
r = adb_write(fd, p, len);
if (r == -1) {
- D("writex: fd=%d error %d: %s", fd, errno, strerror(errno));
+ D("writex: fd=%d error %d: %s", fd.get(), errno, strerror(errno));
if (errno == EAGAIN) {
std::this_thread::yield();
continue;
} else if (errno == EPIPE) {
- D("writex: fd=%d disconnected", fd);
+ D("writex: fd=%d disconnected", fd.get());
errno = 0;
return false;
} else {
@@ -129,15 +129,15 @@
return true;
}
-bool WriteFdExactly(int fd, const char* str) {
+bool WriteFdExactly(borrowed_fd fd, const char* str) {
return WriteFdExactly(fd, str, strlen(str));
}
-bool WriteFdExactly(int fd, const std::string& str) {
+bool WriteFdExactly(borrowed_fd fd, const std::string& str) {
return WriteFdExactly(fd, str.c_str(), str.size());
}
-bool WriteFdFmt(int fd, const char* fmt, ...) {
+bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) {
std::string str;
va_list ap;
@@ -148,7 +148,7 @@
return WriteFdExactly(fd, str);
}
-bool ReadOrderlyShutdown(int fd) {
+bool ReadOrderlyShutdown(borrowed_fd fd) {
char buf[16];
// Only call this function if you're sure that the peer does
@@ -178,7 +178,7 @@
// data. We don't repeatedly call adb_read() until we get zero because
// we don't know how long that would take, but we do know that the
// caller wants to close the socket soon.
- VLOG(RWX) << "ReadOrderlyShutdown(" << fd << ") unexpectedly read "
+ VLOG(RWX) << "ReadOrderlyShutdown(" << fd.get() << ") unexpectedly read "
<< dump_hex(buf, result);
// Shutdown the socket to prevent the caller from reading or writing to
// it which doesn't make sense if we just read and discarded some data.
diff --git a/adb/adb_io.h b/adb/adb_io.h
index d6e65d8..9628946 100644
--- a/adb/adb_io.h
+++ b/adb/adb_io.h
@@ -25,16 +25,16 @@
#include "adb_unique_fd.h"
// Sends the protocol "OKAY" message.
-bool SendOkay(int fd);
+bool SendOkay(borrowed_fd fd);
// Sends the protocol "FAIL" message, with the given failure reason.
-bool SendFail(int fd, std::string_view reason);
+bool SendFail(borrowed_fd fd, std::string_view reason);
// Writes a protocol-format string; a four hex digit length followed by the string data.
-bool SendProtocolString(int fd, std::string_view s);
+bool SendProtocolString(borrowed_fd fd, std::string_view s);
// Reads a protocol-format string; a four hex digit length followed by the string data.
-bool ReadProtocolString(int fd, std::string* s, std::string* error);
+bool ReadProtocolString(borrowed_fd fd, std::string* s, std::string* error);
// Reads exactly len bytes from fd into buf.
//
@@ -42,7 +42,7 @@
// were read. If EOF was found, errno will be set to 0.
//
// If this function fails, the contents of buf are undefined.
-bool ReadFdExactly(int fd, void* buf, size_t len);
+bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len);
// Given a client socket, wait for orderly/graceful shutdown. Call this:
//
@@ -60,19 +60,19 @@
// connect()s from the client to fail with WSAEADDRINUSE on Windows.
// Returns true if it is sure that orderly/graceful shutdown has occurred with
// no additional data read from the server.
-bool ReadOrderlyShutdown(int fd);
+bool ReadOrderlyShutdown(borrowed_fd fd);
// Writes exactly len bytes from buf to fd.
//
// Returns false if there is an error or if the fd was closed before the write
// completed. If the other end of the fd (such as in a socket, pipe, or fifo),
// is closed, errno will be set to 0.
-bool WriteFdExactly(int fd, const void* buf, size_t len);
+bool WriteFdExactly(borrowed_fd fd, const void* buf, size_t len);
// Same as above, but for strings.
-bool WriteFdExactly(int fd, const char* s);
-bool WriteFdExactly(int fd, const std::string& s);
+bool WriteFdExactly(borrowed_fd fd, const char* s);
+bool WriteFdExactly(borrowed_fd fd, const std::string& s);
// Same as above, but formats the string to send.
-bool WriteFdFmt(int fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
+bool WriteFdFmt(borrowed_fd fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
#endif /* ADB_IO_H */
diff --git a/adb/adb_unique_fd.h b/adb/adb_unique_fd.h
index d47213d..b6c910a 100644
--- a/adb/adb_unique_fd.h
+++ b/adb/adb_unique_fd.h
@@ -32,6 +32,8 @@
using unique_fd = android::base::unique_fd;
#endif
+using android::base::borrowed_fd;
+
template <typename T>
int adb_close(const android::base::unique_fd_impl<T>&)
__attribute__((__unavailable__("adb_close called on unique_fd")));
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 9791769..cf5fbc8 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -234,15 +234,15 @@
#if !defined(_WIN32)
// Windows version provided in sysdeps_win32.cpp
-bool set_file_block_mode(int fd, bool block) {
- int flags = fcntl(fd, F_GETFL, 0);
+bool set_file_block_mode(borrowed_fd fd, bool block) {
+ int flags = fcntl(fd.get(), F_GETFL, 0);
if (flags == -1) {
- PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd;
+ PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd.get();
return false;
}
flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
- if (fcntl(fd, F_SETFL, flags) != 0) {
- PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags;
+ if (fcntl(fd.get(), F_SETFL, flags) != 0) {
+ PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd.get() << ", flags " << flags;
return false;
}
return true;
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 8b0dcee..faad03d 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -26,6 +26,7 @@
#include <android-base/macros.h>
#include "adb.h"
+#include "adb_unique_fd.h"
void close_stdin();
@@ -51,7 +52,7 @@
[[noreturn]] void error_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
[[noreturn]] void perror_exit(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
-bool set_file_block_mode(int fd, bool block);
+bool set_file_block_mode(borrowed_fd fd, bool block);
// Given forward/reverse targets, returns true if they look sane. If an error is found, fills
// |error| and returns false.
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index bd676c2..cdca3aa 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -149,13 +149,13 @@
TEST(adb_utils, set_file_block_mode) {
unique_fd fd(adb_open("/dev/null", O_RDWR | O_APPEND));
ASSERT_GE(fd, 0);
- int flags = fcntl(fd, F_GETFL, 0);
+ int flags = fcntl(fd.get(), F_GETFL, 0);
ASSERT_EQ(O_RDWR | O_APPEND, (flags & (O_RDWR | O_APPEND)));
ASSERT_TRUE(set_file_block_mode(fd, false));
- int new_flags = fcntl(fd, F_GETFL, 0);
+ int new_flags = fcntl(fd.get(), F_GETFL, 0);
ASSERT_EQ(flags | O_NONBLOCK, new_flags);
ASSERT_TRUE(set_file_block_mode(fd, true));
- new_flags = fcntl(fd, F_GETFL, 0);
+ new_flags = fcntl(fd.get(), F_GETFL, 0);
ASSERT_EQ(flags, new_flags);
}
#endif
diff --git a/adb/client/adb_client.cpp b/adb/client/adb_client.cpp
index 5a7bc8d..7e408a8 100644
--- a/adb/client/adb_client.cpp
+++ b/adb/client/adb_client.cpp
@@ -128,7 +128,7 @@
return result;
}
-bool adb_status(int fd, std::string* error) {
+bool adb_status(borrowed_fd fd, std::string* error) {
char buf[5];
if (!ReadFdExactly(fd, buf, 4)) {
*error = perror_str("protocol fault (couldn't read status)");
diff --git a/adb/client/adb_client.h b/adb/client/adb_client.h
index 8d32c93..fe1e584 100644
--- a/adb/client/adb_client.h
+++ b/adb/client/adb_client.h
@@ -16,13 +16,14 @@
#pragma once
-#include "adb.h"
-#include "sysdeps.h"
-#include "transport.h"
-
#include <optional>
#include <string>
+#include "adb.h"
+#include "adb_unique_fd.h"
+#include "sysdeps.h"
+#include "transport.h"
+
// Explicitly check the adb server version.
// All of the commands below do this implicitly.
// Only the first invocation of this function will check the server version.
@@ -64,7 +65,7 @@
// Reads a standard adb status response (OKAY|FAIL) and returns true in the
// event of OKAY, false in the event of FAIL or protocol error.
-bool adb_status(int fd, std::string* _Nonnull error);
+bool adb_status(borrowed_fd fd, std::string* _Nonnull error);
// Create a host command corresponding to selected transport type/serial.
std::string format_host_command(const char* _Nonnull command);
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index f39aa58..0e0a76b 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -262,7 +262,7 @@
// stdout/stderr are routed independently and the remote exit code will be
// returned.
// if |callback| is non-null, stdout/stderr output will be handled by it.
-int read_and_dump(int fd, bool use_shell_protocol = false,
+int read_and_dump(borrowed_fd fd, bool use_shell_protocol = false,
StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK) {
int exit_code = 0;
if (fd < 0) return exit_code;
@@ -305,9 +305,9 @@
}
length = protocol->data_length();
} else {
- D("read_and_dump(): pre adb_read(fd=%d)", fd);
+ D("read_and_dump(): pre adb_read(fd=%d)", fd.get());
length = adb_read(fd, raw_buffer, sizeof(raw_buffer));
- D("read_and_dump(): post adb_read(fd=%d): length=%d", fd, length);
+ D("read_and_dump(): post adb_read(fd=%d): length=%d", fd.get(), length);
if (length <= 0) {
break;
}
@@ -887,7 +887,7 @@
return -1;
}
fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
- return adb_sideload_legacy(filename, package_fd, static_cast<int>(sb.st_size));
+ return adb_sideload_legacy(filename, package_fd.get(), static_cast<int>(sb.st_size));
}
int opt = SIDELOAD_HOST_BLOCK_SIZE;
@@ -1207,14 +1207,14 @@
return send_shell_command(cmd);
}
-static void write_zeros(int bytes, int fd) {
+static void write_zeros(int bytes, borrowed_fd fd) {
int old_stdin_mode = -1;
int old_stdout_mode = -1;
std::vector<char> buf(bytes);
- D("write_zeros(%d) -> %d", bytes, fd);
+ D("write_zeros(%d) -> %d", bytes, fd.get());
- stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
+ stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
if (fd == STDOUT_FILENO) {
fwrite(buf.data(), 1, bytes, stdout);
@@ -1223,7 +1223,7 @@
adb_write(fd, buf.data(), bytes);
}
- stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
+ stdinout_raw_prologue(-1, fd.get(), old_stdin_mode, old_stdout_mode);
D("write_zeros() finished");
}
diff --git a/adb/daemon/abb.cpp b/adb/daemon/abb.cpp
index aa75bb1..425438e 100644
--- a/adb/daemon/abb.cpp
+++ b/adb/daemon/abb.cpp
@@ -29,11 +29,11 @@
class AdbFdTextOutput : public android::TextOutput {
public:
- explicit AdbFdTextOutput(int fd) : mFD(fd) {}
+ explicit AdbFdTextOutput(borrowed_fd fd) : fd_(fd) {}
private:
android::status_t print(const char* txt, size_t len) override {
- return WriteFdExactly(mFD, txt, len) ? android::OK : -errno;
+ return WriteFdExactly(fd_, txt, len) ? android::OK : -errno;
}
void moveIndent(int delta) override { /*not implemented*/
}
@@ -44,7 +44,7 @@
}
private:
- int mFD;
+ borrowed_fd fd_;
};
std::vector<std::string_view> parseCmdArgs(std::string_view args) {
@@ -68,10 +68,11 @@
} // namespace
-static int execCmd(std::string_view args, int in, int out, int err) {
+static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) {
AdbFdTextOutput oin(out);
AdbFdTextOutput oerr(err);
- return cmdMain(parseCmdArgs(args), oin, oerr, in, out, err, RunMode::kLibrary);
+ return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(),
+ RunMode::kLibrary);
}
int main(int argc, char* const argv[]) {
diff --git a/adb/daemon/jdwp_service.cpp b/adb/daemon/jdwp_service.cpp
index 66bfc0d..cd9b669 100644
--- a/adb/daemon/jdwp_service.cpp
+++ b/adb/daemon/jdwp_service.cpp
@@ -325,12 +325,12 @@
addrlen = pathlen + sizeof(addr.sun_family);
- if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
+ if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
D("could not bind vm debug control socket: %d: %s", errno, strerror(errno));
return -1;
}
- if (listen(s, 4) < 0) {
+ if (listen(s.get(), 4) < 0) {
D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno));
return -1;
}
diff --git a/adb/daemon/reboot_service.cpp b/adb/daemon/reboot_service.cpp
index a5a11b8..13398af 100644
--- a/adb/daemon/reboot_service.cpp
+++ b/adb/daemon/reboot_service.cpp
@@ -58,7 +58,7 @@
sockaddr_un addr = {.sun_family = AF_UNIX};
strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
- if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
+ if (connect(sock.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
PLOG(ERROR) << "Couldn't connect to recovery socket";
return;
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
index 49dce66..4fbccdb 100644
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ b/adb/daemon/set_verity_enable_state_service.cpp
@@ -58,7 +58,7 @@
}
int OFF = 0;
- bool result = (ioctl(fd, BLKROSET, &OFF) != -1);
+ bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
return result;
}
@@ -197,7 +197,7 @@
}
if (!android::base::GetBoolProperty("ro.secure", false)) {
- overlayfs_setup(fd, enable);
+ overlayfs_setup(fd.get(), enable);
WriteFdExactly(fd.get(), "verity not enabled - ENG build\n");
return;
}
@@ -242,7 +242,7 @@
}
}
}
- if (!any_changed) any_changed = overlayfs_setup(fd, enable);
+ if (!any_changed) any_changed = overlayfs_setup(fd.get(), enable);
if (any_changed) {
WriteFdExactly(fd.get(), "Now reboot your device for settings to take effect\n");
diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp
index 3c8f393..de97068 100644
--- a/adb/daemon/shell_service.cpp
+++ b/adb/daemon/shell_service.cpp
@@ -114,7 +114,7 @@
namespace {
// Reads from |fd| until close or failure.
-std::string ReadAll(int fd) {
+std::string ReadAll(borrowed_fd fd) {
char buffer[512];
std::string received;
@@ -317,9 +317,10 @@
child_stdinout_sfd.reset(OpenPtyChildFd(pts_name, &child_error_sfd));
}
- dup2(child_stdinout_sfd, STDIN_FILENO);
- dup2(child_stdinout_sfd, STDOUT_FILENO);
- dup2(child_stderr_sfd != -1 ? child_stderr_sfd : child_stdinout_sfd, STDERR_FILENO);
+ dup2(child_stdinout_sfd.get(), STDIN_FILENO);
+ dup2(child_stdinout_sfd.get(), STDOUT_FILENO);
+ dup2(child_stderr_sfd != -1 ? child_stderr_sfd.get() : child_stdinout_sfd.get(),
+ STDERR_FILENO);
// exec doesn't trigger destructors, close the FDs manually.
stdinout_sfd_.reset(-1);
@@ -415,7 +416,7 @@
}
} else {
// Raw protocol doesn't support multiple output streams, so combine stdout and stderr.
- child_stderr_sfd.reset(dup(child_stdinout_sfd));
+ child_stderr_sfd.reset(dup(child_stdinout_sfd.get()));
}
D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
@@ -537,7 +538,7 @@
FD_ZERO(&master_write_set);
for (unique_fd* sfd : {&protocol_sfd_, &stdinout_sfd_, &stderr_sfd_}) {
if (*sfd != -1) {
- FD_SET(*sfd, &master_read_set);
+ FD_SET(sfd->get(), &master_read_set);
}
}
@@ -547,8 +548,8 @@
unique_fd* dead_sfd = SelectLoop(&master_read_set, &master_write_set);
if (dead_sfd) {
D("closing FD %d", dead_sfd->get());
- FD_CLR(*dead_sfd, &master_read_set);
- FD_CLR(*dead_sfd, &master_write_set);
+ FD_CLR(dead_sfd->get(), &master_read_set);
+ FD_CLR(dead_sfd->get(), &master_write_set);
if (dead_sfd == &protocol_sfd_) {
// Using SIGHUP is a decent general way to indicate that the
// controlling process is going away. If specific signals are
@@ -573,7 +574,7 @@
namespace {
inline bool ValidAndInSet(const unique_fd& sfd, fd_set* set) {
- return sfd != -1 && FD_ISSET(sfd, set);
+ return sfd != -1 && FD_ISSET(sfd.get(), set);
}
} // namespace
@@ -581,7 +582,8 @@
unique_fd* Subprocess::SelectLoop(fd_set* master_read_set_ptr,
fd_set* master_write_set_ptr) {
fd_set read_set, write_set;
- int select_n = std::max(std::max(protocol_sfd_, stdinout_sfd_), stderr_sfd_) + 1;
+ int select_n =
+ std::max(std::max(protocol_sfd_.get(), stdinout_sfd_.get()), stderr_sfd_.get()) + 1;
unique_fd* dead_sfd = nullptr;
// Keep calling select() and passing data until an FD closes/errors.
@@ -614,8 +616,8 @@
dead_sfd = PassInput();
// If we didn't finish writing, block on stdin write.
if (input_bytes_left_) {
- FD_CLR(protocol_sfd_, master_read_set_ptr);
- FD_SET(stdinout_sfd_, master_write_set_ptr);
+ FD_CLR(protocol_sfd_.get(), master_read_set_ptr);
+ FD_SET(stdinout_sfd_.get(), master_write_set_ptr);
}
}
@@ -624,8 +626,8 @@
dead_sfd = PassInput();
// If we finished writing, go back to blocking on protocol read.
if (!input_bytes_left_) {
- FD_SET(protocol_sfd_, master_read_set_ptr);
- FD_CLR(stdinout_sfd_, master_write_set_ptr);
+ FD_SET(protocol_sfd_.get(), master_read_set_ptr);
+ FD_CLR(stdinout_sfd_.get(), master_write_set_ptr);
}
}
} // while (!dead_sfd)
@@ -639,7 +641,7 @@
if (!input_->Read()) {
// Read() uses ReadFdExactly() which sets errno to 0 on EOF.
if (errno != 0) {
- PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_;
+ PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
}
return &protocol_sfd_;
}
@@ -655,7 +657,7 @@
ws.ws_col = cols;
ws.ws_xpixel = x_pixels;
ws.ws_ypixel = y_pixels;
- ioctl(stdinout_sfd_, TIOCSWINSZ, &ws);
+ ioctl(stdinout_sfd_.get(), TIOCSWINSZ, &ws);
}
break;
case ShellProtocol::kIdStdin:
@@ -666,8 +668,7 @@
if (adb_shutdown(stdinout_sfd_, SHUT_WR) == 0) {
return nullptr;
}
- PLOG(ERROR) << "failed to shutdown writes to FD "
- << stdinout_sfd_;
+ PLOG(ERROR) << "failed to shutdown writes to FD " << stdinout_sfd_.get();
return &stdinout_sfd_;
} else {
// PTYs can't close just input, so rather than close the
@@ -688,7 +689,7 @@
int bytes = adb_write(stdinout_sfd_, input_->data() + index, input_bytes_left_);
if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
if (bytes < 0) {
- PLOG(ERROR) << "error reading stdin FD " << stdinout_sfd_;
+ PLOG(ERROR) << "error reading stdin FD " << stdinout_sfd_.get();
}
// stdin is done, mark this packet as finished and we'll just start
// dumping any further data received from the protocol FD.
@@ -708,14 +709,14 @@
// read() returns EIO if a PTY closes; don't report this as an error,
// it just means the subprocess completed.
if (bytes < 0 && !(type_ == SubprocessType::kPty && errno == EIO)) {
- PLOG(ERROR) << "error reading output FD " << *sfd;
+ PLOG(ERROR) << "error reading output FD " << sfd->get();
}
return sfd;
}
if (bytes > 0 && !output_->Write(id, bytes)) {
if (errno != 0) {
- PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_;
+ PLOG(ERROR) << "error reading protocol FD " << protocol_sfd_.get();
}
return &protocol_sfd_;
}
diff --git a/adb/daemon/shell_service.h b/adb/daemon/shell_service.h
index 3abd958..030228c 100644
--- a/adb/daemon/shell_service.h
+++ b/adb/daemon/shell_service.h
@@ -48,7 +48,7 @@
// Sets up in/out and error streams to emulate shell-like behavior.
//
// Returns an open FD connected to the thread or -1 on failure.
-using Command = int(std::string_view args, int in, int out, int err);
+using Command = int(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err);
unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
// Create a pipe containing the error.
diff --git a/adb/daemon/shell_service_test.cpp b/adb/daemon/shell_service_test.cpp
index dc79d12..cdd8dbe 100644
--- a/adb/daemon/shell_service_test.cpp
+++ b/adb/daemon/shell_service_test.cpp
@@ -77,7 +77,7 @@
namespace {
// Reads raw data from |fd| until it closes or errors.
-std::string ReadRaw(int fd) {
+std::string ReadRaw(borrowed_fd fd) {
char buffer[1024];
char *cur_ptr = buffer, *end_ptr = buffer + sizeof(buffer);
@@ -93,12 +93,12 @@
// Reads shell protocol data from |fd| until it closes or errors. Fills
// |stdout| and |stderr| with their respective data, and returns the exit code
// read from the protocol or -1 if an exit code packet was not received.
-int ReadShellProtocol(int fd, std::string* stdout, std::string* stderr) {
+int ReadShellProtocol(borrowed_fd fd, std::string* stdout, std::string* stderr) {
int exit_code = -1;
stdout->clear();
stderr->clear();
- auto protocol = std::make_unique<ShellProtocol>(fd);
+ auto protocol = std::make_unique<ShellProtocol>(fd.get());
while (protocol->Read()) {
switch (protocol->id()) {
case ShellProtocol::kIdStdout:
diff --git a/adb/shell_protocol.h b/adb/shell_protocol.h
index 2c82689..4aab813 100644
--- a/adb/shell_protocol.h
+++ b/adb/shell_protocol.h
@@ -21,6 +21,7 @@
#include <android-base/macros.h>
#include "adb.h"
+#include "adb_unique_fd.h"
// Class to send and receive shell protocol packets.
//
@@ -60,7 +61,7 @@
// should be dynamically allocated on the heap instead.
//
// |fd| is an open file descriptor to be used to send or receive packets.
- explicit ShellProtocol(int fd);
+ explicit ShellProtocol(borrowed_fd fd);
virtual ~ShellProtocol();
// Returns a pointer to the data buffer.
@@ -103,7 +104,7 @@
kHeaderSize = sizeof(Id) + sizeof(length_t)
};
- int fd_;
+ borrowed_fd fd_;
char buffer_[kBufferSize];
size_t data_length_ = 0, bytes_left_ = 0;
diff --git a/adb/shell_service_protocol.cpp b/adb/shell_service_protocol.cpp
index 13b66ec..95afaff 100644
--- a/adb/shell_service_protocol.cpp
+++ b/adb/shell_service_protocol.cpp
@@ -22,7 +22,7 @@
#include "adb_io.h"
-ShellProtocol::ShellProtocol(int fd) : fd_(fd) {
+ShellProtocol::ShellProtocol(borrowed_fd fd) : fd_(fd) {
buffer_[0] = kIdInvalid;
}
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index de4fff9..1333724 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -314,14 +314,14 @@
addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port;
addr.svm_cid = VMADDR_CID_ANY;
socklen_t addr_len = sizeof(addr);
- if (bind(serverfd, reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
+ if (bind(serverfd.get(), reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
return -1;
}
- if (listen(serverfd, 4)) {
+ if (listen(serverfd.get(), 4)) {
return -1;
}
if (serverfd >= 0 && resolved_port) {
- if (getsockname(serverfd, reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
+ if (getsockname(serverfd.get(), reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
*resolved_port = addr.svm_port;
} else {
return -1;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 15247e7..78abba5 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -36,6 +36,7 @@
#include <android-base/unique_fd.h>
#include <android-base/utf8.h>
+#include "adb_unique_fd.h"
#include "sysdeps/errno.h"
#include "sysdeps/network.h"
#include "sysdeps/stat.h"
@@ -76,42 +77,40 @@
extern int adb_thread_setname(const std::string& name);
-static __inline__ void close_on_exec(int fd)
-{
+static __inline__ void close_on_exec(borrowed_fd fd) {
/* nothing really */
}
-extern int adb_unlink(const char* path);
-#undef unlink
-#define unlink ___xxx_unlink
+extern int adb_unlink(const char* path);
+#undef unlink
+#define unlink ___xxx_unlink
extern int adb_mkdir(const std::string& path, int mode);
-#undef mkdir
-#define mkdir ___xxx_mkdir
+#undef mkdir
+#define mkdir ___xxx_mkdir
// See the comments for the !defined(_WIN32) versions of adb_*().
extern int adb_open(const char* path, int options);
extern int adb_creat(const char* path, int mode);
-extern int adb_read(int fd, void* buf, int len);
-extern int adb_write(int fd, const void* buf, int len);
-extern int64_t adb_lseek(int fd, int64_t pos, int where);
-extern int adb_shutdown(int fd, int direction = SHUT_RDWR);
+extern int adb_read(borrowed_fd fd, void* buf, int len);
+extern int adb_write(borrowed_fd fd, const void* buf, int len);
+extern int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where);
+extern int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR);
extern int adb_close(int fd);
extern int adb_register_socket(SOCKET s);
// See the comments for the !defined(_WIN32) version of unix_close().
-static __inline__ int unix_close(int fd)
-{
+static __inline__ int unix_close(int fd) {
return close(fd);
}
-#undef close
-#define close ____xxx_close
+#undef close
+#define close ____xxx_close
// Like unix_read(), but may return EINTR.
-extern int unix_read_interruptible(int fd, void* buf, size_t len);
+extern int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len);
// See the comments for the !defined(_WIN32) version of unix_read().
-static __inline__ int unix_read(int fd, void* buf, size_t len) {
+static __inline__ int unix_read(borrowed_fd fd, void* buf, size_t len) {
return TEMP_FAILURE_RETRY(unix_read_interruptible(fd, buf, len));
}
@@ -119,23 +118,21 @@
#define read ___xxx_read
// See the comments for the !defined(_WIN32) version of unix_write().
-static __inline__ int unix_write(int fd, const void* buf, size_t len)
-{
- return write(fd, buf, len);
+static __inline__ int unix_write(borrowed_fd fd, const void* buf, size_t len) {
+ return write(fd.get(), buf, len);
}
#undef write
#define write ___xxx_write
// See the comments for the !defined(_WIN32) version of unix_lseek().
-static __inline__ int unix_lseek(int fd, int pos, int where) {
- return lseek(fd, pos, where);
+static __inline__ int unix_lseek(borrowed_fd fd, int pos, int where) {
+ return lseek(fd.get(), pos, where);
}
#undef lseek
#define lseek ___xxx_lseek
// See the comments for the !defined(_WIN32) version of adb_open_mode().
-static __inline__ int adb_open_mode(const char* path, int options, int mode)
-{
+static __inline__ int adb_open_mode(const char* path, int options, int mode) {
return adb_open(path, options);
}
@@ -152,7 +149,7 @@
// with |fd| must have GENERIC_READ access (which console FDs have by default).
// Returns 1 if |fd| is a console FD, 0 otherwise. The value of errno after
// calling this function is unreliable and should not be used.
-int unix_isatty(int fd);
+int unix_isatty(borrowed_fd fd);
#define isatty ___xxx_isatty
int network_inaddr_any_server(int port, int type, std::string* error);
@@ -168,20 +165,21 @@
int network_connect(const std::string& host, int port, int type, int timeout,
std::string* error);
-extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen);
+extern int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen);
#undef accept
#define accept ___xxx_accept
// Returns the local port number of a bound socket, or -1 on failure.
-int adb_socket_get_local_port(int fd);
+int adb_socket_get_local_port(borrowed_fd fd);
-extern int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen);
+extern int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
+ socklen_t optlen);
#undef setsockopt
#define setsockopt ___xxx_setsockopt
-extern int adb_socketpair( int sv[2] );
+extern int adb_socketpair(int sv[2]);
struct adb_pollfd {
int fd;
@@ -214,8 +212,7 @@
extern int adb_fputc(int ch, FILE* stream);
extern int adb_putchar(int ch);
extern int adb_puts(const char* buf);
-extern size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb,
- FILE* stream);
+extern size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
extern FILE* adb_fopen(const char* f, const char* m);
@@ -344,9 +341,8 @@
return c == '/';
}
-static __inline__ void close_on_exec(int fd)
-{
- fcntl( fd, F_SETFD, FD_CLOEXEC );
+static __inline__ void close_on_exec(borrowed_fd fd) {
+ fcntl(fd.get(), F_SETFD, FD_CLOEXEC);
}
// Open a file and return a file descriptor that may be used with unix_read(),
@@ -374,12 +370,10 @@
// Similar to the two-argument adb_open(), but takes a mode parameter for file
// creation. See adb_open() for more info.
-static __inline__ int adb_open_mode( const char* pathname, int options, int mode )
-{
- return TEMP_FAILURE_RETRY( open( pathname, options, mode ) );
+static __inline__ int adb_open_mode(const char* pathname, int options, int mode) {
+ return TEMP_FAILURE_RETRY(open(pathname, options, mode));
}
-
// Open a file and return a file descriptor that may be used with adb_read(),
// adb_write(), adb_close(), but not unix_read(), unix_write(), unix_close().
//
@@ -387,23 +381,21 @@
// sysdeps_win32.cpp) uses Windows native file I/O and bypasses the C Runtime
// and its CR/LF translation. The returned file descriptor should be used with
// adb_read(), adb_write(), adb_close(), etc.
-static __inline__ int adb_open( const char* pathname, int options )
-{
- int fd = TEMP_FAILURE_RETRY( open( pathname, options ) );
- if (fd < 0)
- return -1;
- close_on_exec( fd );
+static __inline__ int adb_open(const char* pathname, int options) {
+ int fd = TEMP_FAILURE_RETRY(open(pathname, options));
+ if (fd < 0) return -1;
+ close_on_exec(fd);
return fd;
}
-#undef open
-#define open ___xxx_open
+#undef open
+#define open ___xxx_open
-static __inline__ int adb_shutdown(int fd, int direction = SHUT_RDWR) {
- return shutdown(fd, direction);
+static __inline__ int adb_shutdown(borrowed_fd fd, int direction = SHUT_RDWR) {
+ return shutdown(fd.get(), direction);
}
-#undef shutdown
-#define shutdown ____xxx_shutdown
+#undef shutdown
+#define shutdown ____xxx_shutdown
// Closes a file descriptor that came from adb_open() or adb_open_mode(), but
// not designed to take a file descriptor from unix_open(). See the comments
@@ -411,81 +403,76 @@
__inline__ int adb_close(int fd) {
return close(fd);
}
-#undef close
-#define close ____xxx_close
+#undef close
+#define close ____xxx_close
// On Windows, ADB has an indirection layer for file descriptors. If we get a
// Win32 SOCKET object from an external library, we have to map it in to that
// indirection layer, which this does.
-__inline__ int adb_register_socket(int s) {
+__inline__ int adb_register_socket(int s) {
return s;
}
-static __inline__ int adb_read(int fd, void* buf, size_t len)
-{
- return TEMP_FAILURE_RETRY( read( fd, buf, len ) );
+static __inline__ int adb_read(borrowed_fd fd, void* buf, size_t len) {
+ return TEMP_FAILURE_RETRY(read(fd.get(), buf, len));
}
// Like unix_read(), but does not handle EINTR.
-static __inline__ int unix_read_interruptible(int fd, void* buf, size_t len) {
- return read(fd, buf, len);
+static __inline__ int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
+ return read(fd.get(), buf, len);
}
-#undef read
-#define read ___xxx_read
+#undef read
+#define read ___xxx_read
-static __inline__ int adb_write(int fd, const void* buf, size_t len)
-{
- return TEMP_FAILURE_RETRY( write( fd, buf, len ) );
+static __inline__ int adb_write(borrowed_fd fd, const void* buf, size_t len) {
+ return TEMP_FAILURE_RETRY(write(fd.get(), buf, len));
}
#undef write
#define write ___xxx_write
-static __inline__ int64_t adb_lseek(int fd, int64_t pos, int where) {
+static __inline__ int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
#if defined(__APPLE__)
- return lseek(fd, pos, where);
+ return lseek(fd.get(), pos, where);
#else
- return lseek64(fd, pos, where);
+ return lseek64(fd.get(), pos, where);
#endif
}
#undef lseek
#define lseek ___xxx_lseek
-static __inline__ int adb_unlink(const char* path)
-{
- return unlink(path);
+static __inline__ int adb_unlink(const char* path) {
+ return unlink(path);
}
-#undef unlink
-#define unlink ___xxx_unlink
+#undef unlink
+#define unlink ___xxx_unlink
-static __inline__ int adb_creat(const char* path, int mode)
-{
- int fd = TEMP_FAILURE_RETRY( creat( path, mode ) );
+static __inline__ int adb_creat(const char* path, int mode) {
+ int fd = TEMP_FAILURE_RETRY(creat(path, mode));
- if ( fd < 0 )
- return -1;
+ if (fd < 0) return -1;
close_on_exec(fd);
return fd;
}
-#undef creat
-#define creat ___xxx_creat
+#undef creat
+#define creat ___xxx_creat
-static __inline__ int unix_isatty(int fd) {
- return isatty(fd);
+static __inline__ int unix_isatty(borrowed_fd fd) {
+ return isatty(fd.get());
}
-#define isatty ___xxx_isatty
+#define isatty ___xxx_isatty
// Helper for network_* functions.
inline int _fd_set_error_str(int fd, std::string* error) {
- if (fd == -1) {
- *error = strerror(errno);
- }
- return fd;
+ if (fd == -1) {
+ *error = strerror(errno);
+ }
+ return fd;
}
inline int network_inaddr_any_server(int port, int type, std::string* error) {
- return _fd_set_error_str(socket_inaddr_any_server(port, type), error);
+ return _fd_set_error_str(socket_inaddr_any_server(port, type), error);
}
inline int network_local_client(const char* name, int namespace_id, int type, std::string* error) {
@@ -498,22 +485,21 @@
int network_connect(const std::string& host, int port, int type, int timeout, std::string* error);
-static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen)
-{
+static __inline__ int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr,
+ socklen_t* addrlen) {
int fd;
- fd = TEMP_FAILURE_RETRY( accept( serverfd, addr, addrlen ) );
- if (fd >= 0)
- close_on_exec(fd);
+ fd = TEMP_FAILURE_RETRY(accept(serverfd.get(), addr, addrlen));
+ if (fd >= 0) close_on_exec(fd);
return fd;
}
-#undef accept
-#define accept ___xxx_accept
+#undef accept
+#define accept ___xxx_accept
-inline int adb_socket_get_local_port(int fd) {
- return socket_get_local_port(fd);
+inline int adb_socket_get_local_port(borrowed_fd fd) {
+ return socket_get_local_port(fd.get());
}
// Operate on a file descriptor returned from unix_open() or a well-known file
@@ -524,10 +510,10 @@
// Windows implementations (in the ifdef above and in sysdeps_win32.cpp) call
// into the C Runtime and its configurable CR/LF translation (which is settable
// via _setmode()).
-#define unix_read adb_read
-#define unix_write adb_write
+#define unix_read adb_read
+#define unix_write adb_write
#define unix_lseek adb_lseek
-#define unix_close adb_close
+#define unix_close adb_close
static __inline__ int adb_thread_setname(const std::string& name) {
#ifdef __APPLE__
@@ -542,34 +528,31 @@
#endif
}
-static __inline__ int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen )
-{
- return setsockopt( fd, level, optname, optval, optlen );
+static __inline__ int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval,
+ socklen_t optlen) {
+ return setsockopt(fd.get(), level, optname, optval, optlen);
}
-#undef setsockopt
-#define setsockopt ___xxx_setsockopt
+#undef setsockopt
+#define setsockopt ___xxx_setsockopt
-static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] )
-{
- return socketpair( d, type, protocol, sv );
+static __inline__ int unix_socketpair(int d, int type, int protocol, int sv[2]) {
+ return socketpair(d, type, protocol, sv);
}
-static __inline__ int adb_socketpair( int sv[2] )
-{
- int rc;
+static __inline__ int adb_socketpair(int sv[2]) {
+ int rc;
- rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
- if (rc < 0)
- return -1;
+ rc = unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (rc < 0) return -1;
- close_on_exec( sv[0] );
- close_on_exec( sv[1] );
+ close_on_exec(sv[0]);
+ close_on_exec(sv[1]);
return 0;
}
-#undef socketpair
-#define socketpair ___xxx_socketpair
+#undef socketpair
+#define socketpair ___xxx_socketpair
typedef struct pollfd adb_pollfd;
static __inline__ int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
@@ -578,13 +561,12 @@
#define poll ___xxx_poll
-static __inline__ int adb_mkdir(const std::string& path, int mode)
-{
+static __inline__ int adb_mkdir(const std::string& path, int mode) {
return mkdir(path.c_str(), mode);
}
-#undef mkdir
-#define mkdir ___xxx_mkdir
+#undef mkdir
+#define mkdir ___xxx_mkdir
static __inline__ int adb_is_absolute_host_path(const char* path) {
return path[0] == '/';
@@ -592,15 +574,15 @@
#endif /* !_WIN32 */
-static inline void disable_tcp_nagle(int fd) {
+static inline void disable_tcp_nagle(borrowed_fd fd) {
int off = 1;
- adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
+ adb_setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
}
// Sets TCP socket |fd| to send a keepalive TCP message every |interval_sec| seconds. Set
// |interval_sec| to 0 to disable keepalives. If keepalives are enabled, the connection will be
// configured to drop after 10 missed keepalives. Returns true on success.
-bool set_tcp_keepalive(int fd, int interval_sec);
+bool set_tcp_keepalive(borrowed_fd fd, int interval_sec);
#if defined(_WIN32)
// Win32 defines ERROR, which we don't need, but which conflicts with google3 logging.
diff --git a/adb/sysdeps/posix/network.cpp b/adb/sysdeps/posix/network.cpp
index 4de240e..c5c2275 100644
--- a/adb/sysdeps/posix/network.cpp
+++ b/adb/sysdeps/posix/network.cpp
@@ -104,13 +104,13 @@
socklen_t addrlen = sizeof(addr_storage);
sockaddr* addr = (ipv6 ? loopback_addr6 : loopback_addr4)(&addr_storage, &addrlen, port);
- if (bind(s, addr, addrlen) != 0) {
+ if (bind(s.get(), addr, addrlen) != 0) {
set_error(error);
return -1;
}
if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
- if (listen(s, SOMAXCONN) != 0) {
+ if (listen(s.get(), SOMAXCONN) != 0) {
set_error(error);
return -1;
}
diff --git a/adb/sysdeps/uio.h b/adb/sysdeps/uio.h
index d06ef89..ced884b 100644
--- a/adb/sysdeps/uio.h
+++ b/adb/sysdeps/uio.h
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include "adb_unique_fd.h"
+
#if defined(_WIN32)
// Layout of this struct must match struct WSABUF (verified via static assert in sysdeps_win32.cpp)
@@ -26,13 +28,15 @@
void* iov_base;
};
-ssize_t adb_writev(int fd, const adb_iovec* iov, int iovcnt);
+ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt);
#else
#include <sys/uio.h>
using adb_iovec = struct iovec;
-#define adb_writev writev
+inline ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
+ return writev(fd.get(), iov, iovcnt);
+}
#endif
diff --git a/adb/sysdeps_unix.cpp b/adb/sysdeps_unix.cpp
index 4445a44..3fdc917 100644
--- a/adb/sysdeps_unix.cpp
+++ b/adb/sysdeps_unix.cpp
@@ -16,7 +16,7 @@
#include "sysdeps.h"
-bool set_tcp_keepalive(int fd, int interval_sec) {
+bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
int enable = (interval_sec > 0);
if (adb_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))) {
return false;
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 4c5d8cb..886ded4 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -145,16 +145,14 @@
static FHRec _win32_fhs[ WIN32_MAX_FHS ];
static int _win32_fh_next; // where to start search for free FHRec
-static FH
-_fh_from_int( int fd, const char* func )
-{
- FH f;
+static FH _fh_from_int(borrowed_fd bfd, const char* func) {
+ FH f;
+ int fd = bfd.get();
fd -= WIN32_FH_BASE;
if (fd < 0 || fd >= WIN32_MAX_FHS) {
- D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
- func );
+ D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
errno = EBADF;
return nullptr;
}
@@ -162,8 +160,7 @@
f = &_win32_fhs[fd];
if (f->used == 0) {
- D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
- func );
+ D("_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE, func);
errno = EBADF;
return nullptr;
}
@@ -171,20 +168,15 @@
return f;
}
-
-static int
-_fh_to_int( FH f )
-{
+static int _fh_to_int(FH f) {
if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
return (int)(f - _win32_fhs) + WIN32_FH_BASE;
return -1;
}
-static FH
-_fh_alloc( FHClass clazz )
-{
- FH f = nullptr;
+static FH _fh_alloc(FHClass clazz) {
+ FH f = nullptr;
std::lock_guard<std::mutex> lock(_win32_lock);
@@ -206,10 +198,7 @@
return nullptr;
}
-
-static int
-_fh_close( FH f )
-{
+static int _fh_close(FH f) {
// Use lock so that closing only happens once and so that _fh_alloc can't
// allocate a FH that we're in the middle of closing.
std::lock_guard<std::mutex> lock(_win32_lock);
@@ -456,7 +445,7 @@
return _fh_to_int(f);
}
-int adb_read(int fd, void* buf, int len) {
+int adb_read(borrowed_fd fd, void* buf, int len) {
FH f = _fh_from_int(fd, __func__);
if (f == nullptr) {
@@ -467,7 +456,7 @@
return f->clazz->_fh_read(f, buf, len);
}
-int adb_write(int fd, const void* buf, int len) {
+int adb_write(borrowed_fd fd, const void* buf, int len) {
FH f = _fh_from_int(fd, __func__);
if (f == nullptr) {
@@ -478,7 +467,7 @@
return f->clazz->_fh_write(f, buf, len);
}
-ssize_t adb_writev(int fd, const adb_iovec* iov, int iovcnt) {
+ssize_t adb_writev(borrowed_fd fd, const adb_iovec* iov, int iovcnt) {
FH f = _fh_from_int(fd, __func__);
if (f == nullptr) {
@@ -489,7 +478,7 @@
return f->clazz->_fh_writev(f, iov, iovcnt);
}
-int64_t adb_lseek(int fd, int64_t pos, int where) {
+int64_t adb_lseek(borrowed_fd fd, int64_t pos, int where) {
FH f = _fh_from_int(fd, __func__);
if (!f) {
errno = EBADF;
@@ -973,11 +962,11 @@
}
#undef accept
-int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t* addrlen) {
+int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen) {
FH serverfh = _fh_from_int(serverfd, __func__);
if (!serverfh || serverfh->clazz != &_fh_socket_class) {
- D("adb_socket_accept: invalid fd %d", serverfd);
+ D("adb_socket_accept: invalid fd %d", serverfd.get());
errno = EBADF;
return -1;
}
@@ -992,7 +981,7 @@
fh->fh_socket = accept(serverfh->fh_socket, addr, addrlen);
if (fh->fh_socket == INVALID_SOCKET) {
const DWORD err = WSAGetLastError();
- LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd
+ LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd.get()
<< " failed: " + android::base::SystemErrorCodeToString(err);
_socket_set_errno(err);
return -1;
@@ -1000,16 +989,16 @@
const int fd = _fh_to_int(fh.get());
snprintf(fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name);
- D("adb_socket_accept on fd %d returns fd %d", serverfd, fd);
+ D("adb_socket_accept on fd %d returns fd %d", serverfd.get(), fd);
fh.release();
return fd;
}
-int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen) {
+int adb_setsockopt(borrowed_fd fd, int level, int optname, const void* optval, socklen_t optlen) {
FH fh = _fh_from_int(fd, __func__);
if (!fh || fh->clazz != &_fh_socket_class) {
- D("adb_setsockopt: invalid fd %d", fd);
+ D("adb_setsockopt: invalid fd %d", fd.get());
errno = EBADF;
return -1;
}
@@ -1022,7 +1011,7 @@
setsockopt(fh->fh_socket, level, optname, reinterpret_cast<const char*>(optval), optlen);
if (result == SOCKET_ERROR) {
const DWORD err = WSAGetLastError();
- D("adb_setsockopt: setsockopt on fd %d level %d optname %d failed: %s\n", fd, level,
+ D("adb_setsockopt: setsockopt on fd %d level %d optname %d failed: %s\n", fd.get(), level,
optname, android::base::SystemErrorCodeToString(err).c_str());
_socket_set_errno(err);
result = -1;
@@ -1030,11 +1019,11 @@
return result;
}
-int adb_getsockname(int fd, struct sockaddr* sockaddr, socklen_t* optlen) {
+static int adb_getsockname(borrowed_fd fd, struct sockaddr* sockaddr, socklen_t* optlen) {
FH fh = _fh_from_int(fd, __func__);
if (!fh || fh->clazz != &_fh_socket_class) {
- D("adb_getsockname: invalid fd %d", fd);
+ D("adb_getsockname: invalid fd %d", fd.get());
errno = EBADF;
return -1;
}
@@ -1042,7 +1031,7 @@
int result = getsockname(fh->fh_socket, sockaddr, optlen);
if (result == SOCKET_ERROR) {
const DWORD err = WSAGetLastError();
- D("adb_getsockname: setsockopt on fd %d failed: %s\n", fd,
+ D("adb_getsockname: setsockopt on fd %d failed: %s\n", fd.get(),
android::base::SystemErrorCodeToString(err).c_str());
_socket_set_errno(err);
result = -1;
@@ -1050,7 +1039,7 @@
return result;
}
-int adb_socket_get_local_port(int fd) {
+int adb_socket_get_local_port(borrowed_fd fd) {
sockaddr_storage addr_storage;
socklen_t addr_len = sizeof(addr_storage);
@@ -1068,11 +1057,11 @@
return ntohs(reinterpret_cast<sockaddr_in*>(&addr_storage)->sin_port);
}
-int adb_shutdown(int fd, int direction) {
+int adb_shutdown(borrowed_fd fd, int direction) {
FH f = _fh_from_int(fd, __func__);
if (!f || f->clazz != &_fh_socket_class) {
- D("adb_shutdown: invalid fd %d", fd);
+ D("adb_shutdown: invalid fd %d", fd.get());
errno = EBADF;
return -1;
}
@@ -1080,7 +1069,7 @@
D("adb_shutdown: %s", f->name);
if (shutdown(f->fh_socket, direction) == SOCKET_ERROR) {
const DWORD err = WSAGetLastError();
- D("socket shutdown fd %d failed: %s", fd,
+ D("socket shutdown fd %d failed: %s", fd.get(),
android::base::SystemErrorCodeToString(err).c_str());
_socket_set_errno(err);
return -1;
@@ -1138,12 +1127,12 @@
return -1;
}
-bool set_file_block_mode(int fd, bool block) {
+bool set_file_block_mode(borrowed_fd fd, bool block) {
FH fh = _fh_from_int(fd, __func__);
if (!fh || !fh->used) {
errno = EBADF;
- D("Setting nonblocking on bad file descriptor %d", fd);
+ D("Setting nonblocking on bad file descriptor %d", fd.get());
return false;
}
@@ -1152,22 +1141,22 @@
if (ioctlsocket(fh->u.socket, FIONBIO, &x) != 0) {
int error = WSAGetLastError();
_socket_set_errno(error);
- D("Setting %d nonblocking failed (%d)", fd, error);
+ D("Setting %d nonblocking failed (%d)", fd.get(), error);
return false;
}
return true;
} else {
errno = ENOTSOCK;
- D("Setting nonblocking on non-socket %d", fd);
+ D("Setting nonblocking on non-socket %d", fd.get());
return false;
}
}
-bool set_tcp_keepalive(int fd, int interval_sec) {
+bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) {
FH fh = _fh_from_int(fd, __func__);
if (!fh || fh->clazz != &_fh_socket_class) {
- D("set_tcp_keepalive(%d) failed: invalid fd", fd);
+ D("set_tcp_keepalive(%d) failed: invalid fd", fd.get());
errno = EBADF;
return false;
}
@@ -1181,7 +1170,7 @@
if (WSAIoctl(fh->fh_socket, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), nullptr, 0,
&bytes_returned, nullptr, nullptr) != 0) {
const DWORD err = WSAGetLastError();
- D("set_tcp_keepalive(%d) failed: %s", fd,
+ D("set_tcp_keepalive(%d) failed: %s", fd.get(),
android::base::SystemErrorCodeToString(err).c_str());
_socket_set_errno(err);
return false;
@@ -1228,12 +1217,12 @@
// Returns a console HANDLE if |fd| is a console, otherwise returns nullptr.
// If a valid HANDLE is returned and |mode| is not null, |mode| is also filled
// with the console mode. Requires GENERIC_READ access to the underlying HANDLE.
-static HANDLE _get_console_handle(int fd, DWORD* mode=nullptr) {
+static HANDLE _get_console_handle(borrowed_fd fd, DWORD* mode = nullptr) {
// First check isatty(); this is very fast and eliminates most non-console
// FDs, but returns 1 for both consoles and character devices like NUL.
#pragma push_macro("isatty")
#undef isatty
- if (!isatty(fd)) {
+ if (!isatty(fd.get())) {
return nullptr;
}
#pragma pop_macro("isatty")
@@ -1241,7 +1230,7 @@
// To differentiate between character devices and consoles we need to get
// the underlying HANDLE and use GetConsoleMode(), which is what requires
// GENERIC_READ permissions.
- const intptr_t intptr_handle = _get_osfhandle(fd);
+ const intptr_t intptr_handle = _get_osfhandle(fd.get());
if (intptr_handle == -1) {
return nullptr;
}
@@ -1265,7 +1254,7 @@
return _get_console_handle(fd);
}
-int unix_isatty(int fd) {
+int unix_isatty(borrowed_fd fd) {
return _get_console_handle(fd) ? 1 : 0;
}
@@ -1645,7 +1634,7 @@
// Prefix the len bytes in buf with the escape character, and then return the
// new buffer length.
-size_t _escape_prefix(char* const buf, const size_t len) {
+static size_t _escape_prefix(char* const buf, const size_t len) {
// If nothing to prefix, don't do anything. We might be called with
// len == 0, if alt was held down with a dead key which produced nothing.
if (len == 0) {
@@ -2073,7 +2062,7 @@
}
// Called by 'adb shell' and 'adb exec-in' (via unix_read()) to read from stdin.
-int unix_read_interruptible(int fd, void* buf, size_t len) {
+int unix_read_interruptible(borrowed_fd fd, void* buf, size_t len) {
if ((fd == STDIN_FILENO) && (_console_handle != nullptr)) {
// If it is a request to read from stdin, and stdin_raw_init() has been
// called, and it successfully configured the console, then read from
@@ -2093,7 +2082,7 @@
// plain read() in favor of unix_read() or adb_read().
#pragma push_macro("read")
#undef read
- return read(fd, buf, len);
+ return read(fd.get(), buf, len);
#pragma pop_macro("read")
}
}
diff --git a/base/Android.bp b/base/Android.bp
index d4268ca..340f814 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -46,6 +46,7 @@
name: "libbase_defaults",
defaults: ["libbase_cflags_defaults"],
srcs: [
+ "abi_compatibility.cpp",
"chrono_utils.cpp",
"cmsg.cpp",
"file.cpp",
diff --git a/base/abi_compatibility.cpp b/base/abi_compatibility.cpp
new file mode 100644
index 0000000..06a7801
--- /dev/null
+++ b/base/abi_compatibility.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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 <memory>
+
+#include "android-base/cmsg.h"
+#include "android-base/file.h"
+#include "android-base/mapped_file.h"
+#include "android-base/unique_fd.h"
+
+namespace android {
+namespace base {
+
+// These ABI-compatibility shims are in a separate file for two reasons:
+// 1. If they were in the file with the actual functions, it prevents calls to
+// those functions by other functions in the file, due to ambiguity.
+// 2. We will hopefully be able to delete these quickly.
+
+#if !defined(_WIN32)
+ssize_t SendFileDescriptorVector(int sockfd, const void* data, size_t len,
+ const std::vector<int>& fds) {
+ return SendFileDescriptorVector(borrowed_fd(sockfd), data, len, fds);
+}
+
+ssize_t ReceiveFileDescriptorVector(int sockfd, void* data, size_t len, size_t max_fds,
+ std::vector<unique_fd>* fds) {
+ return ReceiveFileDescriptorVector(borrowed_fd(sockfd), data, len, max_fds, fds);
+}
+#endif
+
+bool ReadFdToString(int fd, std::string* content) {
+ return ReadFdToString(borrowed_fd(fd), content);
+}
+
+bool WriteStringToFd(const std::string& content, int fd) {
+ return WriteStringToFd(content, borrowed_fd(fd));
+}
+
+bool ReadFully(int fd, void* data, size_t byte_count) {
+ return ReadFully(borrowed_fd(fd), data, byte_count);
+}
+
+bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset) {
+ return ReadFullyAtOffset(borrowed_fd(fd), data, byte_count, offset);
+}
+
+bool WriteFully(int fd, const void* data, size_t byte_count) {
+ return WriteFully(borrowed_fd(fd), data, byte_count);
+}
+
+#if defined(__LP64__)
+#define MAPPEDFILE_FROMFD _ZN10MappedFile6FromFdEilmi
+#else
+#define MAPPEDFILE_FROMFD _ZN10MappedFile6FromFdEixmi
+#endif
+
+#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
+extern "C" std::unique_ptr<MappedFile> MAPPEDFILE_FROMFD(int fd, off64_t offset, size_t length,
+ int prot) {
+ return MappedFile::FromFd(fd, offset, length, prot);
+}
+
+} // namespace base
+} // namespace android
diff --git a/base/cmsg.cpp b/base/cmsg.cpp
index 42866f8..1fa873c 100644
--- a/base/cmsg.cpp
+++ b/base/cmsg.cpp
@@ -29,7 +29,7 @@
namespace android {
namespace base {
-ssize_t SendFileDescriptorVector(int sockfd, const void* data, size_t len,
+ssize_t SendFileDescriptorVector(borrowed_fd sockfd, const void* data, size_t len,
const std::vector<int>& fds) {
size_t cmsg_space = CMSG_SPACE(sizeof(int) * fds.size());
size_t cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
@@ -67,10 +67,10 @@
int flags = 0;
#endif
- return TEMP_FAILURE_RETRY(sendmsg(sockfd, &msg, flags));
+ return TEMP_FAILURE_RETRY(sendmsg(sockfd.get(), &msg, flags));
}
-ssize_t ReceiveFileDescriptorVector(int sockfd, void* data, size_t len, size_t max_fds,
+ssize_t ReceiveFileDescriptorVector(borrowed_fd sockfd, void* data, size_t len, size_t max_fds,
std::vector<unique_fd>* fds) {
fds->clear();
@@ -98,7 +98,7 @@
flags |= MSG_CMSG_CLOEXEC | MSG_NOSIGNAL;
#endif
- ssize_t rc = TEMP_FAILURE_RETRY(recvmsg(sockfd, &msg, flags));
+ ssize_t rc = TEMP_FAILURE_RETRY(recvmsg(sockfd.get(), &msg, flags));
if (rc == -1) {
return -1;
diff --git a/base/file.cpp b/base/file.cpp
index adc8984..3dfcfbb 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -176,20 +176,20 @@
// Versions of standard library APIs that support UTF-8 strings.
using namespace android::base::utf8;
-bool ReadFdToString(int fd, std::string* content) {
+bool ReadFdToString(borrowed_fd fd, std::string* content) {
content->clear();
// Although original we had small files in mind, this code gets used for
// very large files too, where the std::string growth heuristics might not
// be suitable. https://code.google.com/p/android/issues/detail?id=258500.
struct stat sb;
- if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
+ if (fstat(fd.get(), &sb) != -1 && sb.st_size > 0) {
content->reserve(sb.st_size);
}
char buf[BUFSIZ];
ssize_t n;
- while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+ while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) {
content->append(buf, n);
}
return (n == 0) ? true : false;
@@ -206,11 +206,11 @@
return ReadFdToString(fd, content);
}
-bool WriteStringToFd(const std::string& content, int fd) {
+bool WriteStringToFd(const std::string& content, borrowed_fd fd) {
const char* p = content.data();
size_t left = content.size();
while (left > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, left));
+ ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, left));
if (n == -1) {
return false;
}
@@ -269,11 +269,11 @@
return WriteStringToFd(content, fd) || CleanUpAfterFailedWrite(path);
}
-bool ReadFully(int fd, void* data, size_t byte_count) {
+bool ReadFully(borrowed_fd fd, void* data, size_t byte_count) {
uint8_t* p = reinterpret_cast<uint8_t*>(data);
size_t remaining = byte_count;
while (remaining > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining));
+ ssize_t n = TEMP_FAILURE_RETRY(read(fd.get(), p, remaining));
if (n <= 0) return false;
p += n;
remaining -= n;
@@ -284,14 +284,14 @@
#if defined(_WIN32)
// Windows implementation of pread. Note that this DOES move the file descriptors read position,
// but it does so atomically.
-static ssize_t pread(int fd, void* data, size_t byte_count, off64_t offset) {
+static ssize_t pread(borrowed_fd fd, void* data, size_t byte_count, off64_t offset) {
DWORD bytes_read;
OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.Offset = static_cast<DWORD>(offset);
overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
- if (!ReadFile(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), data, static_cast<DWORD>(byte_count),
- &bytes_read, &overlapped)) {
+ if (!ReadFile(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), data,
+ static_cast<DWORD>(byte_count), &bytes_read, &overlapped)) {
// In case someone tries to read errno (since this is masquerading as a POSIX call)
errno = EIO;
return -1;
@@ -300,10 +300,10 @@
}
#endif
-bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset) {
+bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset) {
uint8_t* p = reinterpret_cast<uint8_t*>(data);
while (byte_count > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(pread(fd, p, byte_count, offset));
+ ssize_t n = TEMP_FAILURE_RETRY(pread(fd.get(), p, byte_count, offset));
if (n <= 0) return false;
p += n;
byte_count -= n;
@@ -312,11 +312,11 @@
return true;
}
-bool WriteFully(int fd, const void* data, size_t byte_count) {
+bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count) {
const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
size_t remaining = byte_count;
while (remaining > 0) {
- ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining));
+ ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, remaining));
if (n == -1) return false;
p += n;
remaining -= n;
diff --git a/base/include/android-base/cmsg.h b/base/include/android-base/cmsg.h
index 7f93ddc..e4197b1 100644
--- a/base/include/android-base/cmsg.h
+++ b/base/include/android-base/cmsg.h
@@ -51,20 +51,20 @@
// Note that the write can return short if the socket type is SOCK_STREAM. When
// this happens, file descriptors are still sent to the other end, but with
// truncated data. For this reason, using SOCK_SEQPACKET or SOCK_DGRAM is recommended.
-ssize_t SendFileDescriptorVector(int sock, const void* data, size_t len,
+ssize_t SendFileDescriptorVector(borrowed_fd sock, const void* data, size_t len,
const std::vector<int>& fds);
// Receive file descriptors from a Unix domain socket.
//
// If more FDs (or bytes, for datagram sockets) are received than expected,
// -1 is returned with errno set to EMSGSIZE, and all received FDs are thrown away.
-ssize_t ReceiveFileDescriptorVector(int sock, void* data, size_t len, size_t max_fds,
+ssize_t ReceiveFileDescriptorVector(borrowed_fd sock, void* data, size_t len, size_t max_fds,
std::vector<android::base::unique_fd>* fds);
// Helper for SendFileDescriptorVector that constructs a std::vector for you, e.g.:
// SendFileDescriptors(sock, "foo", 3, std::move(fd1), std::move(fd2))
template <typename... Args>
-ssize_t SendFileDescriptors(int sock, const void* data, size_t len, Args&&... sent_fds) {
+ssize_t SendFileDescriptors(borrowed_fd sock, const void* data, size_t len, Args&&... sent_fds) {
// Do not allow implicit conversion to int: people might try to do something along the lines of:
// SendFileDescriptors(..., std::move(a_unique_fd))
// and be surprised when the unique_fd isn't closed afterwards.
@@ -79,7 +79,7 @@
// If fewer file descriptors are received than requested, -1 is returned with errno set to ENOMSG.
// In both cases, all arguments are cleared and any received FDs are thrown away.
template <typename... Args>
-ssize_t ReceiveFileDescriptors(int sock, void* data, size_t len, Args&&... received_fds) {
+ssize_t ReceiveFileDescriptors(borrowed_fd sock, void* data, size_t len, Args&&... received_fds) {
std::vector<unique_fd*> fds;
Append(fds, std::forward<Args>(received_fds)...);
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index f8748b5..c622562 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -21,8 +21,9 @@
#include <string>
-#include <android-base/macros.h>
+#include "android-base/macros.h"
#include "android-base/off64_t.h"
+#include "android-base/unique_fd.h"
#if !defined(_WIN32) && !defined(O_BINARY)
/** Windows needs O_BINARY, but Unix never mangles line endings. */
@@ -77,13 +78,13 @@
namespace android {
namespace base {
-bool ReadFdToString(int fd, std::string* content);
+bool ReadFdToString(borrowed_fd fd, std::string* content);
bool ReadFileToString(const std::string& path, std::string* content,
bool follow_symlinks = false);
bool WriteStringToFile(const std::string& content, const std::string& path,
bool follow_symlinks = false);
-bool WriteStringToFd(const std::string& content, int fd);
+bool WriteStringToFd(const std::string& content, borrowed_fd fd);
#if !defined(_WIN32)
bool WriteStringToFile(const std::string& content, const std::string& path,
@@ -91,7 +92,7 @@
bool follow_symlinks = false);
#endif
-bool ReadFully(int fd, void* data, size_t byte_count);
+bool ReadFully(borrowed_fd fd, void* data, size_t byte_count);
// Reads `byte_count` bytes from the file descriptor at the specified offset.
// Returns false if there was an IO error or EOF was reached before reading `byte_count` bytes.
@@ -101,9 +102,9 @@
// get modified. This means that ReadFullyAtOffset can be used concurrently with other calls to the
// same function, but concurrently seeking or reading incrementally can lead to unexpected
// behavior.
-bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset);
+bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset);
-bool WriteFully(int fd, const void* data, size_t byte_count);
+bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count);
bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);
diff --git a/base/include/android-base/mapped_file.h b/base/include/android-base/mapped_file.h
index 80513b1..b719646 100644
--- a/base/include/android-base/mapped_file.h
+++ b/base/include/android-base/mapped_file.h
@@ -16,13 +16,14 @@
#pragma once
-#include "android-base/macros.h"
-#include "android-base/off64_t.h"
-
#include <sys/types.h>
#include <memory>
+#include "android-base/macros.h"
+#include "android-base/off64_t.h"
+#include "android-base/unique_fd.h"
+
#if defined(_WIN32)
#include <windows.h>
#define PROT_READ 1
@@ -44,7 +45,8 @@
* `offset` does not need to be page-aligned. If `PROT_WRITE` is set in `prot`, the mapping
* will be writable, otherwise it will be read-only. Mappings are always `MAP_SHARED`.
*/
- static std::unique_ptr<MappedFile> FromFd(int fd, off64_t offset, size_t length, int prot);
+ static std::unique_ptr<MappedFile> FromFd(borrowed_fd fd, off64_t offset, size_t length,
+ int prot);
/**
* Removes the mapping.
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 3fa3bea..3a02cff 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -103,7 +103,17 @@
void reset(int new_value = -1) { reset(new_value, nullptr); }
int get() const { return fd_; }
+
+#if !defined(ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION)
+ // unique_fd's operator int is dangerous, but we have way too much code that
+ // depends on it, so make this opt-in at first.
operator int() const { return get(); } // NOLINT
+#endif
+
+ bool operator>=(int rhs) const { return get() >= rhs; }
+ bool operator<(int rhs) const { return get() < rhs; }
+ bool operator==(int rhs) const { return get() == rhs; }
+ bool operator!=(int rhs) const { return get() != rhs; }
// Catch bogus error checks (i.e.: "!fd" instead of "fd != -1").
bool operator!() const = delete;
@@ -246,6 +256,22 @@
#endif // !defined(_WIN32)
+// A wrapper type that can be implicitly constructed from either int or unique_fd.
+struct borrowed_fd {
+ /* implicit */ borrowed_fd(int fd) : fd_(fd) {}
+ template <typename T>
+ /* implicit */ borrowed_fd(const unique_fd_impl<T>& ufd) : fd_(ufd.get()) {}
+
+ int get() const { return fd_; }
+
+ bool operator>=(int rhs) const { return get() >= rhs; }
+ bool operator<(int rhs) const { return get() < rhs; }
+ bool operator==(int rhs) const { return get() == rhs; }
+ bool operator!=(int rhs) const { return get() != rhs; }
+
+ private:
+ int fd_ = -1;
+};
} // namespace base
} // namespace android
diff --git a/base/mapped_file.cpp b/base/mapped_file.cpp
index 7c65dc3..f689bfa 100644
--- a/base/mapped_file.cpp
+++ b/base/mapped_file.cpp
@@ -18,6 +18,8 @@
#include <errno.h>
+#include "android-base/unique_fd.h"
+
namespace android {
namespace base {
@@ -31,7 +33,8 @@
#endif
}
-std::unique_ptr<MappedFile> MappedFile::FromFd(int fd, off64_t offset, size_t length, int prot) {
+std::unique_ptr<MappedFile> MappedFile::FromFd(borrowed_fd fd, off64_t offset, size_t length,
+ int prot) {
static off64_t page_size = InitPageSize();
size_t slop = offset % page_size;
off64_t file_offset = offset - slop;
@@ -39,7 +42,7 @@
#if defined(_WIN32)
HANDLE handle =
- CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), nullptr,
+ CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), nullptr,
(prot & PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, 0, 0, nullptr);
if (handle == nullptr) {
// http://b/119818070 "app crashes when reading asset of zero length".
@@ -58,7 +61,7 @@
return std::unique_ptr<MappedFile>(
new MappedFile{static_cast<char*>(base), length, slop, handle});
#else
- void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd, file_offset);
+ void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd.get(), file_offset);
if (base == MAP_FAILED) {
// http://b/119818070 "app crashes when reading asset of zero length".
// mmap fails with EINVAL for a zero length region.
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index c608a8c..cb55745 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -463,6 +463,7 @@
ThreadInfo info;
info.pid = target_process;
info.tid = thread;
+ info.uid = getuid();
info.process_name = process_name;
info.thread_name = get_thread_name(thread);
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 00334bc..6482ed3 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -256,7 +256,7 @@
auto& mount_point = entry.mount_point;
if (fs_mgr_is_verity_enabled(entry)) {
retval = VERITY_PARTITION;
- if (android::base::GetProperty("ro.boot.vbmeta.devices_state", "") != "locked") {
+ if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") != "locked") {
if (AvbOps* ops = avb_ops_user_new()) {
auto ret = avb_user_verity_set(
ops, android::base::GetProperty("ro.boot.slot_suffix", "").c_str(),
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index f069c58..7dd3ad4 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -235,7 +235,7 @@
SetInitAvbVersionInRecovery();
- setenv("FIRST_STAGE_STARTED_AT", std::to_string(start_time.time_since_epoch().count()).c_str(),
+ setenv(kEnvFirstStageStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(),
1);
const char* path = "/system/bin/init";
diff --git a/init/first_stage_init.h b/init/first_stage_init.h
index 0476e44..7de816f 100644
--- a/init/first_stage_init.h
+++ b/init/first_stage_init.h
@@ -21,5 +21,7 @@
int FirstStageMain(int argc, char** argv);
+static constexpr char kEnvFirstStageStartedAt[] = "FIRST_STAGE_STARTED_AT";
+
} // namespace init
} // namespace android
diff --git a/init/init.cpp b/init/init.cpp
index a18c2c8..1f3c2fc 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -56,6 +56,7 @@
#include "action_parser.h"
#include "boringssl_self_test.h"
#include "epoll.h"
+#include "first_stage_init.h"
#include "first_stage_mount.h"
#include "import_parser.h"
#include "keychords.h"
@@ -630,20 +631,18 @@
static void RecordStageBoottimes(const boot_clock::time_point& second_stage_start_time) {
int64_t first_stage_start_time_ns = -1;
- static constexpr char first_stage_started_at[] = "FIRST_STAGE_STARTED_AT";
- if (auto first_stage_start_time_str = getenv(first_stage_started_at);
+ if (auto first_stage_start_time_str = getenv(kEnvFirstStageStartedAt);
first_stage_start_time_str) {
property_set("ro.boottime.init", first_stage_start_time_str);
android::base::ParseInt(first_stage_start_time_str, &first_stage_start_time_ns);
}
- unsetenv(first_stage_started_at);
+ unsetenv(kEnvFirstStageStartedAt);
int64_t selinux_start_time_ns = -1;
- static constexpr char selinux_started_at[] = "SELINUX_STARTED_AT";
- if (auto selinux_start_time_str = getenv(selinux_started_at); selinux_start_time_str) {
+ if (auto selinux_start_time_str = getenv(kEnvSelinuxStartedAt); selinux_start_time_str) {
android::base::ParseInt(selinux_start_time_str, &selinux_start_time_ns);
}
- unsetenv(selinux_started_at);
+ unsetenv(kEnvSelinuxStartedAt);
if (selinux_start_time_ns == -1) return;
if (first_stage_start_time_ns == -1) return;
diff --git a/init/selinux.cpp b/init/selinux.cpp
index f897170..8a63363 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -544,7 +544,7 @@
PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
}
- setenv("SELINUX_STARTED_AT", std::to_string(start_time.time_since_epoch().count()).c_str(), 1);
+ setenv(kEnvSelinuxStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(), 1);
const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
diff --git a/init/selinux.h b/init/selinux.h
index 3aa9406..c7d6647 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -35,6 +35,8 @@
const std::vector<std::string>& aliases, int type,
std::string* result);
+static constexpr char kEnvSelinuxStartedAt[] = "SELINUX_STARTED_AT";
+
} // namespace init
} // namespace android
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index c473f2c..64fedae 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -68,6 +68,16 @@
return "";
}
+// For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
+// variable to add libraries to the list. This is intended for platform tests only.
+std::string additional_public_libraries() {
+ if (debuggable()) {
+ const char* val = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
+ return val ? val : "";
+ }
+ return "";
+}
+
void InsertVndkVersionStr(std::string* file_name) {
CHECK(file_name != nullptr);
size_t insert_pos = file_name->find_last_of(".");
@@ -171,130 +181,119 @@
}
}
-} // namespace
+static std::string InitDefaultPublicLibraries() {
+ std::string config_file = root_dir() + kDefaultPublicLibrariesFile;
+ std::vector<std::string> sonames;
+ std::string error_msg;
+ LOG_ALWAYS_FATAL_IF(!ReadConfig(config_file, &sonames, always_true, &error_msg),
+ "Error reading public native library list from \"%s\": %s",
+ config_file.c_str(), error_msg.c_str());
-const std::string& default_public_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- std::string config_file = root_dir() + kDefaultPublicLibrariesFile;
- std::vector<std::string> sonames;
- std::string error_msg;
- LOG_ALWAYS_FATAL_IF(!ReadConfig(config_file, &sonames, always_true, &error_msg),
- "Error reading public native library list from \"%s\": %s",
- config_file.c_str(), error_msg.c_str());
+ std::string additional_libs = additional_public_libraries();
+ if (!additional_libs.empty()) {
+ auto vec = base::Split(additional_libs, ":");
+ std::copy(vec.begin(), vec.end(), std::back_inserter(sonames));
+ }
- // For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
- // variable to add libraries to the list. This is intended for platform tests only.
- if (debuggable()) {
- const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
- if (additional_libs != nullptr && additional_libs[0] != '\0') {
- std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
- std::copy(additional_libs_vector.begin(), additional_libs_vector.end(),
- std::back_inserter(sonames));
- }
+ // Remove the public libs in the runtime namespace.
+ // These libs are listed in public.android.txt, but we don't want the rest of android
+ // in default namespace to dlopen the libs.
+ // For example, libicuuc.so is exposed to classloader namespace from runtime namespace.
+ // Unfortunately, it does not have stable C symbols, and default namespace should only use
+ // stable symbols in libandroidicu.so. http://b/120786417
+ for (const std::string& lib_name : kRuntimePublicLibraries) {
+ std::string path(kRuntimeApexLibPath);
+ path.append("/").append(lib_name);
+
+ struct stat s;
+ // Do nothing if the path in /apex does not exist.
+ // Runtime APEX must be mounted since libnativeloader is in the same APEX
+ if (stat(path.c_str(), &s) != 0) {
+ continue;
}
- // Remove the public libs in the runtime namespace.
- // These libs are listed in public.android.txt, but we don't want the rest of android
- // in default namespace to dlopen the libs.
- // For example, libicuuc.so is exposed to classloader namespace from runtime namespace.
- // Unfortunately, it does not have stable C symbols, and default namespace should only use
- // stable symbols in libandroidicu.so. http://b/120786417
- for (const std::string& lib_name : kRuntimePublicLibraries) {
- std::string path(kRuntimeApexLibPath);
- path.append("/").append(lib_name);
-
- struct stat s;
- // Do nothing if the path in /apex does not exist.
- // Runtime APEX must be mounted since libnativeloader is in the same APEX
- if (stat(path.c_str(), &s) != 0) {
- continue;
- }
-
- auto it = std::find(sonames.begin(), sonames.end(), lib_name);
- if (it != sonames.end()) {
- sonames.erase(it);
- }
+ auto it = std::find(sonames.begin(), sonames.end(), lib_name);
+ if (it != sonames.end()) {
+ sonames.erase(it);
}
- list = android::base::Join(sonames, ':');
- cached = true;
+ }
+ return android::base::Join(sonames, ':');
+}
+
+static std::string InitRuntimePublicLibraries() {
+ CHECK(sizeof(kRuntimePublicLibraries) > 0);
+ std::string list = android::base::Join(kRuntimePublicLibraries, ":");
+
+ std::string additional_libs = additional_public_libraries();
+ if (!additional_libs.empty()) {
+ list = list + ':' + additional_libs;
}
return list;
}
-const std::string& runtime_public_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- list = android::base::Join(kRuntimePublicLibraries, ":");
- // For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
- // variable to add libraries to the list. This is intended for platform tests only.
- if (debuggable()) {
- const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
- if (additional_libs != nullptr && additional_libs[0] != '\0') {
- list = list + ':' + additional_libs;
- }
- }
- }
- return list;
-}
-
-const std::string& vendor_public_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- // This file is optional, quietly ignore if the file does not exist.
- std::vector<std::string> sonames;
- ReadConfig(kVendorPublicLibrariesFile, &sonames, always_true, nullptr);
- list = android::base::Join(sonames, ':');
- cached = true;
- }
- return list;
+static std::string InitVendorPublicLibraries() {
+ // This file is optional, quietly ignore if the file does not exist.
+ std::vector<std::string> sonames;
+ ReadConfig(kVendorPublicLibrariesFile, &sonames, always_true, nullptr);
+ return android::base::Join(sonames, ':');
}
// read /system/etc/public.libraries-<companyname>.txt and
// /product/etc/public.libraries-<companyname>.txt which contain partner defined
// system libs that are exposed to apps. The libs in the txt files must be
// named as lib<name>.<companyname>.so.
+static std::string InitExtendedPublicLibraries() {
+ std::vector<std::string> sonames;
+ ReadExtensionLibraries("/system/etc", &sonames);
+ ReadExtensionLibraries("/product/etc", &sonames);
+ return android::base::Join(sonames, ':');
+}
+
+static std::string InitLlndkLibraries() {
+ std::string config_file = kLlndkLibrariesFile;
+ InsertVndkVersionStr(&config_file);
+ std::vector<std::string> sonames;
+ ReadConfig(config_file, &sonames, always_true, nullptr);
+ return android::base::Join(sonames, ':');
+}
+
+static std::string InitVndkspLibraries() {
+ std::string config_file = kVndkLibrariesFile;
+ InsertVndkVersionStr(&config_file);
+ std::vector<std::string> sonames;
+ ReadConfig(config_file, &sonames, always_true, nullptr);
+ return android::base::Join(sonames, ':');
+}
+
+} // namespace
+
+const std::string& default_public_libraries() {
+ static std::string list = InitDefaultPublicLibraries();
+ return list;
+}
+
+const std::string& runtime_public_libraries() {
+ static std::string list = InitRuntimePublicLibraries();
+ return list;
+}
+
+const std::string& vendor_public_libraries() {
+ static std::string list = InitVendorPublicLibraries();
+ return list;
+}
+
const std::string& extended_public_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- std::vector<std::string> sonames;
- ReadExtensionLibraries("/system/etc", &sonames);
- ReadExtensionLibraries("/product/etc", &sonames);
- list = android::base::Join(sonames, ':');
- cached = true;
- }
+ static std::string list = InitExtendedPublicLibraries();
return list;
}
const std::string& llndk_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- std::string config_file = kLlndkLibrariesFile;
- InsertVndkVersionStr(&config_file);
- std::vector<std::string> sonames;
- ReadConfig(config_file, &sonames, always_true, nullptr);
- list = android::base::Join(sonames, ':');
- cached = true;
- }
+ static std::string list = InitLlndkLibraries();
return list;
}
const std::string& vndksp_libraries() {
- static bool cached = false;
- static std::string list;
- if (!cached) {
- std::string config_file = kVndkLibrariesFile;
- InsertVndkVersionStr(&config_file);
- std::vector<std::string> sonames;
- ReadConfig(config_file, &sonames, always_true, nullptr);
- list = android::base::Join(sonames, ':');
- cached = true;
- }
+ static std::string list = InitVndkspLibraries();
return list;
}
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index 78a02e5..0207a75 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -32,6 +32,8 @@
shared_libs: [
"libbase",
"libcgrouprc",
+ ],
+ static_libs: [
"libjsoncpp",
],
// for cutils/android_filesystem_config.h
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index 6e837a4..7eead7e 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -177,7 +177,10 @@
*
* Returns 0 on success and negative values on failure.
*/
-// TODO: switch these ZipStrings to std::string_view.
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+ const std::string_view optional_prefix = "",
+ const std::string_view optional_suffix = "");
+// TODO: remove this.
int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
const ZipString* optional_prefix, const ZipString* optional_suffix);
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index c6def73..3a3a694 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -249,7 +249,7 @@
// libziparchive iteration order doesn't match the central directory.
// We could sort, but that would cost extra and wouldn't match either.
void* cookie;
- int err = StartIteration(zah, &cookie, nullptr, nullptr);
+ int err = StartIteration(zah, &cookie);
if (err != 0) {
error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err));
}
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 2bd8fb9..ac3e236 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -689,54 +689,59 @@
}
struct IterationHandle {
- uint32_t position;
- // TODO: switch these to std::string now that Windows uses libc++ too.
- ZipString prefix;
- ZipString suffix;
ZipArchive* archive;
- IterationHandle(const ZipString* in_prefix, const ZipString* in_suffix) {
- if (in_prefix) {
- uint8_t* name_copy = new uint8_t[in_prefix->name_length];
- memcpy(name_copy, in_prefix->name, in_prefix->name_length);
- prefix.name = name_copy;
- prefix.name_length = in_prefix->name_length;
- } else {
- prefix.name = NULL;
- prefix.name_length = 0;
- }
- if (in_suffix) {
- uint8_t* name_copy = new uint8_t[in_suffix->name_length];
- memcpy(name_copy, in_suffix->name, in_suffix->name_length);
- suffix.name = name_copy;
- suffix.name_length = in_suffix->name_length;
- } else {
- suffix.name = NULL;
- suffix.name_length = 0;
- }
- }
+ std::string prefix_holder;
+ ZipString prefix;
- ~IterationHandle() {
- delete[] prefix.name;
- delete[] suffix.name;
- }
+ std::string suffix_holder;
+ ZipString suffix;
+
+ uint32_t position = 0;
+
+ IterationHandle(ZipArchive* archive, const std::string_view in_prefix,
+ const std::string_view in_suffix)
+ : archive(archive),
+ prefix_holder(in_prefix),
+ prefix(prefix_holder),
+ suffix_holder(in_suffix),
+ suffix(suffix_holder) {}
};
int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
- const ZipString* optional_prefix, const ZipString* optional_suffix) {
+ const std::string_view optional_prefix,
+ const std::string_view optional_suffix) {
if (archive == NULL || archive->hash_table == NULL) {
ALOGW("Zip: Invalid ZipArchiveHandle");
return kInvalidHandle;
}
- IterationHandle* cookie = new IterationHandle(optional_prefix, optional_suffix);
- cookie->position = 0;
- cookie->archive = archive;
+ if (optional_prefix.size() > static_cast<size_t>(UINT16_MAX) ||
+ optional_suffix.size() > static_cast<size_t>(UINT16_MAX)) {
+ ALOGW("Zip: prefix/suffix too long");
+ return kInvalidEntryName;
+ }
- *cookie_ptr = cookie;
+ *cookie_ptr = new IterationHandle(archive, optional_prefix, optional_suffix);
return 0;
}
+// TODO: remove this.
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+ const ZipString* optional_prefix, const ZipString* optional_suffix) {
+ std::string prefix;
+ if (optional_prefix) {
+ prefix = std::string(reinterpret_cast<const char*>(optional_prefix->name),
+ optional_prefix->name_length);
+ }
+ std::string suffix;
+ if (optional_suffix) {
+ suffix = std::string(reinterpret_cast<const char*>(optional_suffix->name),
+ optional_suffix->name_length);
+ }
+ return StartIteration(archive, cookie_ptr, prefix.c_str(), suffix.c_str());
+}
+
void EndIteration(void* cookie) {
delete reinterpret_cast<IterationHandle*>(cookie);
}
diff --git a/libziparchive/zip_archive_benchmark.cpp b/libziparchive/zip_archive_benchmark.cpp
index 52166a4..434f2e1 100644
--- a/libziparchive/zip_archive_benchmark.cpp
+++ b/libziparchive/zip_archive_benchmark.cpp
@@ -75,7 +75,7 @@
while (state.KeepRunning()) {
OpenArchive(temp_file->path, &handle);
- StartIteration(handle, &iteration_cookie, nullptr, nullptr);
+ StartIteration(handle, &iteration_cookie);
while (Next(iteration_cookie, &data, &name) == 0) {
}
EndIteration(iteration_cookie);
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index cfbce1c..993c975 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -107,7 +107,7 @@
close(fd);
}
-static void AssertIterationOrder(const ZipString* prefix, const ZipString* suffix,
+static void AssertIterationOrder(const std::string_view prefix, const std::string_view suffix,
const std::vector<std::string>& expected_names_sorted) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
@@ -137,30 +137,26 @@
static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b.txt", "b/", "b/c.txt",
"b/d.txt"};
- AssertIterationOrder(nullptr, nullptr, kExpectedMatchesSorted);
+ AssertIterationOrder("", "", kExpectedMatchesSorted);
}
TEST(ziparchive, IterationWithPrefix) {
- ZipString prefix("b/");
static const std::vector<std::string> kExpectedMatchesSorted = {"b/", "b/c.txt", "b/d.txt"};
- AssertIterationOrder(&prefix, nullptr, kExpectedMatchesSorted);
+ AssertIterationOrder("b/", "", kExpectedMatchesSorted);
}
TEST(ziparchive, IterationWithSuffix) {
- ZipString suffix(".txt");
static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b.txt", "b/c.txt",
"b/d.txt"};
- AssertIterationOrder(nullptr, &suffix, kExpectedMatchesSorted);
+ AssertIterationOrder("", ".txt", kExpectedMatchesSorted);
}
TEST(ziparchive, IterationWithPrefixAndSuffix) {
- ZipString prefix("b");
- ZipString suffix(".txt");
static const std::vector<std::string> kExpectedMatchesSorted = {"b.txt", "b/c.txt", "b/d.txt"};
- AssertIterationOrder(&prefix, &suffix, kExpectedMatchesSorted);
+ AssertIterationOrder("b", ".txt", kExpectedMatchesSorted);
}
TEST(ziparchive, IterationWithBadPrefixAndSuffix) {
@@ -168,9 +164,7 @@
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
void* iteration_cookie;
- ZipString prefix("x");
- ZipString suffix("y");
- ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, "x", "y"));
ZipEntry data;
ZipString name;
@@ -228,7 +222,7 @@
ASSERT_EQ(0, OpenArchiveWrapper("declaredlength.zip", &handle));
void* iteration_cookie;
- ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, nullptr, nullptr));
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie));
ZipString name;
ZipEntry data;
diff --git a/usbd/usbd.cpp b/usbd/usbd.cpp
index 41cd8dd..191fb92 100644
--- a/usbd/usbd.cpp
+++ b/usbd/usbd.cpp
@@ -22,15 +22,20 @@
#include <android-base/properties.h>
#include <android/hardware/usb/gadget/1.0/IUsbGadget.h>
+#include <hidl/HidlTransportSupport.h>
+
#define PERSISTENT_USB_CONFIG "persist.sys.usb.config"
using android::base::GetProperty;
using android::base::SetProperty;
+using android::hardware::configureRpcThreadpool;
using android::hardware::usb::gadget::V1_0::GadgetFunction;
using android::hardware::usb::gadget::V1_0::IUsbGadget;
using android::hardware::Return;
int main(int /*argc*/, char** /*argv*/) {
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
android::sp<IUsbGadget> gadget = IUsbGadget::getService();
Return<void> ret;