blob: 9a78cb9f5eb4b53cee7ef021e0f00c62f5b639fb [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <fbl/auto_call.h>
#include <fbl/unique_fd.h>
#include <lib/fdio/unsafe.h>
#include <lib/zx/channel.h>
#include <utility>
namespace fzl {
// Helper utility which borrows a file descriptor to allow the caller
// to make access to channel-based calls.
//
// FdioCaller consumes |fd|, but the same |fd| may be re-acquired by
// calling "release()" on the FdioCaller object.
class FdioCaller {
public:
FdioCaller() : io_(nullptr) {}
explicit FdioCaller(fbl::unique_fd fd) :
fd_(std::move(fd)), io_(fdio_unsafe_fd_to_io(fd_.get())) {}
~FdioCaller() {
release();
}
void reset(fbl::unique_fd fd) {
release();
fd_ = std::move(fd);
io_ = fdio_unsafe_fd_to_io(fd_.get());
}
fbl::unique_fd release() {
if (io_ != nullptr) {
fdio_unsafe_release(io_);
io_ = nullptr;
}
return std::move(fd_);
}
explicit operator bool() const {
return io_ != nullptr;
}
// This channel is borrowed, but returned as a zx_handle_t for convenience.
//
// It should not be closed.
// It should not be transferred.
// It should not be kept alive longer than the FdioCaller object, nor should
// it be kept alive after FdioCaller.release() is called.
zx_handle_t borrow_channel() const {
return fdio_unsafe_borrow_channel(io_);
}
FdioCaller& operator=(FdioCaller&& o) = delete;
FdioCaller(FdioCaller&& o) = delete;
FdioCaller(const FdioCaller&) = delete;
FdioCaller& operator=(const FdioCaller&) = delete;
private:
fbl::unique_fd fd_;
fdio_t* io_;
};
} // namespace fzl