1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <stdlib.h> 8 #include <unistd.h> 9 10 #include <fbl/macros.h> 11 #include <fbl/type_support.h> 12 13 namespace fbl { 14 15 // A scoped file descriptor that automatically closes when it goes 16 // out of scope. 17 class unique_fd { 18 public: unique_fd()19 constexpr unique_fd() : fd_(InvalidValue()) {} unique_fd(int fd)20 explicit unique_fd(int fd) : fd_(fd) { } 21 InvalidValue()22 static constexpr int InvalidValue() { return -1; } 23 ~unique_fd()24 ~unique_fd() { 25 reset(); 26 } 27 unique_fd(unique_fd && o)28 unique_fd(unique_fd&& o) : fd_(o.release()) {} 29 unique_fd& operator=(unique_fd&& o) { 30 reset(o.release()); 31 return *this; 32 } 33 34 // Comparison against raw file descriptors (of the form fd == unique_fd) 35 bool operator==(int fd) const { return (fd_ == fd); } 36 bool operator!=(int fd) const { return (fd_ != fd); } 37 38 // Comparison against other unique_fd's. 39 bool operator==(const unique_fd& o) const { return fd_ == o.fd_; } 40 bool operator!=(const unique_fd& o) const { return fd_ != o.fd_; } 41 42 // move semantics only 43 DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(unique_fd); 44 duplicate()45 fbl::unique_fd duplicate() { 46 return fbl::unique_fd(dup(fd_)); 47 } 48 release()49 int release() { 50 int t = fd_; 51 fd_ = InvalidValue(); 52 return t; 53 } 54 55 void reset(int t = InvalidValue()) { 56 if (fd_ != InvalidValue()) { 57 close(fd_); 58 } 59 fd_ = t; 60 } 61 swap(unique_fd & other)62 void swap(unique_fd& other) { 63 int t = fd_; 64 fd_ = other.fd_; 65 other.fd_ = t; 66 } 67 get()68 int get() const { 69 return fd_; 70 } 71 is_valid()72 bool is_valid() const { 73 return fd_ != InvalidValue(); 74 } 75 76 explicit operator bool() const { 77 return is_valid(); 78 } 79 80 explicit operator int() const { 81 return fd_; 82 } 83 84 private: 85 int fd_; 86 }; 87 88 } // namespace fbl 89