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