fd_file.cc revision e21dc3db191df04c100620965bee4617b3b24397
1761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes/*
2761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Copyright (C) 2009 The Android Open Source Project
3761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
4761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * you may not use this file except in compliance with the License.
6761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * You may obtain a copy of the License at
7761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
8761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes *
10761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * See the License for the specific language governing permissions and
14761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * limitations under the License.
15761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes */
16761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
17761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
184303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
19761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <errno.h>
20761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <sys/stat.h>
21761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <sys/types.h>
22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <unistd.h>
23761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
244303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe#include "base/logging.h"
254303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesnamespace unix_file {
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
284303ba97313458491e038d78efa041d41cf7bb43Andreas GampeFdFile::FdFile() : guard_state_(GuardState::kClosed), fd_(-1), auto_close_(true) {
29761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
314303ba97313458491e038d78efa041d41cf7bb43Andreas GampeFdFile::FdFile(int fd, bool check_usage)
324303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    : guard_state_(check_usage ? GuardState::kBase : GuardState::kNoCheck),
334303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      fd_(fd), auto_close_(true) {
34761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
35761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
364303ba97313458491e038d78efa041d41cf7bb43Andreas GampeFdFile::FdFile(int fd, const std::string& path, bool check_usage)
374303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    : guard_state_(check_usage ? GuardState::kBase : GuardState::kNoCheck),
384303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      fd_(fd), file_path_(path), auto_close_(true) {
39b45ccbf0e3c8f576de2f8608e12dc8c6ad002e0bBrian Carlstrom  CHECK_NE(0U, path.size());
40761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
41761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
42761600567d73b23324ae0251e871c15d6849ffd8Elliott HughesFdFile::~FdFile() {
434303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (kCheckSafeUsage && (guard_state_ < GuardState::kNoCheck)) {
444303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    if (guard_state_ < GuardState::kFlushed) {
454303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      LOG(::art::ERROR) << "File " << file_path_ << " wasn't explicitly flushed before destruction.";
464303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    }
474303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    if (guard_state_ < GuardState::kClosed) {
484303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      LOG(::art::ERROR) << "File " << file_path_ << " wasn't explicitly closed before destruction.";
494303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    }
504303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    CHECK_GE(guard_state_, GuardState::kClosed);
514303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
52761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  if (auto_close_ && fd_ != -1) {
534303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    if (Close() != 0) {
544303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      PLOG(::art::WARNING) << "Failed to close file " << file_path_;
554303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    }
564303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
574303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe}
584303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
594303ba97313458491e038d78efa041d41cf7bb43Andreas Gampevoid FdFile::moveTo(GuardState target, GuardState warn_threshold, const char* warning) {
604303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (kCheckSafeUsage) {
614303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    if (guard_state_ < GuardState::kNoCheck) {
624303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      if (warn_threshold < GuardState::kNoCheck && guard_state_ >= warn_threshold) {
634303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe        LOG(::art::ERROR) << warning;
644303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      }
654303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      guard_state_ = target;
664303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    }
674303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
684303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe}
694303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
704303ba97313458491e038d78efa041d41cf7bb43Andreas Gampevoid FdFile::moveUp(GuardState target, const char* warning) {
714303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (kCheckSafeUsage) {
724303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    if (guard_state_ < GuardState::kNoCheck) {
734303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      if (guard_state_ < target) {
744303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe        guard_state_ = target;
754303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      } else if (target < guard_state_) {
764303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe        LOG(::art::ERROR) << warning;
774303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe      }
784303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    }
79761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
80761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
81761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
82761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesvoid FdFile::DisableAutoClose() {
83761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  auto_close_ = false;
84761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
85761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
86761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesbool FdFile::Open(const std::string& path, int flags) {
87761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return Open(path, flags, 0640);
88761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
89761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
90761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesbool FdFile::Open(const std::string& path, int flags, mode_t mode) {
91761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  CHECK_EQ(fd_, -1) << path;
92761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  fd_ = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
93761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  if (fd_ == -1) {
94761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return false;
95761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
96761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  file_path_ = path;
974303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  static_assert(O_RDONLY == 0, "Readonly flag has unexpected value.");
984303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (kCheckSafeUsage && (flags & (O_RDWR | O_CREAT | O_WRONLY)) != 0) {
994303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    // Start in the base state (not flushed, not closed).
1004303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    guard_state_ = GuardState::kBase;
1014303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  } else {
1024303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    // We are not concerned with read-only files. In that case, proper flushing and closing is
1034303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    // not important.
1044303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    guard_state_ = GuardState::kNoCheck;
1054303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
106761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return true;
107761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
108761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
109761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint FdFile::Close() {
110761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int result = TEMP_FAILURE_RETRY(close(fd_));
1114303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
1124303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  // Test here, so the file is closed and not leaked.
1134303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (kCheckSafeUsage) {
1144303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    CHECK_GE(guard_state_, GuardState::kFlushed) << "File " << file_path_
1154303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe        << " has not been flushed before closing.";
1164303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    moveUp(GuardState::kClosed, nullptr);
1174303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
1184303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
119761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  if (result == -1) {
120761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return -errno;
121761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  } else {
122761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    fd_ = -1;
123761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    file_path_ = "";
124761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    return 0;
125761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
126761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
127761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
128761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint FdFile::Flush() {
129c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#ifdef __linux__
130761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int rc = TEMP_FAILURE_RETRY(fdatasync(fd_));
131c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#else
132c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers  int rc = TEMP_FAILURE_RETRY(fsync(fd_));
133c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#endif
1344303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  moveUp(GuardState::kFlushed, "Flushing closed file.");
135761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return (rc == -1) ? -errno : rc;
136761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
137761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
138761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint64_t FdFile::Read(char* buf, int64_t byte_count, int64_t offset) const {
139c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#ifdef __linux__
140761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int rc = TEMP_FAILURE_RETRY(pread64(fd_, buf, byte_count, offset));
141c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#else
142c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers  int rc = TEMP_FAILURE_RETRY(pread(fd_, buf, byte_count, offset));
143c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#endif
144761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return (rc == -1) ? -errno : rc;
145761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
146761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
147761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint FdFile::SetLength(int64_t new_length) {
148c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#ifdef __linux__
149761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int rc = TEMP_FAILURE_RETRY(ftruncate64(fd_, new_length));
150c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#else
151c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers  int rc = TEMP_FAILURE_RETRY(ftruncate(fd_, new_length));
152c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#endif
1534303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  moveTo(GuardState::kBase, GuardState::kClosed, "Truncating closed file.");
154761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return (rc == -1) ? -errno : rc;
155761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
156761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
157761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint64_t FdFile::GetLength() const {
158761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  struct stat s;
159761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int rc = TEMP_FAILURE_RETRY(fstat(fd_, &s));
160761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return (rc == -1) ? -errno : s.st_size;
161761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
162761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
163761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint64_t FdFile::Write(const char* buf, int64_t byte_count, int64_t offset) {
164c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#ifdef __linux__
165761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int rc = TEMP_FAILURE_RETRY(pwrite64(fd_, buf, byte_count, offset));
166c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#else
167c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers  int rc = TEMP_FAILURE_RETRY(pwrite(fd_, buf, byte_count, offset));
168c5f17732d8144491c642776b6b48c85dfadf4b52Ian Rogers#endif
1694303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  moveTo(GuardState::kBase, GuardState::kClosed, "Writing into closed file.");
170761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return (rc == -1) ? -errno : rc;
171761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
172761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
173761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesint FdFile::Fd() const {
174761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return fd_;
175761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
176761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
177761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesbool FdFile::IsOpened() const {
178761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return fd_ >= 0;
179761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
180761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
1813774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstatic ssize_t ReadIgnoreOffset(int fd, void *buf, size_t count, off_t offset) {
1823774335b08076117d6950cd472cdd59a167470b5Igor Murashkin  DCHECK_EQ(offset, 0);
1833774335b08076117d6950cd472cdd59a167470b5Igor Murashkin  return read(fd, buf, count);
1843774335b08076117d6950cd472cdd59a167470b5Igor Murashkin}
1853774335b08076117d6950cd472cdd59a167470b5Igor Murashkin
1863774335b08076117d6950cd472cdd59a167470b5Igor Murashkintemplate <ssize_t (*read_func)(int, void*, size_t, off_t)>
1873774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstatic bool ReadFullyGeneric(int fd, void* buffer, size_t byte_count, size_t offset) {
188761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  char* ptr = static_cast<char*>(buffer);
189761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  while (byte_count > 0) {
1903774335b08076117d6950cd472cdd59a167470b5Igor Murashkin    ssize_t bytes_read = TEMP_FAILURE_RETRY(read_func(fd, ptr, byte_count, offset));
191825201e9a7e718470e2dac222dffdee729050ac5Andreas Gampe    if (bytes_read <= 0) {
192825201e9a7e718470e2dac222dffdee729050ac5Andreas Gampe      // 0: end of file
193825201e9a7e718470e2dac222dffdee729050ac5Andreas Gampe      // -1: error
194761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes      return false;
195761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    }
196761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    byte_count -= bytes_read;  // Reduce the number of remaining bytes.
197761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    ptr += bytes_read;  // Move the buffer forward.
1983774335b08076117d6950cd472cdd59a167470b5Igor Murashkin    offset += static_cast<size_t>(bytes_read);  // Move the offset forward.
199761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
200761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return true;
201761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
202761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
2033774335b08076117d6950cd472cdd59a167470b5Igor Murashkinbool FdFile::ReadFully(void* buffer, size_t byte_count) {
2043774335b08076117d6950cd472cdd59a167470b5Igor Murashkin  return ReadFullyGeneric<ReadIgnoreOffset>(fd_, buffer, byte_count, 0);
2053774335b08076117d6950cd472cdd59a167470b5Igor Murashkin}
2063774335b08076117d6950cd472cdd59a167470b5Igor Murashkin
2073774335b08076117d6950cd472cdd59a167470b5Igor Murashkinbool FdFile::PreadFully(void* buffer, size_t byte_count, size_t offset) {
2083774335b08076117d6950cd472cdd59a167470b5Igor Murashkin  return ReadFullyGeneric<pread>(fd_, buffer, byte_count, offset);
2093774335b08076117d6950cd472cdd59a167470b5Igor Murashkin}
2103774335b08076117d6950cd472cdd59a167470b5Igor Murashkin
211ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersbool FdFile::WriteFully(const void* buffer, size_t byte_count) {
212761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  const char* ptr = static_cast<const char*>(buffer);
2134303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  moveTo(GuardState::kBase, GuardState::kClosed, "Writing into closed file.");
214761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  while (byte_count > 0) {
215ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ssize_t bytes_written = TEMP_FAILURE_RETRY(write(fd_, ptr, byte_count));
216ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    if (bytes_written == -1) {
217761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes      return false;
218761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    }
219ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    byte_count -= bytes_written;  // Reduce the number of remaining bytes.
220ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ptr += bytes_written;  // Move the buffer forward.
221761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  }
222761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  return true;
223761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}
224761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
2254303ba97313458491e038d78efa041d41cf7bb43Andreas Gampevoid FdFile::Erase() {
2264303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  TEMP_FAILURE_RETRY(SetLength(0));
2274303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  TEMP_FAILURE_RETRY(Flush());
2284303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  TEMP_FAILURE_RETRY(Close());
2294303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe}
2304303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
2314303ba97313458491e038d78efa041d41cf7bb43Andreas Gampeint FdFile::FlushCloseOrErase() {
2324303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  int flush_result = TEMP_FAILURE_RETRY(Flush());
2334303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (flush_result != 0) {
2344303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    LOG(::art::ERROR) << "CloseOrErase failed while flushing a file.";
2354303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    Erase();
2364303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    return flush_result;
2374303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
2384303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  int close_result = TEMP_FAILURE_RETRY(Close());
2394303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (close_result != 0) {
2404303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    LOG(::art::ERROR) << "CloseOrErase failed while closing a file.";
2414303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    Erase();
2424303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    return close_result;
2434303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
2444303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  return 0;
2454303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe}
2464303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
2474303ba97313458491e038d78efa041d41cf7bb43Andreas Gampeint FdFile::FlushClose() {
2484303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  int flush_result = TEMP_FAILURE_RETRY(Flush());
2494303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (flush_result != 0) {
2504303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    LOG(::art::ERROR) << "FlushClose failed while flushing a file.";
2514303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
2524303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  int close_result = TEMP_FAILURE_RETRY(Close());
2534303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (close_result != 0) {
2544303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    LOG(::art::ERROR) << "FlushClose failed while closing a file.";
2554303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
2564303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  return (flush_result != 0) ? flush_result : close_result;
2574303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe}
2584303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe
259e21dc3db191df04c100620965bee4617b3b24397Andreas Gampevoid FdFile::MarkUnchecked() {
260e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe  guard_state_ = GuardState::kNoCheck;
261e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe}
262e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe
263761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}  // namespace unix_file
264