1 /* 2 * Copyright 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 BCC_SUPPORT_FILE_BASE_H 18 #define BCC_SUPPORT_FILE_BASE_H 19 20 #include <fcntl.h> 21 #include <unistd.h> 22 #include <string> 23 #include <system_error> 24 25 namespace android { 26 class FileMap; 27 } 28 29 namespace bcc { 30 31 class FileBase { 32 public: 33 enum OpenModeEnum { 34 kReadMode = 1 << 0, 35 kWriteMode = 1 << 1, 36 kReadWriteMode = (kReadMode | kWriteMode), 37 }; 38 39 enum FlagEnum { 40 kBinary = 1 << 0, 41 kTruncate = 1 << 1, 42 kAppend = 1 << 2, 43 kDeleteOnClose = 1 << 3 44 }; 45 46 enum LockModeEnum { 47 // The shared resource behind the Stream locked in ReadLock mode can be 48 // locked by other processes at the same time. 49 kReadLock, 50 51 // The shared resource behind the Stream locked in WriteLock mode can only 52 // be locked by one process. It's exclusive. That is, the shared resource 53 // cannot have both ReadLock and WriteLock simultaneously. 54 kWriteLock 55 }; 56 57 // Default configuration to the lock(). 58 enum { 59 kDefaultMaxRetryLock = 4, 60 kDefaultRetryLockInterval = 200000UL, 61 }; 62 63 protected: 64 // Grant direct access of the internal file descriptor to the sub-class and 65 // error message such that they can implement their own I/O functionality. 66 int mFD; 67 68 std::error_code mError; 69 70 private: 71 std::string mName; 72 73 // The 2nd argument to the POSIX open(). 74 unsigned mOpenFlags; 75 76 // True true if we should call unlock() in destructor. 77 bool mShouldUnlock; 78 79 // True if file should be deleted in destructor. 80 bool mShouldDelete; 81 82 // Open mName with flag mOpenFlags (using POSIX open().) 83 bool open(); 84 85 // Return true if mFD is the corresponded file descriptor to the file named 86 // mName on the filesystem. This check may returns failed, for example, 87 // someone re-create the file with the same name after we openning the file. 88 bool checkFileIntegrity(); 89 reopen()90 inline bool reopen() { 91 // It's a private method, and all its callers are the few that can invoke it. 92 // That is, the pre-condition will be checked by the caller. Therefore, we don't 93 // need to check it again in reopen(). 94 close(); 95 return open(); 96 } 97 98 private: 99 FileBase(FileBase &); // Do not implement. 100 void operator=(const FileBase &); // Do not implement. 101 102 protected: 103 // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to 104 // FileBase. It's a bit set composed by the value defined in 105 // FileBase::FlagEnum. 106 FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags); 107 108 void detectError(); 109 110 public: 111 // Lock the file descriptor in given pMode. If pNonblocking is true, the lock 112 // request issued will return immediately when the shared resource is locked. 113 // In this case, it retries pMaxRetry times, each wait pRetryInterval (in 114 // usecs) before the previous retry getting done. 115 // 116 // Only file is allowed to use this API. 117 bool lock(enum LockModeEnum pMode, bool pNonblocking = true, 118 unsigned pMaxRetry = kDefaultMaxRetryLock, 119 useconds_t pRetryInterval = kDefaultRetryLockInterval); 120 121 void unlock(); 122 hasError()123 inline bool hasError() const 124 { return (bool) mError; } 125 getError()126 inline const std::error_code &getError() const 127 { return mError; } 128 129 // The return value of std::error_code::message() is obtained upon the call 130 // and is passed by value (that is, it's not a member of std::error_code.) getErrorMessage()131 inline std::string getErrorMessage() const 132 { return mError.message(); } 133 134 void close(); 135 136 virtual ~FileBase(); 137 }; 138 139 } // end namespace bcc 140 141 #endif // BCC_SUPPORT_FILE_BASE_H 142