mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Make StatusMatcher more flexible
PiperOrigin-RevId: 244879203 Change-Id: I5f7994130a898e84f041b18c0b5313d7e8b32780
This commit is contained in:
parent
726b1fb451
commit
6cbaaead8b
|
@ -23,61 +23,61 @@
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
sapi::Status RPCChannel::Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
|
::sapi::Status RPCChannel::Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
|
||||||
v::Type exp_type) {
|
v::Type exp_type) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (!comms_->SendTLV(tag, sizeof(call),
|
if (!comms_->SendTLV(tag, sizeof(call),
|
||||||
reinterpret_cast<const uint8_t*>(&call))) {
|
reinterpret_cast<const uint8_t*>(&call))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(exp_type));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(exp_type));
|
||||||
*ret = fret;
|
*ret = fret;
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
|
::sapi::StatusOr<FuncRet> RPCChannel::Return(v::Type exp_type) {
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
FuncRet ret;
|
FuncRet ret;
|
||||||
if (!comms_->RecvTLV(&tag, &len, &ret, sizeof(ret))) {
|
if (!comms_->RecvTLV(&tag, &len, &ret, sizeof(ret))) {
|
||||||
return sapi::UnavailableError("Receiving TLV value failed");
|
return ::sapi::UnavailableError("Receiving TLV value failed");
|
||||||
}
|
}
|
||||||
if (tag != comms::kMsgReturn) {
|
if (tag != comms::kMsgReturn) {
|
||||||
LOG(ERROR) << "tag != comms::kMsgReturn (" << absl::StrCat(absl::Hex(tag))
|
LOG(ERROR) << "tag != comms::kMsgReturn (" << absl::StrCat(absl::Hex(tag))
|
||||||
<< " != " << absl::StrCat(absl::Hex(comms::kMsgReturn)) << ")";
|
<< " != " << absl::StrCat(absl::Hex(comms::kMsgReturn)) << ")";
|
||||||
return sapi::UnavailableError("Received TLV has incorrect tag");
|
return ::sapi::UnavailableError("Received TLV has incorrect tag");
|
||||||
}
|
}
|
||||||
if (len != sizeof(FuncRet)) {
|
if (len != sizeof(FuncRet)) {
|
||||||
LOG(ERROR) << "len != sizeof(FuncReturn) (" << len
|
LOG(ERROR) << "len != sizeof(FuncReturn) (" << len
|
||||||
<< " != " << sizeof(FuncRet) << ")";
|
<< " != " << sizeof(FuncRet) << ")";
|
||||||
return sapi::UnavailableError("Received TLV has incorrect length");
|
return ::sapi::UnavailableError("Received TLV has incorrect length");
|
||||||
}
|
}
|
||||||
if (ret.ret_type != exp_type) {
|
if (ret.ret_type != exp_type) {
|
||||||
LOG(ERROR) << "FuncRet->type != exp_type (" << ret.ret_type
|
LOG(ERROR) << "FuncRet->type != exp_type (" << ret.ret_type
|
||||||
<< " != " << exp_type << ")";
|
<< " != " << exp_type << ")";
|
||||||
return sapi::UnavailableError("Received TLV has incorrect return type");
|
return ::sapi::UnavailableError("Received TLV has incorrect return type");
|
||||||
}
|
}
|
||||||
if (!ret.success) {
|
if (!ret.success) {
|
||||||
LOG(ERROR) << "FuncRet->success == false";
|
LOG(ERROR) << "FuncRet->success == false";
|
||||||
return sapi::UnavailableError("Function call failed");
|
return ::sapi::UnavailableError("Function call failed");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Allocate(size_t size, void** addr) {
|
::sapi::Status RPCChannel::Allocate(size_t size, void** addr) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
uint64_t sz = size;
|
uint64_t sz = size;
|
||||||
if (!comms_->SendTLV(comms::kMsgAllocate, sizeof(sz),
|
if (!comms_->SendTLV(comms::kMsgAllocate, sizeof(sz),
|
||||||
reinterpret_cast<uint8_t*>(&sz))) {
|
reinterpret_cast<uint8_t*>(&sz))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
|
||||||
*addr = reinterpret_cast<void*>(fret.int_val);
|
*addr = reinterpret_cast<void*>(fret.int_val);
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Reallocate(void* old_addr, size_t size,
|
::sapi::Status RPCChannel::Reallocate(void* old_addr, size_t size,
|
||||||
void** new_addr) {
|
void** new_addr) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
comms::ReallocRequest req;
|
comms::ReallocRequest req;
|
||||||
|
@ -86,54 +86,54 @@ sapi::Status RPCChannel::Reallocate(void* old_addr, size_t size,
|
||||||
|
|
||||||
if (!comms_->SendTLV(comms::kMsgReallocate, sizeof(comms::ReallocRequest),
|
if (!comms_->SendTLV(comms::kMsgReallocate, sizeof(comms::ReallocRequest),
|
||||||
reinterpret_cast<uint8_t*>(&req))) {
|
reinterpret_cast<uint8_t*>(&req))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fret_or = Return(v::Type::kPointer);
|
auto fret_or = Return(v::Type::kPointer);
|
||||||
if (!fret_or.ok()) {
|
if (!fret_or.ok()) {
|
||||||
*new_addr = nullptr;
|
*new_addr = nullptr;
|
||||||
return sapi::UnavailableError(
|
return ::sapi::UnavailableError(
|
||||||
absl::StrCat("Reallocate() failed on the remote side: ",
|
absl::StrCat("Reallocate() failed on the remote side: ",
|
||||||
fret_or.status().message()));
|
fret_or.status().message()));
|
||||||
}
|
}
|
||||||
auto fret = std::move(fret_or).ValueOrDie();
|
auto fret = std::move(fret_or).ValueOrDie();
|
||||||
|
|
||||||
*new_addr = reinterpret_cast<void*>(fret.int_val);
|
*new_addr = reinterpret_cast<void*>(fret.int_val);
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Free(void* addr) {
|
::sapi::Status RPCChannel::Free(void* addr) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
uint64_t remote = reinterpret_cast<uint64_t>(addr);
|
uint64_t remote = reinterpret_cast<uint64_t>(addr);
|
||||||
if (!comms_->SendTLV(comms::kMsgFree, sizeof(remote),
|
if (!comms_->SendTLV(comms::kMsgFree, sizeof(remote),
|
||||||
reinterpret_cast<uint8_t*>(&remote))) {
|
reinterpret_cast<uint8_t*>(&remote))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
||||||
if (!fret.success) {
|
if (!fret.success) {
|
||||||
return sapi::UnavailableError("Free() failed on the remote side");
|
return ::sapi::UnavailableError("Free() failed on the remote side");
|
||||||
}
|
}
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Symbol(const char* symname, void** addr) {
|
::sapi::Status RPCChannel::Symbol(const char* symname, void** addr) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (!comms_->SendTLV(comms::kMsgSymbol, strlen(symname) + 1,
|
if (!comms_->SendTLV(comms::kMsgSymbol, strlen(symname) + 1,
|
||||||
reinterpret_cast<const uint8_t*>(symname))) {
|
reinterpret_cast<const uint8_t*>(symname))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kPointer));
|
||||||
*addr = reinterpret_cast<void*>(fret.int_val);
|
*addr = reinterpret_cast<void*>(fret.int_val);
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Exit() {
|
::sapi::Status RPCChannel::Exit() {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (comms_->IsTerminated()) {
|
if (comms_->IsTerminated()) {
|
||||||
VLOG(2) << "Comms channel already terminated";
|
VLOG(2) << "Comms channel already terminated";
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try the RPC exit sequence. But, the only thing that matters as a success
|
// Try the RPC exit sequence. But, the only thing that matters as a success
|
||||||
|
@ -146,62 +146,62 @@ sapi::Status RPCChannel::Exit() {
|
||||||
if (!comms_->IsTerminated()) {
|
if (!comms_->IsTerminated()) {
|
||||||
LOG(ERROR) << "Comms channel not terminated in Exit()";
|
LOG(ERROR) << "Comms channel not terminated in Exit()";
|
||||||
// TODO(hamacher): Better error code
|
// TODO(hamacher): Better error code
|
||||||
return sapi::FailedPreconditionError(
|
return ::sapi::FailedPreconditionError(
|
||||||
"Comms channel not terminated in Exit()");
|
"Comms channel not terminated in Exit()");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::SendFD(int local_fd, int* remote_fd) {
|
::sapi::Status RPCChannel::SendFD(int local_fd, int* remote_fd) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
bool unused = true;
|
bool unused = true;
|
||||||
if (!comms_->SendTLV(comms::kMsgSendFd, sizeof(unused),
|
if (!comms_->SendTLV(comms::kMsgSendFd, sizeof(unused),
|
||||||
reinterpret_cast<uint8_t*>(&unused))) {
|
reinterpret_cast<uint8_t*>(&unused))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
if (!comms_->SendFD(local_fd)) {
|
if (!comms_->SendFD(local_fd)) {
|
||||||
return sapi::UnavailableError("Sending FD failed");
|
return ::sapi::UnavailableError("Sending FD failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kInt));
|
||||||
if (!fret.success) {
|
if (!fret.success) {
|
||||||
return sapi::UnavailableError("SendFD failed on the remote side");
|
return ::sapi::UnavailableError("SendFD failed on the remote side");
|
||||||
}
|
}
|
||||||
*remote_fd = fret.int_val;
|
*remote_fd = fret.int_val;
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::RecvFD(int remote_fd, int* local_fd) {
|
::sapi::Status RPCChannel::RecvFD(int remote_fd, int* local_fd) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (!comms_->SendTLV(comms::kMsgRecvFd, sizeof(remote_fd),
|
if (!comms_->SendTLV(comms::kMsgRecvFd, sizeof(remote_fd),
|
||||||
reinterpret_cast<uint8_t*>(&remote_fd))) {
|
reinterpret_cast<uint8_t*>(&remote_fd))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!comms_->RecvFD(local_fd)) {
|
if (!comms_->RecvFD(local_fd)) {
|
||||||
return sapi::UnavailableError("Receving FD failed");
|
return ::sapi::UnavailableError("Receving FD failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
||||||
if (!fret.success) {
|
if (!fret.success) {
|
||||||
return sapi::UnavailableError("RecvFD failed on the remote side");
|
return ::sapi::UnavailableError("RecvFD failed on the remote side");
|
||||||
}
|
}
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::Status RPCChannel::Close(int remote_fd) {
|
::sapi::Status RPCChannel::Close(int remote_fd) {
|
||||||
absl::MutexLock lock(&mutex_);
|
absl::MutexLock lock(&mutex_);
|
||||||
if (!comms_->SendTLV(comms::kMsgClose, sizeof(remote_fd),
|
if (!comms_->SendTLV(comms::kMsgClose, sizeof(remote_fd),
|
||||||
reinterpret_cast<uint8_t*>(&remote_fd))) {
|
reinterpret_cast<uint8_t*>(&remote_fd))) {
|
||||||
return sapi::UnavailableError("Sending TLV value failed");
|
return ::sapi::UnavailableError("Sending TLV value failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
SAPI_ASSIGN_OR_RETURN(auto fret, Return(v::Type::kVoid));
|
||||||
if (!fret.success) {
|
if (!fret.success) {
|
||||||
return sapi::UnavailableError("Close() failed on the remote side");
|
return ::sapi::UnavailableError("Close() failed on the remote side");
|
||||||
}
|
}
|
||||||
return sapi::OkStatus();
|
return ::sapi::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sapi
|
} // namespace sapi
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sandboxed_api/call.h"
|
#include "sandboxed_api/call.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/var_type.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
#include "sandboxed_api/util/status.h"
|
||||||
#include "sandboxed_api/util/statusor.h"
|
#include "sandboxed_api/util/statusor.h"
|
||||||
#include "sandboxed_api/var_type.h"
|
|
||||||
|
|
||||||
namespace sapi {
|
namespace sapi {
|
||||||
|
|
||||||
|
@ -33,38 +33,38 @@ class RPCChannel {
|
||||||
explicit RPCChannel(sandbox2::Comms* comms) : comms_(comms) {}
|
explicit RPCChannel(sandbox2::Comms* comms) : comms_(comms) {}
|
||||||
|
|
||||||
// Calls a function.
|
// Calls a function.
|
||||||
sapi::Status Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
|
::sapi::Status Call(const FuncCall& call, uint32_t tag, FuncRet* ret,
|
||||||
v::Type exp_type);
|
v::Type exp_type);
|
||||||
|
|
||||||
// Allocates memory.
|
// Allocates memory.
|
||||||
sapi::Status Allocate(size_t size, void** addr);
|
::sapi::Status Allocate(size_t size, void** addr);
|
||||||
|
|
||||||
// Reallocates memory.
|
// Reallocates memory.
|
||||||
sapi::Status Reallocate(void* old_addr, size_t size, void** new_addr);
|
::sapi::Status Reallocate(void* old_addr, size_t size, void** new_addr);
|
||||||
|
|
||||||
// Frees memory.
|
// Frees memory.
|
||||||
sapi::Status Free(void* addr);
|
::sapi::Status Free(void* addr);
|
||||||
|
|
||||||
// Returns address of a symbol.
|
// Returns address of a symbol.
|
||||||
sapi::Status Symbol(const char* symname, void** addr);
|
::sapi::Status Symbol(const char* symname, void** addr);
|
||||||
|
|
||||||
// Makes the remote part exit.
|
// Makes the remote part exit.
|
||||||
sapi::Status Exit();
|
::sapi::Status Exit();
|
||||||
|
|
||||||
// Transfers fd to sandboxee.
|
// Transfers fd to sandboxee.
|
||||||
sapi::Status SendFD(int local_fd, int* remote_fd);
|
::sapi::Status SendFD(int local_fd, int* remote_fd);
|
||||||
|
|
||||||
// Retrieves fd from sandboxee.
|
// Retrieves fd from sandboxee.
|
||||||
sapi::Status RecvFD(int remote_fd, int* local_fd);
|
::sapi::Status RecvFD(int remote_fd, int* local_fd);
|
||||||
|
|
||||||
// Closes fd in sandboxee.
|
// Closes fd in sandboxee.
|
||||||
sapi::Status Close(int remote_fd);
|
::sapi::Status Close(int remote_fd);
|
||||||
|
|
||||||
sandbox2::Comms* comms() const { return comms_; }
|
sandbox2::Comms* comms() const { return comms_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Receives the result after a call.
|
// Receives the result after a call.
|
||||||
sapi::StatusOr<FuncRet> Return(v::Type exp_type);
|
::sapi::StatusOr<FuncRet> Return(v::Type exp_type);
|
||||||
|
|
||||||
sandbox2::Comms* comms_; // Owned by sandbox2;
|
sandbox2::Comms* comms_; // Owned by sandbox2;
|
||||||
absl::Mutex mutex_;
|
absl::Mutex mutex_;
|
||||||
|
|
|
@ -526,6 +526,7 @@ cc_library(
|
||||||
"//sandboxed_api/sandbox2/util:strerror",
|
"//sandboxed_api/sandbox2/util:strerror",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"//sandboxed_api/util:status",
|
"//sandboxed_api/util:status",
|
||||||
|
"//sandboxed_api/util:status_proto",
|
||||||
"//sandboxed_api/util:statusor",
|
"//sandboxed_api/util:statusor",
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "absl/synchronization/mutex.h"
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
#include "sandboxed_api/util/status.h"
|
||||||
|
#include "sandboxed_api/util/status.pb.h"
|
||||||
|
|
||||||
namespace proto2 {
|
namespace proto2 {
|
||||||
class Message;
|
class Message;
|
||||||
|
|
|
@ -307,7 +307,7 @@ TEST_F(CommsTest, TestSendRecvStatusOK) {
|
||||||
};
|
};
|
||||||
auto b = [](Comms* comms) {
|
auto b = [](Comms* comms) {
|
||||||
// Send a good status.
|
// Send a good status.
|
||||||
ASSERT_THAT(comms->SendStatus(sapi::OkStatus()), IsTrue());
|
ASSERT_THAT(comms->SendStatus(::sapi::OkStatus()), IsTrue());
|
||||||
};
|
};
|
||||||
HandleCommunication(sockname_, a, b);
|
HandleCommunication(sockname_, a, b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,17 +33,17 @@ namespace {
|
||||||
constexpr absl::string_view kMktempSuffix = "XXXXXX";
|
constexpr absl::string_view kMktempSuffix = "XXXXXX";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
::sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
||||||
absl::string_view prefix) {
|
absl::string_view prefix) {
|
||||||
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
||||||
int fd = mkstemp(&name_template[0]);
|
int fd = mkstemp(&name_template[0]);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return sapi::UnknownError(absl::StrCat("mkstemp():", StrError(errno)));
|
return ::sapi::UnknownError(absl::StrCat("mkstemp():", StrError(errno)));
|
||||||
}
|
}
|
||||||
return std::pair<std::string, int>{std::move(name_template), fd};
|
return std::pair<std::string, int>{std::move(name_template), fd};
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
::sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
absl::string_view prefix) {
|
absl::string_view prefix) {
|
||||||
auto result_or = CreateNamedTempFile(prefix);
|
auto result_or = CreateNamedTempFile(prefix);
|
||||||
if (result_or.ok()) {
|
if (result_or.ok()) {
|
||||||
|
@ -56,10 +56,10 @@ sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
return result_or.status();
|
return result_or.status();
|
||||||
}
|
}
|
||||||
|
|
||||||
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
|
::sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix) {
|
||||||
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
std::string name_template = absl::StrCat(prefix, kMktempSuffix);
|
||||||
if (mkdtemp(&name_template[0]) == nullptr) {
|
if (mkdtemp(&name_template[0]) == nullptr) {
|
||||||
return sapi::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
|
return ::sapi::UnknownError(absl::StrCat("mkdtemp():", StrError(errno)));
|
||||||
}
|
}
|
||||||
return name_template;
|
return name_template;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,18 +23,18 @@ namespace sandbox2 {
|
||||||
|
|
||||||
// Creates a temporary file under a path starting with prefix. File is not
|
// Creates a temporary file under a path starting with prefix. File is not
|
||||||
// unlinked and its path is returned together with an open fd.
|
// unlinked and its path is returned together with an open fd.
|
||||||
sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
::sapi::StatusOr<std::pair<std::string, int>> CreateNamedTempFile(
|
||||||
absl::string_view prefix);
|
absl::string_view prefix);
|
||||||
|
|
||||||
// Creates a temporary file under a path starting with prefix. File is not
|
// Creates a temporary file under a path starting with prefix. File is not
|
||||||
// unlinked and its path is returned. FD of the created file is closed just
|
// unlinked and its path is returned. FD of the created file is closed just
|
||||||
// after creation.
|
// after creation.
|
||||||
sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
::sapi::StatusOr<std::string> CreateNamedTempFileAndClose(
|
||||||
absl::string_view prefix);
|
absl::string_view prefix);
|
||||||
|
|
||||||
// Creates a temporary directory under a path starting with prefix.
|
// Creates a temporary directory under a path starting with prefix.
|
||||||
// Returns the path of the created directory.
|
// Returns the path of the created directory.
|
||||||
sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
|
::sapi::StatusOr<std::string> CreateTempDir(absl::string_view prefix);
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "sandboxed_api/util/status_matchers.h"
|
#include "sandboxed_api/util/status_matchers.h"
|
||||||
|
|
||||||
using sapi::IsOk;
|
using sapi::IsOk;
|
||||||
|
using sapi::StatusIs;
|
||||||
using testing::Eq;
|
using testing::Eq;
|
||||||
using testing::IsTrue;
|
using testing::IsTrue;
|
||||||
using testing::Ne;
|
using testing::Ne;
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SANDBOXED_API_UTIL_STATUS_MATCHERS_H_
|
#ifndef SANDBOXED_API_UTIL_STATUS_MATCHERS_H_
|
||||||
#define SANDBOXED_API_UTIL_STATUS_MATCHERS_H_
|
#define SANDBOXED_API_UTIL_STATUS_MATCHERS_H_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "sandboxed_api/util/status.h"
|
#include "sandboxed_api/util/status.h"
|
||||||
|
@ -59,9 +61,10 @@ class StatusIsMatcher {
|
||||||
StatusIsMatcher(Enum code, absl::optional<absl::string_view> message)
|
StatusIsMatcher(Enum code, absl::optional<absl::string_view> message)
|
||||||
: code_{code}, message_{message} {}
|
: code_{code}, message_{message} {}
|
||||||
|
|
||||||
template <typename StatusT>
|
template <typename T>
|
||||||
bool MatchAndExplain(const StatusT& status,
|
bool MatchAndExplain(const T& value,
|
||||||
::testing::MatchResultListener* listener) const {
|
::testing::MatchResultListener* listener) const {
|
||||||
|
auto status = GetStatus(value);
|
||||||
if (code_ != status.code()) {
|
if (code_ != status.code()) {
|
||||||
*listener << "whose error code is generic::"
|
*listener << "whose error code is generic::"
|
||||||
<< internal::CodeEnumToString(status.code());
|
<< internal::CodeEnumToString(status.code());
|
||||||
|
@ -74,12 +77,6 @@ class StatusIsMatcher {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool MatchAndExplain(const StatusOr<T>& status_or,
|
|
||||||
::testing::MatchResultListener* listener) const {
|
|
||||||
return MatchAndExplain(status_or.status(), listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DescribeTo(std::ostream* os) const {
|
void DescribeTo(std::ostream* os) const {
|
||||||
*os << "has a status code that is generic::"
|
*os << "has a status code that is generic::"
|
||||||
<< internal::CodeEnumToString(code_);
|
<< internal::CodeEnumToString(code_);
|
||||||
|
@ -98,6 +95,20 @@ class StatusIsMatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename StatusT,
|
||||||
|
typename std::enable_if<
|
||||||
|
!std::is_void<decltype(std::declval<StatusT>().code())>::value,
|
||||||
|
int>::type = 0>
|
||||||
|
static const StatusT& GetStatus(const StatusT& status) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StatusOrT,
|
||||||
|
typename StatusT = decltype(std::declval<StatusOrT>().status())>
|
||||||
|
static StatusT GetStatus(const StatusOrT& status_or) {
|
||||||
|
return status_or.status();
|
||||||
|
}
|
||||||
|
|
||||||
const Enum code_;
|
const Enum code_;
|
||||||
const absl::optional<std::string> message_;
|
const absl::optional<std::string> message_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user