1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_ 18 #define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_ 19 20 #include <errno.h> 21 #include <memory> 22 #include <sys/types.h> 23 24 #include <base/logging.h> 25 26 // Abstraction for managing opening, reading, writing and closing of file 27 // descriptors. This includes an abstract class and one standard implementation 28 // based on POSIX system calls. 29 // 30 // TODO(garnold) this class is modeled after (and augments the functionality of) 31 // the FileWriter class; ultimately, the latter should be replaced by the former 32 // throughout the codebase. A few deviations from the original FileWriter: 33 // 34 // * Providing two flavors of Open() 35 // 36 // * A FileDescriptor is reusable and can be used to read/write multiple files 37 // as long as open/close preconditions are respected. 38 // 39 // * Write() returns the number of bytes written: this appears to be more useful 40 // for clients, who may wish to retry or otherwise do something useful with 41 // the remaining data that was not written. 42 // 43 // * Provides a Reset() method, which will force to abandon a currently open 44 // file descriptor and allow opening another file, without necessarily 45 // properly closing the old one. This may be useful in cases where a "closer" 46 // class does not care whether Close() was successful, but may need to reuse 47 // the same file descriptor again. 48 49 namespace chromeos_update_engine { 50 51 class FileDescriptor; 52 using FileDescriptorPtr = std::shared_ptr<FileDescriptor>; 53 54 // An abstract class defining the file descriptor API. 55 class FileDescriptor { 56 public: FileDescriptor()57 FileDescriptor() {} ~FileDescriptor()58 virtual ~FileDescriptor() {} 59 60 // Opens a file descriptor. The descriptor must be in the closed state prior 61 // to this call. Returns true on success, false otherwise. Specific 62 // implementations may set errno accordingly. 63 virtual bool Open(const char* path, int flags, mode_t mode) = 0; 64 virtual bool Open(const char* path, int flags) = 0; 65 66 // Reads from a file descriptor up to a given count. The descriptor must be 67 // open prior to this call. Returns the number of bytes read, or -1 on error. 68 // Specific implementations may set errno accordingly. 69 virtual ssize_t Read(void* buf, size_t count) = 0; 70 71 // Writes to a file descriptor. The descriptor must be open prior to this 72 // call. Returns the number of bytes written, or -1 if an error occurred and 73 // no bytes were written. Specific implementations may set errno accordingly. 74 virtual ssize_t Write(const void* buf, size_t count) = 0; 75 76 // Seeks to an offset. Returns the resulting offset location as measured in 77 // bytes from the beginning. On error, return -1. Specific implementations 78 // may set errno accordingly. 79 virtual off64_t Seek(off64_t offset, int whence) = 0; 80 81 // Runs a ioctl() on the file descriptor if supported. Returns whether 82 // the operation is supported. The |request| can be one of BLKDISCARD, 83 // BLKZEROOUT and BLKSECDISCARD to discard, write zeros or securely discard 84 // the blocks. These ioctls accept a range of bytes (|start| and |length|) 85 // over which they perform the operation. The return value from the ioctl is 86 // stored in |result|. 87 virtual bool BlkIoctl(int request, 88 uint64_t start, 89 uint64_t length, 90 int* result) = 0; 91 92 // Closes a file descriptor. The descriptor must be open prior to this call. 93 // Returns true on success, false otherwise. Specific implementations may set 94 // errno accordingly. 95 virtual bool Close() = 0; 96 97 // Resets the file descriptor, abandoning a currently open file and returning 98 // the descriptor to the closed state. 99 virtual void Reset() = 0; 100 101 // Indicates whether or not an implementation sets meaningful errno. 102 virtual bool IsSettingErrno() = 0; 103 104 // Indicates whether the descriptor is currently open. 105 virtual bool IsOpen() = 0; 106 107 private: 108 DISALLOW_COPY_AND_ASSIGN(FileDescriptor); 109 }; 110 111 // A simple EINTR-immune wrapper implementation around standard system calls. 112 class EintrSafeFileDescriptor : public FileDescriptor { 113 public: EintrSafeFileDescriptor()114 EintrSafeFileDescriptor() : fd_(-1) {} 115 116 // Interface methods. 117 bool Open(const char* path, int flags, mode_t mode) override; 118 bool Open(const char* path, int flags) override; 119 ssize_t Read(void* buf, size_t count) override; 120 ssize_t Write(const void* buf, size_t count) override; 121 off64_t Seek(off64_t offset, int whence) override; 122 bool BlkIoctl(int request, 123 uint64_t start, 124 uint64_t length, 125 int* result) override; 126 bool Close() override; 127 void Reset() override; IsSettingErrno()128 bool IsSettingErrno() override { 129 return true; 130 } IsOpen()131 bool IsOpen() override { 132 return (fd_ >= 0); 133 } 134 135 protected: 136 int fd_; 137 }; 138 139 } // namespace chromeos_update_engine 140 141 #endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_ 142