14f94c520f8d699a5973956a1716272146be17128Zonr Chang/* 24f94c520f8d699a5973956a1716272146be17128Zonr Chang * Copyright 2012, The Android Open Source Project 34f94c520f8d699a5973956a1716272146be17128Zonr Chang * 44f94c520f8d699a5973956a1716272146be17128Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 54f94c520f8d699a5973956a1716272146be17128Zonr Chang * you may not use this file except in compliance with the License. 64f94c520f8d699a5973956a1716272146be17128Zonr Chang * You may obtain a copy of the License at 74f94c520f8d699a5973956a1716272146be17128Zonr Chang * 84f94c520f8d699a5973956a1716272146be17128Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 94f94c520f8d699a5973956a1716272146be17128Zonr Chang * 104f94c520f8d699a5973956a1716272146be17128Zonr Chang * Unless required by applicable law or agreed to in writing, software 114f94c520f8d699a5973956a1716272146be17128Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 124f94c520f8d699a5973956a1716272146be17128Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f94c520f8d699a5973956a1716272146be17128Zonr Chang * See the License for the specific language governing permissions and 144f94c520f8d699a5973956a1716272146be17128Zonr Chang * limitations under the License. 154f94c520f8d699a5973956a1716272146be17128Zonr Chang */ 164f94c520f8d699a5973956a1716272146be17128Zonr Chang 17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#ifndef BCC_SUPPORT_FILE_BASE_H 18c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#define BCC_SUPPORT_FILE_BASE_H 194f94c520f8d699a5973956a1716272146be17128Zonr Chang 204f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <fcntl.h> 21c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include <unistd.h> 224f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <string> 23d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines#include <system_error> 244f94c520f8d699a5973956a1716272146be17128Zonr Chang 254f94c520f8d699a5973956a1716272146be17128Zonr Changnamespace android { 264f94c520f8d699a5973956a1716272146be17128Zonr Chang class FileMap; 274f94c520f8d699a5973956a1716272146be17128Zonr Chang} 284f94c520f8d699a5973956a1716272146be17128Zonr Chang 294f94c520f8d699a5973956a1716272146be17128Zonr Changnamespace bcc { 304f94c520f8d699a5973956a1716272146be17128Zonr Chang 314f94c520f8d699a5973956a1716272146be17128Zonr Changclass FileBase { 324f94c520f8d699a5973956a1716272146be17128Zonr Changpublic: 334f94c520f8d699a5973956a1716272146be17128Zonr Chang enum OpenModeEnum { 344f94c520f8d699a5973956a1716272146be17128Zonr Chang kReadMode = 1 << 0, 354f94c520f8d699a5973956a1716272146be17128Zonr Chang kWriteMode = 1 << 1, 364f94c520f8d699a5973956a1716272146be17128Zonr Chang kReadWriteMode = (kReadMode | kWriteMode), 374f94c520f8d699a5973956a1716272146be17128Zonr Chang }; 384f94c520f8d699a5973956a1716272146be17128Zonr Chang 394f94c520f8d699a5973956a1716272146be17128Zonr Chang enum FlagEnum { 404f94c520f8d699a5973956a1716272146be17128Zonr Chang kBinary = 1 << 0, 41c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao kTruncate = 1 << 1, 42b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao kAppend = 1 << 2, 43331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines kDeleteOnClose = 1 << 3 444f94c520f8d699a5973956a1716272146be17128Zonr Chang }; 454f94c520f8d699a5973956a1716272146be17128Zonr Chang 464f94c520f8d699a5973956a1716272146be17128Zonr Chang enum LockModeEnum { 474f94c520f8d699a5973956a1716272146be17128Zonr Chang // The shared resource behind the Stream locked in ReadLock mode can be 484f94c520f8d699a5973956a1716272146be17128Zonr Chang // locked by other processes at the same time. 494f94c520f8d699a5973956a1716272146be17128Zonr Chang kReadLock, 504f94c520f8d699a5973956a1716272146be17128Zonr Chang 514f94c520f8d699a5973956a1716272146be17128Zonr Chang // The shared resource behind the Stream locked in WriteLock mode can only 524f94c520f8d699a5973956a1716272146be17128Zonr Chang // be locked by one process. It's exclusive. That is, the shared resource 534f94c520f8d699a5973956a1716272146be17128Zonr Chang // cannot have both ReadLock and WriteLock simultaneously. 544f94c520f8d699a5973956a1716272146be17128Zonr Chang kWriteLock 554f94c520f8d699a5973956a1716272146be17128Zonr Chang }; 564f94c520f8d699a5973956a1716272146be17128Zonr Chang 574f94c520f8d699a5973956a1716272146be17128Zonr Chang // Default configuration to the lock(). 584f94c520f8d699a5973956a1716272146be17128Zonr Chang enum { 594f94c520f8d699a5973956a1716272146be17128Zonr Chang kDefaultMaxRetryLock = 4, 604f94c520f8d699a5973956a1716272146be17128Zonr Chang kDefaultRetryLockInterval = 200000UL, 614f94c520f8d699a5973956a1716272146be17128Zonr Chang }; 624f94c520f8d699a5973956a1716272146be17128Zonr Chang 634f94c520f8d699a5973956a1716272146be17128Zonr Changprotected: 644f94c520f8d699a5973956a1716272146be17128Zonr Chang // Grant direct access of the internal file descriptor to the sub-class and 654f94c520f8d699a5973956a1716272146be17128Zonr Chang // error message such that they can implement their own I/O functionality. 664f94c520f8d699a5973956a1716272146be17128Zonr Chang int mFD; 674f94c520f8d699a5973956a1716272146be17128Zonr Chang 68d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines std::error_code mError; 694f94c520f8d699a5973956a1716272146be17128Zonr Chang 704f94c520f8d699a5973956a1716272146be17128Zonr Changprivate: 714f94c520f8d699a5973956a1716272146be17128Zonr Chang std::string mName; 724f94c520f8d699a5973956a1716272146be17128Zonr Chang 734f94c520f8d699a5973956a1716272146be17128Zonr Chang // The 2nd argument to the POSIX open(). 744f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned mOpenFlags; 754f94c520f8d699a5973956a1716272146be17128Zonr Chang 764f94c520f8d699a5973956a1716272146be17128Zonr Chang // True true if we should call unlock() in destructor. 774f94c520f8d699a5973956a1716272146be17128Zonr Chang bool mShouldUnlock; 784f94c520f8d699a5973956a1716272146be17128Zonr Chang 79331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines // True if file should be deleted in destructor. 80331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines bool mShouldDelete; 81331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines 824f94c520f8d699a5973956a1716272146be17128Zonr Chang // Open mName with flag mOpenFlags (using POSIX open().) 834f94c520f8d699a5973956a1716272146be17128Zonr Chang bool open(); 844f94c520f8d699a5973956a1716272146be17128Zonr Chang 854f94c520f8d699a5973956a1716272146be17128Zonr Chang // Return true if mFD is the corresponded file descriptor to the file named 864f94c520f8d699a5973956a1716272146be17128Zonr Chang // mName on the filesystem. This check may returns failed, for example, 874f94c520f8d699a5973956a1716272146be17128Zonr Chang // someone re-create the file with the same name after we openning the file. 884f94c520f8d699a5973956a1716272146be17128Zonr Chang bool checkFileIntegrity(); 894f94c520f8d699a5973956a1716272146be17128Zonr Chang 904f94c520f8d699a5973956a1716272146be17128Zonr Chang inline bool reopen() { 914f94c520f8d699a5973956a1716272146be17128Zonr Chang // It's a private method, and all its callers are the few that can invoke it. 924f94c520f8d699a5973956a1716272146be17128Zonr Chang // That is, the pre-condition will be checked by the caller. Therefore, we don't 934f94c520f8d699a5973956a1716272146be17128Zonr Chang // need to check it again in reopen(). 944f94c520f8d699a5973956a1716272146be17128Zonr Chang close(); 954f94c520f8d699a5973956a1716272146be17128Zonr Chang return open(); 964f94c520f8d699a5973956a1716272146be17128Zonr Chang } 974f94c520f8d699a5973956a1716272146be17128Zonr Chang 984f94c520f8d699a5973956a1716272146be17128Zonr Changprivate: 994f94c520f8d699a5973956a1716272146be17128Zonr Chang FileBase(FileBase &); // Do not implement. 1004f94c520f8d699a5973956a1716272146be17128Zonr Chang void operator=(const FileBase &); // Do not implement. 1014f94c520f8d699a5973956a1716272146be17128Zonr Chang 1024f94c520f8d699a5973956a1716272146be17128Zonr Changprotected: 1034f94c520f8d699a5973956a1716272146be17128Zonr Chang // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to 1044f94c520f8d699a5973956a1716272146be17128Zonr Chang // FileBase. It's a bit set composed by the value defined in 1054f94c520f8d699a5973956a1716272146be17128Zonr Chang // FileBase::FlagEnum. 1064f94c520f8d699a5973956a1716272146be17128Zonr Chang FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags); 1074f94c520f8d699a5973956a1716272146be17128Zonr Chang 1084f94c520f8d699a5973956a1716272146be17128Zonr Chang void detectError(); 1094f94c520f8d699a5973956a1716272146be17128Zonr Chang 1104f94c520f8d699a5973956a1716272146be17128Zonr Changpublic: 1114f94c520f8d699a5973956a1716272146be17128Zonr Chang // Lock the file descriptor in given pMode. If pNonblocking is true, the lock 1124f94c520f8d699a5973956a1716272146be17128Zonr Chang // request issued will return immediately when the shared resource is locked. 1134f94c520f8d699a5973956a1716272146be17128Zonr Chang // In this case, it retries pMaxRetry times, each wait pRetryInterval (in 1144f94c520f8d699a5973956a1716272146be17128Zonr Chang // usecs) before the previous retry getting done. 1154f94c520f8d699a5973956a1716272146be17128Zonr Chang // 1164f94c520f8d699a5973956a1716272146be17128Zonr Chang // Only file is allowed to use this API. 1174f94c520f8d699a5973956a1716272146be17128Zonr Chang bool lock(enum LockModeEnum pMode, bool pNonblocking = true, 1184f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pMaxRetry = kDefaultMaxRetryLock, 1194f94c520f8d699a5973956a1716272146be17128Zonr Chang useconds_t pRetryInterval = kDefaultRetryLockInterval); 1204f94c520f8d699a5973956a1716272146be17128Zonr Chang 1214f94c520f8d699a5973956a1716272146be17128Zonr Chang void unlock(); 1224f94c520f8d699a5973956a1716272146be17128Zonr Chang 1234f94c520f8d699a5973956a1716272146be17128Zonr Chang inline bool hasError() const 124d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines { return (bool) mError; } 1254f94c520f8d699a5973956a1716272146be17128Zonr Chang 126d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines inline const std::error_code &getError() const 1274f94c520f8d699a5973956a1716272146be17128Zonr Chang { return mError; } 1284f94c520f8d699a5973956a1716272146be17128Zonr Chang 129d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines // The return value of std::error_code::message() is obtained upon the call 130d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines // and is passed by value (that is, it's not a member of std::error_code.) 1314f94c520f8d699a5973956a1716272146be17128Zonr Chang inline std::string getErrorMessage() const 1324f94c520f8d699a5973956a1716272146be17128Zonr Chang { return mError.message(); } 1334f94c520f8d699a5973956a1716272146be17128Zonr Chang 1344f94c520f8d699a5973956a1716272146be17128Zonr Chang void close(); 1354f94c520f8d699a5973956a1716272146be17128Zonr Chang 1364f94c520f8d699a5973956a1716272146be17128Zonr Chang virtual ~FileBase(); 1374f94c520f8d699a5973956a1716272146be17128Zonr Chang}; 1384f94c520f8d699a5973956a1716272146be17128Zonr Chang 1394f94c520f8d699a5973956a1716272146be17128Zonr Chang} // end namespace bcc 1404f94c520f8d699a5973956a1716272146be17128Zonr Chang 141c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#endif // BCC_SUPPORT_FILE_BASE_H 142