FileBase.cpp revision a2dd52f0710c214e00c1a13e25116e1af5eec77a
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 17a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "FileBase.h" 18a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Log.h" 19331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines 204f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/file.h> 214f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/stat.h> 224f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <unistd.h> 234f94c520f8d699a5973956a1716272146be17128Zonr Chang 244f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <cerrno> 25331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <cstring> 264f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <new> 274f94c520f8d699a5973956a1716272146be17128Zonr Chang 284f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <utils/FileMap.h> 294f94c520f8d699a5973956a1716272146be17128Zonr Chang 304f94c520f8d699a5973956a1716272146be17128Zonr Changusing namespace bcc; 314f94c520f8d699a5973956a1716272146be17128Zonr Chang 3248cd745480738c026312931877ecb8ebecb1c64eStephen Hines#ifdef _WIN32 3348cd745480738c026312931877ecb8ebecb1c64eStephen Hines// TODO: Fix flock usage under windows 3448cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_SH 0 3548cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_EX 0 3648cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_NB 0 3748cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_UN 0 3848cd745480738c026312931877ecb8ebecb1c64eStephen Hines 3948cd745480738c026312931877ecb8ebecb1c64eStephen Hinesint flock(int fd, int operation) { 4048cd745480738c026312931877ecb8ebecb1c64eStephen Hines return 0; 4148cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 4248cd745480738c026312931877ecb8ebecb1c64eStephen Hines#endif // _WIN32 4348cd745480738c026312931877ecb8ebecb1c64eStephen Hines 444f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::FileBase(const std::string &pFilename, 454f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pOpenFlags, 464f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pFlags) 474f94c520f8d699a5973956a1716272146be17128Zonr Chang : mFD(-1), 484f94c520f8d699a5973956a1716272146be17128Zonr Chang mError(), 494f94c520f8d699a5973956a1716272146be17128Zonr Chang mName(pFilename), mOpenFlags(pOpenFlags), 50331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldUnlock(false), 51331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldDelete(false) { 524f94c520f8d699a5973956a1716272146be17128Zonr Chang // Process pFlags 534f94c520f8d699a5973956a1716272146be17128Zonr Chang#ifdef O_BINARY 544f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pFlags & kBinary) { 554f94c520f8d699a5973956a1716272146be17128Zonr Chang mOpenFlags |= O_BINARY; 564f94c520f8d699a5973956a1716272146be17128Zonr Chang } 574f94c520f8d699a5973956a1716272146be17128Zonr Chang#endif 58c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao if (pFlags & kTruncate) { 59c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao mOpenFlags |= O_TRUNC; 60c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao } 614f94c520f8d699a5973956a1716272146be17128Zonr Chang 62b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao if (pFlags & kAppend) { 63b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao mOpenFlags |= O_APPEND; 64b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao } 65b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao 66331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (pFlags & kDeleteOnClose) { 67331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldDelete = true; 68331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 69331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines 704f94c520f8d699a5973956a1716272146be17128Zonr Chang // Open the file. 714f94c520f8d699a5973956a1716272146be17128Zonr Chang open(); 724f94c520f8d699a5973956a1716272146be17128Zonr Chang 734f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 744f94c520f8d699a5973956a1716272146be17128Zonr Chang} 754f94c520f8d699a5973956a1716272146be17128Zonr Chang 764f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::~FileBase() { 774f94c520f8d699a5973956a1716272146be17128Zonr Chang close(); 784f94c520f8d699a5973956a1716272146be17128Zonr Chang} 794f94c520f8d699a5973956a1716272146be17128Zonr Chang 804f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::open() { 814f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 824f94c520f8d699a5973956a1716272146be17128Zonr Chang // FIXME: Hard-coded permissions (0644) for newly created file should be 834f94c520f8d699a5973956a1716272146be17128Zonr Chang // removed and provide a way to let the user configure the value. 844f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = ::open(mName.c_str(), mOpenFlags, 0644); 854f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 864f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 874f94c520f8d699a5973956a1716272146be17128Zonr Chang } 884f94c520f8d699a5973956a1716272146be17128Zonr Chang 894f94c520f8d699a5973956a1716272146be17128Zonr Chang // Some errors occurred ... 904f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno != EINTR) { 914f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 924f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 934f94c520f8d699a5973956a1716272146be17128Zonr Chang } 944f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 954f94c520f8d699a5973956a1716272146be17128Zonr Chang // unreachable 964f94c520f8d699a5973956a1716272146be17128Zonr Chang} 974f94c520f8d699a5973956a1716272146be17128Zonr Chang 984f94c520f8d699a5973956a1716272146be17128Zonr Chang 994f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::checkFileIntegrity() { 1004f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the file integrity by examining whether the inode referring to the mFD 1014f94c520f8d699a5973956a1716272146be17128Zonr Chang // and to the file mName are the same. 1024f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat fd_stat, file_stat; 1034f94c520f8d699a5973956a1716272146be17128Zonr Chang 1044f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file descriptor mFD. 1054f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1064f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &fd_stat) == 0) { 1074f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 1084f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 1094f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1104f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1114f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1124f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 1134f94c520f8d699a5973956a1716272146be17128Zonr Chang 1144f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file mName. 1154f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1164f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::stat(mName.c_str(), &file_stat) == 0) { 1174f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 1184f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 1194f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1204f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1214f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1224f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 1234f94c520f8d699a5973956a1716272146be17128Zonr Chang 1244f94c520f8d699a5973956a1716272146be17128Zonr Chang return ((fd_stat.st_dev == file_stat.st_dev) && 1254f94c520f8d699a5973956a1716272146be17128Zonr Chang (fd_stat.st_ino == file_stat.st_ino)); 1264f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1274f94c520f8d699a5973956a1716272146be17128Zonr Chang 1284f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::detectError() { 1294f94c520f8d699a5973956a1716272146be17128Zonr Chang // Read error from errno. 130d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines mError.assign(errno, std::generic_category()); 1314f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1324f94c520f8d699a5973956a1716272146be17128Zonr Chang 1334f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::lock(enum LockModeEnum pMode, 1344f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pNonblocking, 1354f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pMaxRetry, 1364f94c520f8d699a5973956a1716272146be17128Zonr Chang useconds_t pRetryInterval) { 1374f94c520f8d699a5973956a1716272146be17128Zonr Chang int lock_operation; 1384f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned retry = 0; 1394f94c520f8d699a5973956a1716272146be17128Zonr Chang 1404f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the state. 1414f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 1424f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1434f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1444f94c520f8d699a5973956a1716272146be17128Zonr Chang 1454f94c520f8d699a5973956a1716272146be17128Zonr Chang // Return immediately if it's already locked. 1464f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 1474f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1484f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1494f94c520f8d699a5973956a1716272146be17128Zonr Chang 1504f94c520f8d699a5973956a1716272146be17128Zonr Chang // Determine the lock operation (2nd argument) to the flock(). 1514f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pMode == kReadLock) { 1524f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_SH; 1534f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (pMode == kWriteLock) { 1544f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_EX; 1554f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 156d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines mError = std::make_error_code(std::errc::invalid_argument); 1574f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1584f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1594f94c520f8d699a5973956a1716272146be17128Zonr Chang 1604f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pNonblocking) { 1614f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation |= LOCK_NB; 1624f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1634f94c520f8d699a5973956a1716272146be17128Zonr Chang 1644f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1654f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, lock_operation) == 0) { 1664f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = true; 1674f94c520f8d699a5973956a1716272146be17128Zonr Chang // Here we got a lock but we need to check whether the mFD still 1684f94c520f8d699a5973956a1716272146be17128Zonr Chang // "represents" the filename (mName) we opened in the contructor. This 1694f94c520f8d699a5973956a1716272146be17128Zonr Chang // check may failed when another process deleted the original file mFD 1704f94c520f8d699a5973956a1716272146be17128Zonr Chang // mapped when we were trying to obtain the lock on the file. 1714f94c520f8d699a5973956a1716272146be17128Zonr Chang if (!checkFileIntegrity()) { 1724f94c520f8d699a5973956a1716272146be17128Zonr Chang if (hasError() || !reopen()) { 1734f94c520f8d699a5973956a1716272146be17128Zonr Chang // Error occurred when check the file integrity or re-open the file. 1744f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1754f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1764f94c520f8d699a5973956a1716272146be17128Zonr Chang // Wait a while before the next try. 1774f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1784f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1794f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1804f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1814f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1824f94c520f8d699a5973956a1716272146be17128Zonr Chang 1834f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1844f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1854f94c520f8d699a5973956a1716272146be17128Zonr Chang 1864f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was not performed successfully. Check the errno to see whether 1874f94c520f8d699a5973956a1716272146be17128Zonr Chang // it's retry-able. 1884f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno == EINTR) { 1894f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was interrupted by delivery of a signal. Restart without 1904f94c520f8d699a5973956a1716272146be17128Zonr Chang // decrement the retry counter. 1914f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1924f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno == EWOULDBLOCK) { 1934f94c520f8d699a5973956a1716272146be17128Zonr Chang // The file descriptor was locked by others, wait for a while before next 1944f94c520f8d699a5973956a1716272146be17128Zonr Chang // retry. 1954f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1964f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1974f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1984f94c520f8d699a5973956a1716272146be17128Zonr Chang // There's a fatal error occurs when perform flock(). Return immediately 1994f94c520f8d699a5973956a1716272146be17128Zonr Chang // without further retry. 2004f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2014f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 2024f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2034f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (retry <= pMaxRetry); 2044f94c520f8d699a5973956a1716272146be17128Zonr Chang 2054f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 2064f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2074f94c520f8d699a5973956a1716272146be17128Zonr Chang 2084f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::unlock() { 2094f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0) { 2104f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2114f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2124f94c520f8d699a5973956a1716272146be17128Zonr Chang 2134f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2144f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, LOCK_UN) == 0) { 2154f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 2164f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2174f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2184f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2194f94c520f8d699a5973956a1716272146be17128Zonr Chang 2204f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2214f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2224f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2234f94c520f8d699a5973956a1716272146be17128Zonr Chang 2244f94c520f8d699a5973956a1716272146be17128Zonr Changandroid::FileMap *FileBase::createMap(off_t pOffset, size_t pLength, 2254f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pIsReadOnly) { 2264f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 227900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes return nullptr; 2284f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2294f94c520f8d699a5973956a1716272146be17128Zonr Chang 2304f94c520f8d699a5973956a1716272146be17128Zonr Chang android::FileMap *map = new (std::nothrow) android::FileMap(); 231900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (map == nullptr) { 232d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines mError = make_error_code(std::errc::not_enough_memory); 233900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes return nullptr; 2344f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2354f94c520f8d699a5973956a1716272146be17128Zonr Chang 236900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes if (!map->create(nullptr, mFD, pOffset, pLength, pIsReadOnly)) { 2374f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 238f27f126fd25b9be38753f911e732e668384d969cNarayan Kamath delete map; 239900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes return nullptr; 2404f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2414f94c520f8d699a5973956a1716272146be17128Zonr Chang 2424f94c520f8d699a5973956a1716272146be17128Zonr Chang return map; 2434f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2444f94c520f8d699a5973956a1716272146be17128Zonr Chang 2454f94c520f8d699a5973956a1716272146be17128Zonr Changsize_t FileBase::getSize() { 2464f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 2474f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2484f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2494f94c520f8d699a5973956a1716272146be17128Zonr Chang 2504f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat file_stat; 2514f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2524f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &file_stat) == 0) { 2534f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 2544f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 2554f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2564f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2574f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2584f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 2594f94c520f8d699a5973956a1716272146be17128Zonr Chang 2604f94c520f8d699a5973956a1716272146be17128Zonr Chang return file_stat.st_size; 2614f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2624f94c520f8d699a5973956a1716272146be17128Zonr Chang 2634f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::seek(off_t pOffset) { 2644f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2654f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2664f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2674f94c520f8d699a5973956a1716272146be17128Zonr Chang 2684f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2694f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, pOffset, SEEK_SET); 2704f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result == pOffset) { 2714f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2724f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2734f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2744f94c520f8d699a5973956a1716272146be17128Zonr Chang 2754f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2764f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2774f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2784f94c520f8d699a5973956a1716272146be17128Zonr Chang 2794f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::tell() { 2804f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2814f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2824f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2834f94c520f8d699a5973956a1716272146be17128Zonr Chang 2844f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2854f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, 0, SEEK_CUR); 2864f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result != static_cast<off_t>(-1)) { 2874f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2884f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2894f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2904f94c520f8d699a5973956a1716272146be17128Zonr Chang 2914f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2924f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2934f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2944f94c520f8d699a5973956a1716272146be17128Zonr Chang 2954f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::close() { 2964f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 2974f94c520f8d699a5973956a1716272146be17128Zonr Chang unlock(); 2984f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 2994f94c520f8d699a5973956a1716272146be17128Zonr Chang } 3004f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 3014f94c520f8d699a5973956a1716272146be17128Zonr Chang ::close(mFD); 3024f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = -1; 3034f94c520f8d699a5973956a1716272146be17128Zonr Chang } 304331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (mShouldDelete) { 305331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines int res = ::remove(mName.c_str()); 306331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (res != 0) { 307331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines ALOGE("Failed to remove file: %s - %s", mName.c_str(), ::strerror(res)); 308331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 309331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 3104f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 3114f94c520f8d699a5973956a1716272146be17128Zonr Chang} 312