blob: cbea6034b5e42ef2c28c5d552fb4933312a8d34a [file] [log] [blame]
// Copyright 2017 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.
#ifndef FBL_UNIQUE_FD_H_
#define FBL_UNIQUE_FD_H_
#include <stdlib.h>
#include <unistd.h>
#include <fbl/macros.h>
namespace fbl {
// A scoped file descriptor that automatically closes when it goes
// out of scope.
class unique_fd {
public:
constexpr unique_fd() : fd_(InvalidValue()) {}
explicit unique_fd(int fd) : fd_(fd) { }
static constexpr int InvalidValue() { return -1; }
~unique_fd() {
reset();
}
unique_fd(unique_fd&& o) : fd_(o.release()) {}
unique_fd& operator=(unique_fd&& o) {
reset(o.release());
return *this;
}
// Comparison against raw file descriptors (of the form fd == unique_fd)
bool operator==(int fd) const { return (fd_ == fd); }
bool operator!=(int fd) const { return (fd_ != fd); }
// Comparison against other unique_fd's.
bool operator==(const unique_fd& o) const { return fd_ == o.fd_; }
bool operator!=(const unique_fd& o) const { return fd_ != o.fd_; }
// move semantics only
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(unique_fd);
fbl::unique_fd duplicate() const {
return fbl::unique_fd(dup(fd_));
}
int release() {
int t = fd_;
fd_ = InvalidValue();
return t;
}
void reset(int t = InvalidValue()) {
if (fd_ != InvalidValue()) {
close(fd_);
}
fd_ = t;
}
void swap(unique_fd& other) {
int t = fd_;
fd_ = other.fd_;
other.fd_ = t;
}
int get() const {
return fd_;
}
bool is_valid() const {
return fd_ != InvalidValue();
}
explicit operator bool() const {
return is_valid();
}
explicit operator int() const {
return fd_;
}
private:
int fd_;
};
} // namespace fbl
#endif // FBL_UNIQUE_FD_H_