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