Merge "Revert "Revert "Add a way to turn off unique_fd's operator int."""
This commit is contained in:
commit
fe1d1e815f
34 changed files with 403 additions and 310 deletions
|
@ -26,6 +26,7 @@ cc_defaults {
|
|||
"-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",
|
||||
|
||||
|
|
|
@ -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 @@ bool SendProtocolString(int fd, std::string_view s) {
|
|||
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 @@ bool ReadProtocolString(int fd, std::string* s, std::string* error) {
|
|||
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 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) {
|
|||
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 @@ bool WriteFdFmt(int fd, const char* fmt, ...) {
|
|||
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 @@ bool ReadOrderlyShutdown(int fd) {
|
|||
// 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.
|
||||
|
|
20
adb/adb_io.h
20
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 @@ bool ReadProtocolString(int fd, std::string* s, std::string* error);
|
|||
// 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 @@ bool ReadFdExactly(int fd, void* buf, size_t len);
|
|||
// 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 */
|
||||
|
|
|
@ -32,6 +32,8 @@ using unique_fd = android::base::unique_fd_impl<AdbCloser>;
|
|||
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")));
|
||||
|
|
|
@ -234,15 +234,15 @@ std::string perror_str(const char* msg) {
|
|||
|
||||
#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;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <android-base/macros.h>
|
||||
|
||||
#include "adb.h"
|
||||
#include "adb_unique_fd.h"
|
||||
|
||||
void close_stdin();
|
||||
|
||||
|
@ -51,7 +52,7 @@ std::string perror_str(const char* msg);
|
|||
[[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.
|
||||
|
|
|
@ -149,13 +149,13 @@ TEST(adb_utils, mkdirs) {
|
|||
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
|
||||
|
|
|
@ -128,7 +128,7 @@ static std::optional<TransportId> switch_socket_transport(int fd, std::string* e
|
|||
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)");
|
||||
|
|
|
@ -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 @@ int adb_send_emulator_command(int argc, const char* _Nonnull* _Nonnull argv,
|
|||
|
||||
// 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);
|
||||
|
|
|
@ -262,7 +262,7 @@ static void stdin_raw_restore() {
|
|||
// 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 @@ int read_and_dump(int fd, bool use_shell_protocol = false,
|
|||
}
|
||||
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 @@ static int adb_sideload_install(const char* filename, bool rescue_mode) {
|
|||
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 @@ static int logcat(int argc, const char** argv) {
|
|||
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 @@ static void write_zeros(int bytes, int fd) {
|
|||
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");
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ namespace {
|
|||
|
||||
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 @@ class AdbFdTextOutput : public android::TextOutput {
|
|||
}
|
||||
|
||||
private:
|
||||
int mFD;
|
||||
borrowed_fd fd_;
|
||||
};
|
||||
|
||||
std::vector<std::string_view> parseCmdArgs(std::string_view args) {
|
||||
|
@ -68,10 +68,11 @@ std::vector<std::string_view> parseCmdArgs(std::string_view args) {
|
|||
|
||||
} // 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[]) {
|
||||
|
|
|
@ -325,12 +325,12 @@ static int jdwp_control_init(JdwpControl* control, const char* sockname, int soc
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void reboot_service(unique_fd fd, const std::string& arg) {
|
|||
|
||||
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;
|
||||
|
|
|
@ -58,7 +58,7 @@ static bool make_block_device_writable(const std::string& dev) {
|
|||
}
|
||||
|
||||
int OFF = 0;
|
||||
bool result = (ioctl(fd, BLKROSET, &OFF) != -1);
|
||||
bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ void set_verity_enabled_state_service(unique_fd fd, bool enable) {
|
|||
}
|
||||
|
||||
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 @@ void set_verity_enabled_state_service(unique_fd fd, bool enable) {
|
|||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
|
|
|
@ -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 @@ bool Subprocess::ForkAndExec(std::string* error) {
|
|||
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 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
|
|||
}
|
||||
} 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 @@ void Subprocess::PassDataStreams() {
|
|||
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 @@ void Subprocess::PassDataStreams() {
|
|||
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 @@ void Subprocess::PassDataStreams() {
|
|||
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 @@ inline bool ValidAndInSet(const unique_fd& sfd, fd_set* set) {
|
|||
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 @@ unique_fd* Subprocess::SelectLoop(fd_set* master_read_set_ptr,
|
|||
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 @@ unique_fd* Subprocess::SelectLoop(fd_set* master_read_set_ptr,
|
|||
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 @@ unique_fd* Subprocess::PassInput() {
|
|||
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 @@ unique_fd* Subprocess::PassInput() {
|
|||
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 @@ unique_fd* Subprocess::PassInput() {
|
|||
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 @@ unique_fd* Subprocess::PassInput() {
|
|||
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 @@ unique_fd* Subprocess::PassOutput(unique_fd* sfd, ShellProtocol::Id id) {
|
|||
// 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_;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ unique_fd StartSubprocess(std::string name, const char* terminal_type, Subproces
|
|||
// 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.
|
||||
|
|
|
@ -77,7 +77,7 @@ void ShellServiceTest::StartTestCommandInProcess(std::string name, Command comma
|
|||
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 @@ std::string ReadRaw(int fd) {
|
|||
// 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:
|
||||
|
|
|
@ -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 @@ class ShellProtocol {
|
|||
// 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 @@ class ShellProtocol {
|
|||
kHeaderSize = sizeof(Id) + sizeof(length_t)
|
||||
};
|
||||
|
||||
int fd_;
|
||||
borrowed_fd fd_;
|
||||
char buffer_[kBufferSize];
|
||||
size_t data_length_ = 0, bytes_left_ = 0;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "adb_io.h"
|
||||
|
||||
ShellProtocol::ShellProtocol(int fd) : fd_(fd) {
|
||||
ShellProtocol::ShellProtocol(borrowed_fd fd) : fd_(fd) {
|
||||
buffer_[0] = kIdInvalid;
|
||||
}
|
||||
|
||||
|
|
|
@ -314,14 +314,14 @@ int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_
|
|||
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;
|
||||
|
|
228
adb/sysdeps.h
228
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 @@ static __inline__ bool adb_is_separator(char c) {
|
|||
|
||||
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 @@ static __inline__ int unix_read(int fd, void* buf, size_t len) {
|
|||
#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 @@ extern int unix_open(std::string_view path, int options, ...);
|
|||
// 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 @@ inline int network_local_server(const char* name, int namespace_id, int type, st
|
|||
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_fputs(const char* buf, FILE* stream);
|
|||
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 @@ static __inline__ bool adb_is_separator(char c) {
|
|||
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 @@ static __inline__ int unix_open(std::string_view path, int options, ...) {
|
|||
|
||||
// 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 @@ static __inline__ int adb_open_mode( const char* pathname, int options, int
|
|||
// 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 @@ static __inline__ int adb_shutdown(int fd, int direction = SHUT_RDWR) {
|
|||
__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 @@ inline int network_local_server(const char* name, int namespace_id, int type, st
|
|||
|
||||
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 @@ inline int adb_socket_get_local_port(int fd) {
|
|||
// 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 @@ static __inline__ int adb_thread_setname(const std::string& name) {
|
|||
#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 @@ static __inline__ int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
|
|||
|
||||
#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 @@ static __inline__ int adb_is_absolute_host_path(const char* path) {
|
|||
|
||||
#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.
|
||||
|
|
|
@ -104,13 +104,13 @@ static int _network_loopback_server(bool ipv6, int port, int type, std::string*
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ struct adb_iovec {
|
|||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -145,16 +145,14 @@ static std::mutex& _win32_lock = *new std::mutex();
|
|||
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 @@ _fh_from_int( int fd, const char* func )
|
|||
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 @@ _fh_from_int( int fd, const char* func )
|
|||
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 @@ _fh_alloc( FHClass clazz )
|
|||
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 @@ int adb_creat(const char* path, int mode) {
|
|||
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 @@ int adb_read(int fd, void* buf, int len) {
|
|||
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 @@ int adb_write(int fd, const void* buf, int len) {
|
|||
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 @@ ssize_t adb_writev(int fd, const adb_iovec* iov, int iovcnt) {
|
|||
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 @@ int adb_register_socket(SOCKET s) {
|
|||
}
|
||||
|
||||
#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 @@ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t* addrlen) {
|
|||
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 @@ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t* addrlen) {
|
|||
|
||||
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 @@ int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t
|
|||
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 @@ int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t
|
|||
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 adb_getsockname(int fd, struct sockaddr* sockaddr, socklen_t* optlen) {
|
|||
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 @@ int adb_getsockname(int fd, struct sockaddr* sockaddr, socklen_t* optlen) {
|
|||
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 @@ int adb_socket_get_local_port(int fd) {
|
|||
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 @@ int adb_shutdown(int fd, int direction) {
|
|||
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 @@ fail:
|
|||
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 @@ bool set_file_block_mode(int fd, bool block) {
|
|||
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 @@ bool set_tcp_keepalive(int fd, int interval_sec) {
|
|||
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 @@ bool set_tcp_keepalive(int fd, int interval_sec) {
|
|||
// 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 @@ static HANDLE _get_console_handle(int fd, DWORD* mode=nullptr) {
|
|||
// 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 @@ static HANDLE _get_console_handle(FILE* const stream) {
|
|||
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 @@ static char _get_decimal_char() {
|
|||
|
||||
// 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 @@ void stdin_raw_restore() {
|
|||
}
|
||||
|
||||
// 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 @@ int unix_read_interruptible(int fd, void* buf, size_t len) {
|
|||
// 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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ cc_defaults {
|
|||
name: "libbase_defaults",
|
||||
defaults: ["libbase_cflags_defaults"],
|
||||
srcs: [
|
||||
"abi_compatibility.cpp",
|
||||
"chrono_utils.cpp",
|
||||
"cmsg.cpp",
|
||||
"file.cpp",
|
||||
|
|
77
base/abi_compatibility.cpp
Normal file
77
base/abi_compatibility.cpp
Normal file
|
@ -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
|
|
@ -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 @@ ssize_t SendFileDescriptorVector(int sockfd, const void* data, size_t len,
|
|||
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 @@ ssize_t ReceiveFileDescriptorVector(int sockfd, void* data, size_t len, size_t m
|
|||
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;
|
||||
|
|
|
@ -176,20 +176,20 @@ namespace base {
|
|||
// 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 @@ bool ReadFileToString(const std::string& path, std::string* content, bool follow
|
|||
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 @@ bool WriteStringToFile(const std::string& content, const std::string& path,
|
|||
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 @@ bool ReadFully(int fd, void* data, size_t byte_count) {
|
|||
#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 @@ static ssize_t pread(int fd, void* data, size_t byte_count, off64_t offset) {
|
|||
}
|
||||
#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 @@ bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset) {
|
|||
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;
|
||||
|
|
|
@ -51,20 +51,20 @@ namespace base {
|
|||
// 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 @@ ssize_t SendFileDescriptors(int sock, const void* data, size_t len, Args&&... se
|
|||
// 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)...);
|
||||
|
||||
|
|
|
@ -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 @@ class TemporaryDir {
|
|||
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 WriteStringToFile(const std::string& content, const std::string& path,
|
|||
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 @@ bool ReadFully(int fd, void* data, size_t byte_count);
|
|||
// 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);
|
||||
|
||||
|
|
|
@ -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 @@ class MappedFile {
|
|||
* `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.
|
||||
|
|
|
@ -103,7 +103,17 @@ class unique_fd_impl final {
|
|||
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 @@ inline DIR* Fdopendir(unique_fd&& ufd) {
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
#include "android-base/unique_fd.h"
|
||||
|
||||
namespace android {
|
||||
namespace base {
|
||||
|
||||
|
@ -31,7 +33,8 @@ static off64_t InitPageSize() {
|
|||
#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 @@ std::unique_ptr<MappedFile> MappedFile::FromFd(int fd, off64_t offset, size_t le
|
|||
|
||||
#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 @@ std::unique_ptr<MappedFile> MappedFile::FromFd(int fd, off64_t offset, size_t le
|
|||
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.
|
||||
|
|
Loading…
Reference in a new issue