Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9b1f9eb authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "libbinder: Stricter protocol and code for receiving FDs" am: 44f97a53...

Merge "libbinder: Stricter protocol and code for receiving FDs" am: 44f97a53 am: 9b53f343 am: d035dba0 am: 171f0038 am: b0b8e377

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2140048



Change-Id: I73c1227303aa85921d45937952695f7ef8033f0f
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b82e1918 b0b8e377
Loading
Loading
Loading
Loading
+6 −9
Original line number Original line Diff line number Diff line
@@ -2486,10 +2486,10 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const bin
    scanForFds();
    scanForFds();
}
}


status_t Parcel::rpcSetDataReference(const sp<RpcSession>& session, const uint8_t* data,
status_t Parcel::rpcSetDataReference(
                                     size_t dataSize, const uint32_t* objectTable,
        const sp<RpcSession>& session, const uint8_t* data, size_t dataSize,
                                     size_t objectTableSize,
        const uint32_t* objectTable, size_t objectTableSize,
                                     std::vector<base::unique_fd> ancillaryFds,
        std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds,
        release_func relFunc) {
        release_func relFunc) {
    // this code uses 'mOwner == nullptr' to understand whether it owns memory
    // this code uses 'mOwner == nullptr' to understand whether it owns memory
    LOG_ALWAYS_FATAL_IF(relFunc == nullptr, "must provide cleanup function");
    LOG_ALWAYS_FATAL_IF(relFunc == nullptr, "must provide cleanup function");
@@ -2518,10 +2518,7 @@ status_t Parcel::rpcSetDataReference(const sp<RpcSession>& session, const uint8_
    }
    }
    if (!ancillaryFds.empty()) {
    if (!ancillaryFds.empty()) {
        rpcFields->mFds = std::make_unique<decltype(rpcFields->mFds)::element_type>();
        rpcFields->mFds = std::make_unique<decltype(rpcFields->mFds)::element_type>();
        rpcFields->mFds->reserve(ancillaryFds.size());
        *rpcFields->mFds = std::move(ancillaryFds);
        for (auto& fd : ancillaryFds) {
            rpcFields->mFds->push_back(std::move(fd));
        }
    }
    }


    return OK;
    return OK;
+2 −2
Original line number Original line Diff line number Diff line
@@ -300,7 +300,7 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie
    if (status == OK) {
    if (status == OK) {
        iovec iov{&header, sizeof(header)};
        iovec iov{&header, sizeof(header)};
        status = client->interruptableReadFully(server->mShutdownTrigger.get(), &iov, 1,
        status = client->interruptableReadFully(server->mShutdownTrigger.get(), &iov, 1,
                                                std::nullopt, /*enableAncillaryFds=*/false);
                                                std::nullopt, /*ancillaryFds=*/nullptr);
        if (status != OK) {
        if (status != OK) {
            ALOGE("Failed to read ID for client connecting to RPC server: %s",
            ALOGE("Failed to read ID for client connecting to RPC server: %s",
                  statusToString(status).c_str());
                  statusToString(status).c_str());
@@ -315,7 +315,7 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie
                sessionId.resize(header.sessionIdSize);
                sessionId.resize(header.sessionIdSize);
                iovec iov{sessionId.data(), sessionId.size()};
                iovec iov{sessionId.data(), sessionId.size()};
                status = client->interruptableReadFully(server->mShutdownTrigger.get(), &iov, 1,
                status = client->interruptableReadFully(server->mShutdownTrigger.get(), &iov, 1,
                                                        std::nullopt, /*enableAncillaryFds=*/false);
                                                        std::nullopt, /*ancillaryFds=*/nullptr);
                if (status != OK) {
                if (status != OK) {
                    ALOGE("Failed to read session ID for client connecting to RPC server: %s",
                    ALOGE("Failed to read session ID for client connecting to RPC server: %s",
                          statusToString(status).c_str());
                          statusToString(status).c_str());
+54 −42
Original line number Original line Diff line number Diff line
@@ -346,11 +346,14 @@ status_t RpcState::rpcSend(
    return OK;
    return OK;
}
}


status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::rpcRec(
                          const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs) {
        const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
    if (status_t status = connection->rpcTransport->interruptableReadFully(
        const char* what, iovec* iovs, int niovs,
                session->mShutdownTrigger.get(), iovs, niovs, std::nullopt,
        std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
                enableAncillaryFds(session->getFileDescriptorTransportMode()));
    if (status_t status =
                connection->rpcTransport->interruptableReadFully(session->mShutdownTrigger.get(),
                                                                 iovs, niovs, std::nullopt,
                                                                 ancillaryFds);
        status != OK) {
        status != OK) {
        LOG_RPC_DETAIL("Failed to read %s (%d iovs) on RpcTransport %p, error: %s", what, niovs,
        LOG_RPC_DETAIL("Failed to read %s (%d iovs) on RpcTransport %p, error: %s", what, niovs,
                       connection->rpcTransport.get(), statusToString(status).c_str());
                       connection->rpcTransport.get(), statusToString(status).c_str());
@@ -370,7 +373,7 @@ status_t RpcState::readNewSessionResponse(const sp<RpcSession::RpcConnection>& c
                                          const sp<RpcSession>& session, uint32_t* version) {
                                          const sp<RpcSession>& session, uint32_t* version) {
    RpcNewSessionResponse response;
    RpcNewSessionResponse response;
    iovec iov{&response, sizeof(response)};
    iovec iov{&response, sizeof(response)};
    if (status_t status = rpcRec(connection, session, "new session response", &iov, 1);
    if (status_t status = rpcRec(connection, session, "new session response", &iov, 1, nullptr);
        status != OK) {
        status != OK) {
        return status;
        return status;
    }
    }
@@ -391,7 +394,8 @@ status_t RpcState::readConnectionInit(const sp<RpcSession::RpcConnection>& conne
                                      const sp<RpcSession>& session) {
                                      const sp<RpcSession>& session) {
    RpcOutgoingConnectionInit init;
    RpcOutgoingConnectionInit init;
    iovec iov{&init, sizeof(init)};
    iovec iov{&init, sizeof(init)};
    if (status_t status = rpcRec(connection, session, "connection init", &iov, 1); status != OK)
    if (status_t status = rpcRec(connection, session, "connection init", &iov, 1, nullptr);
        status != OK)
        return status;
        return status;


    static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY));
    static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY));
@@ -589,18 +593,26 @@ static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,


status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
                                const sp<RpcSession>& session, Parcel* reply) {
                                const sp<RpcSession>& session, Parcel* reply) {
    std::vector<std::variant<base::unique_fd, base::borrowed_fd>> ancillaryFds;
    RpcWireHeader command;
    RpcWireHeader command;
    while (true) {
    while (true) {
        iovec iov{&command, sizeof(command)};
        iovec iov{&command, sizeof(command)};
        if (status_t status = rpcRec(connection, session, "command header (for reply)", &iov, 1);
        if (status_t status = rpcRec(connection, session, "command header (for reply)", &iov, 1,
                                     enableAncillaryFds(session->getFileDescriptorTransportMode())
                                             ? &ancillaryFds
                                             : nullptr);
            status != OK)
            status != OK)
            return status;
            return status;


        if (command.command == RPC_COMMAND_REPLY) break;
        if (command.command == RPC_COMMAND_REPLY) break;


        if (status_t status = processCommand(connection, session, command, CommandType::ANY);
        if (status_t status = processCommand(connection, session, command, CommandType::ANY,
                                             std::move(ancillaryFds));
            status != OK)
            status != OK)
            return status;
            return status;

        // Reset to avoid spurious use-after-move warning from clang-tidy.
        ancillaryFds = decltype(ancillaryFds)();
    }
    }


    const size_t rpcReplyWireSize = RpcWireReply::wireSize(session->getProtocolVersion().value());
    const size_t rpcReplyWireSize = RpcWireReply::wireSize(session->getProtocolVersion().value());
@@ -622,17 +634,10 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
            {&rpcReply, rpcReplyWireSize},
            {&rpcReply, rpcReplyWireSize},
            {data.data(), data.size()},
            {data.data(), data.size()},
    };
    };
    if (status_t status = rpcRec(connection, session, "reply body", iovs, arraysize(iovs));
    if (status_t status = rpcRec(connection, session, "reply body", iovs, arraysize(iovs), nullptr);
        status != OK)
        status != OK)
        return status;
        return status;


    // Check if the reply came with any ancillary data.
    std::vector<base::unique_fd> pendingFds;
    if (status_t status = connection->rpcTransport->consumePendingAncillaryData(&pendingFds);
        status != OK) {
        return status;
    }

    if (rpcReply.status != OK) return rpcReply.status;
    if (rpcReply.status != OK) return rpcReply.status;


    Span<const uint8_t> parcelSpan = {data.data(), data.size()};
    Span<const uint8_t> parcelSpan = {data.data(), data.size()};
@@ -655,7 +660,7 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
    data.release();
    data.release();
    return reply->rpcSetDataReference(session, parcelSpan.data, parcelSpan.size,
    return reply->rpcSetDataReference(session, parcelSpan.data, parcelSpan.size,
                                      objectTableSpan.data, objectTableSpan.size,
                                      objectTableSpan.data, objectTableSpan.size,
                                      std::move(pendingFds), cleanup_reply_data);
                                      std::move(ancillaryFds), cleanup_reply_data);
}
}


status_t RpcState::sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& connection,
@@ -698,13 +703,17 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con
                                        const sp<RpcSession>& session, CommandType type) {
                                        const sp<RpcSession>& session, CommandType type) {
    LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get());
    LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get());


    std::vector<std::variant<base::unique_fd, base::borrowed_fd>> ancillaryFds;
    RpcWireHeader command;
    RpcWireHeader command;
    iovec iov{&command, sizeof(command)};
    iovec iov{&command, sizeof(command)};
    if (status_t status = rpcRec(connection, session, "command header (for server)", &iov, 1);
    if (status_t status =
                rpcRec(connection, session, "command header (for server)", &iov, 1,
                       enableAncillaryFds(session->getFileDescriptorTransportMode()) ? &ancillaryFds
                                                                                     : nullptr);
        status != OK)
        status != OK)
        return status;
        return status;


    return processCommand(connection, session, command, type);
    return processCommand(connection, session, command, type, std::move(ancillaryFds));
}
}


status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
@@ -720,9 +729,10 @@ status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection
    return OK;
    return OK;
}
}


status_t RpcState::processCommand(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::processCommand(
                                  const sp<RpcSession>& session, const RpcWireHeader& command,
        const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
                                  CommandType type) {
        const RpcWireHeader& command, CommandType type,
        std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds) {
    IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
    IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
    IPCThreadState::SpGuard spGuard{
    IPCThreadState::SpGuard spGuard{
            .address = __builtin_frame_address(0),
            .address = __builtin_frame_address(0),
@@ -741,7 +751,7 @@ status_t RpcState::processCommand(const sp<RpcSession::RpcConnection>& connectio
    switch (command.command) {
    switch (command.command) {
        case RPC_COMMAND_TRANSACT:
        case RPC_COMMAND_TRANSACT:
            if (type != CommandType::ANY) return BAD_TYPE;
            if (type != CommandType::ANY) return BAD_TYPE;
            return processTransact(connection, session, command);
            return processTransact(connection, session, command, std::move(ancillaryFds));
        case RPC_COMMAND_DEC_STRONG:
        case RPC_COMMAND_DEC_STRONG:
            return processDecStrong(connection, session, command);
            return processDecStrong(connection, session, command);
    }
    }
@@ -755,8 +765,10 @@ status_t RpcState::processCommand(const sp<RpcSession::RpcConnection>& connectio
    (void)session->shutdownAndWait(false);
    (void)session->shutdownAndWait(false);
    return DEAD_OBJECT;
    return DEAD_OBJECT;
}
}
status_t RpcState::processTransact(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::processTransact(
                                   const sp<RpcSession>& session, const RpcWireHeader& command) {
        const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
        const RpcWireHeader& command,
        std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds) {
    LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_TRANSACT, "command: %d", command.command);
    LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_TRANSACT, "command: %d", command.command);


    CommandData transactionData(command.bodySize);
    CommandData transactionData(command.bodySize);
@@ -764,10 +776,12 @@ status_t RpcState::processTransact(const sp<RpcSession::RpcConnection>& connecti
        return NO_MEMORY;
        return NO_MEMORY;
    }
    }
    iovec iov{transactionData.data(), transactionData.size()};
    iovec iov{transactionData.data(), transactionData.size()};
    if (status_t status = rpcRec(connection, session, "transaction body", &iov, 1); status != OK)
    if (status_t status = rpcRec(connection, session, "transaction body", &iov, 1, nullptr);
        status != OK)
        return status;
        return status;


    return processTransactInternal(connection, session, std::move(transactionData));
    return processTransactInternal(connection, session, std::move(transactionData),
                                   std::move(ancillaryFds));
}
}


static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
@@ -779,9 +793,10 @@ static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t d
    (void)objectsCount;
    (void)objectsCount;
}
}


status_t RpcState::processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
status_t RpcState::processTransactInternal(
                                           const sp<RpcSession>& session,
        const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
                                           CommandData transactionData) {
        CommandData transactionData,
        std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds) {
    // for 'recursive' calls to this, we have already read and processed the
    // for 'recursive' calls to this, we have already read and processed the
    // binder from the transaction data and taken reference counts into account,
    // binder from the transaction data and taken reference counts into account,
    // so it is cached here.
    // so it is cached here.
@@ -869,13 +884,6 @@ processTransactInternalTailCall:
    reply.markForRpc(session);
    reply.markForRpc(session);


    if (replyStatus == OK) {
    if (replyStatus == OK) {
        // Check if the transaction came with any ancillary data.
        std::vector<base::unique_fd> pendingFds;
        if (status_t status = connection->rpcTransport->consumePendingAncillaryData(&pendingFds);
            status != OK) {
            return status;
        }

        Span<const uint8_t> parcelSpan = {transaction->data,
        Span<const uint8_t> parcelSpan = {transaction->data,
                                          transactionData.size() -
                                          transactionData.size() -
                                                  offsetof(RpcWireTransaction, data)};
                                                  offsetof(RpcWireTransaction, data)};
@@ -901,9 +909,12 @@ processTransactInternalTailCall:
        // only holds onto it for the duration of this function call. Parcel will be
        // only holds onto it for the duration of this function call. Parcel will be
        // deleted before the 'transactionData' object.
        // deleted before the 'transactionData' object.


        replyStatus = data.rpcSetDataReference(session, parcelSpan.data, parcelSpan.size,
        replyStatus =
                data.rpcSetDataReference(session, parcelSpan.data, parcelSpan.size,
                                         objectTableSpan.data, objectTableSpan.size,
                                         objectTableSpan.data, objectTableSpan.size,
                                               std::move(pendingFds), do_nothing_to_transact_data);
                                         std::move(ancillaryFds), do_nothing_to_transact_data);
        // Reset to avoid spurious use-after-move warning from clang-tidy.
        ancillaryFds = std::remove_reference<decltype(ancillaryFds)>::type();


        if (replyStatus == OK) {
        if (replyStatus == OK) {
            if (target) {
            if (target) {
@@ -1073,7 +1084,8 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect


    RpcDecStrong body;
    RpcDecStrong body;
    iovec iov{&body, sizeof(RpcDecStrong)};
    iovec iov{&body, sizeof(RpcDecStrong)};
    if (status_t status = rpcRec(connection, session, "dec ref body", &iov, 1); status != OK)
    if (status_t status = rpcRec(connection, session, "dec ref body", &iov, 1, nullptr);
        status != OK)
        return status;
        return status;


    uint64_t addr = RpcWireAddress::toRaw(body.address);
    uint64_t addr = RpcWireAddress::toRaw(body.address);
+16 −12
Original line number Original line Diff line number Diff line
@@ -184,21 +184,25 @@ private:
            const std::optional<android::base::function_ref<status_t()>>& altPoll,
            const std::optional<android::base::function_ref<status_t()>>& altPoll,
            const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds =
            const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds =
                    nullptr);
                    nullptr);
    [[nodiscard]] status_t rpcRec(const sp<RpcSession::RpcConnection>& connection,
    [[nodiscard]] status_t rpcRec(
                                  const sp<RpcSession>& session, const char* what, iovec* iovs,
            const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
                                  int niovs);
            const char* what, iovec* iovs, int niovs,
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds = nullptr);


    [[nodiscard]] status_t waitForReply(const sp<RpcSession::RpcConnection>& connection,
    [[nodiscard]] status_t waitForReply(const sp<RpcSession::RpcConnection>& connection,
                                        const sp<RpcSession>& session, Parcel* reply);
                                        const sp<RpcSession>& session, Parcel* reply);
    [[nodiscard]] status_t processCommand(const sp<RpcSession::RpcConnection>& connection,
    [[nodiscard]] status_t processCommand(
                                          const sp<RpcSession>& session,
            const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
                                          const RpcWireHeader& command, CommandType type);
            const RpcWireHeader& command, CommandType type,
    [[nodiscard]] status_t processTransact(const sp<RpcSession::RpcConnection>& connection,
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds);
                                           const sp<RpcSession>& session,
    [[nodiscard]] status_t processTransact(
                                           const RpcWireHeader& command);
            const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
    [[nodiscard]] status_t processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
            const RpcWireHeader& command,
                                                   const sp<RpcSession>& session,
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds);
                                                   CommandData transactionData);
    [[nodiscard]] status_t processTransactInternal(
            const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
            CommandData transactionData,
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>&& ancillaryFds);
    [[nodiscard]] status_t processDecStrong(const sp<RpcSession::RpcConnection>& connection,
    [[nodiscard]] status_t processDecStrong(const sp<RpcSession::RpcConnection>& connection,
                                            const sp<RpcSession>& session,
                                            const sp<RpcSession>& session,
                                            const RpcWireHeader& command);
                                            const RpcWireHeader& command);
+5 −13
Original line number Original line Diff line number Diff line
@@ -204,9 +204,9 @@ public:
    status_t interruptableReadFully(
    status_t interruptableReadFully(
            FdTrigger* fdTrigger, iovec* iovs, int niovs,
            FdTrigger* fdTrigger, iovec* iovs, int niovs,
            const std::optional<android::base::function_ref<status_t()>>& altPoll,
            const std::optional<android::base::function_ref<status_t()>>& altPoll,
            bool enableAncillaryFds) override {
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) override {
        auto recv = [&](iovec* iovs, int niovs) -> ssize_t {
        auto recv = [&](iovec* iovs, int niovs) -> ssize_t {
            if (enableAncillaryFds) {
            if (ancillaryFds != nullptr) {
                int fdBuffer[kMaxFdsPerMsg];
                int fdBuffer[kMaxFdsPerMsg];
                alignas(struct cmsghdr) char msgControlBuf[CMSG_SPACE(sizeof(fdBuffer))];
                alignas(struct cmsghdr) char msgControlBuf[CMSG_SPACE(sizeof(fdBuffer))];


@@ -228,10 +228,12 @@ public:
                        // NOTE: It is tempting to reinterpret_cast, but cmsg(3) explicitly asks
                        // NOTE: It is tempting to reinterpret_cast, but cmsg(3) explicitly asks
                        // application devs to memcpy the data to ensure memory alignment.
                        // application devs to memcpy the data to ensure memory alignment.
                        size_t dataLen = cmsg->cmsg_len - CMSG_LEN(0);
                        size_t dataLen = cmsg->cmsg_len - CMSG_LEN(0);
                        LOG_ALWAYS_FATAL_IF(dataLen > sizeof(fdBuffer)); // sanity check
                        memcpy(fdBuffer, CMSG_DATA(cmsg), dataLen);
                        memcpy(fdBuffer, CMSG_DATA(cmsg), dataLen);
                        size_t fdCount = dataLen / sizeof(int);
                        size_t fdCount = dataLen / sizeof(int);
                        ancillaryFds->reserve(ancillaryFds->size() + fdCount);
                        for (size_t i = 0; i < fdCount; i++) {
                        for (size_t i = 0; i < fdCount; i++) {
                            mFdsPendingRead.emplace_back(fdBuffer[i]);
                            ancillaryFds->emplace_back(base::unique_fd(fdBuffer[i]));
                        }
                        }
                        break;
                        break;
                    }
                    }
@@ -256,18 +258,8 @@ public:
        return interruptableReadOrWrite(fdTrigger, iovs, niovs, recv, "recvmsg", POLLIN, altPoll);
        return interruptableReadOrWrite(fdTrigger, iovs, niovs, recv, "recvmsg", POLLIN, altPoll);
    }
    }


    status_t consumePendingAncillaryData(std::vector<base::unique_fd>* fds) override {
        fds->reserve(fds->size() + mFdsPendingRead.size());
        for (auto& fd : mFdsPendingRead) {
            fds->emplace_back(std::move(fd));
        }
        mFdsPendingRead.clear();
        return OK;
    }

private:
private:
    base::unique_fd mSocket;
    base::unique_fd mSocket;
    std::vector<base::unique_fd> mFdsPendingRead;
};
};


// RpcTransportCtx with TLS disabled.
// RpcTransportCtx with TLS disabled.
Loading