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
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_
19761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
20761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <fcntl.h>
21761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <string>
22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/random_access_file.h"
23761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesnamespace unix_file {
26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
279433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe// If true, check whether Flush and Close are called before destruction.
289433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampestatic constexpr bool kCheckSafeUsage = true;
299433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes// A RandomAccessFile implementation backed by a file descriptor.
31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes//
32761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes// Not thread safe.
33761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesclass FdFile : public RandomAccessFile {
34761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes public:
35761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  FdFile();
36761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Creates an FdFile using the given file descriptor. Takes ownership of the
37761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // file descriptor. (Use DisableAutoClose to retain ownership.)
389433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  explicit FdFile(int fd, bool checkUsage);
399433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  explicit FdFile(int fd, const std::string& path, bool checkUsage);
40761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
41761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Destroys an FdFile, closing the file descriptor if Close hasn't already
42761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // been called. (If you care about the return value of Close, call it
43761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // yourself; this is meant to handle failure cases and read-only accesses.
44761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Note though that calling Close and checking its return value is still no
45761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // guarantee that data actually made it to stable storage.)
46761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  virtual ~FdFile();
47761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
48761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Opens file 'file_path' using 'flags' and 'mode'.
49761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  bool Open(const std::string& file_path, int flags);
50761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  bool Open(const std::string& file_path, int flags, mode_t mode);
51761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
52761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // RandomAccessFile API.
539433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  virtual int Close() WARN_UNUSED;
549433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  virtual int64_t Read(char* buf, int64_t byte_count, int64_t offset) const WARN_UNUSED;
559433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  virtual int SetLength(int64_t new_length) WARN_UNUSED;
56761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  virtual int64_t GetLength() const;
579433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  virtual int64_t Write(const char* buf, int64_t byte_count, int64_t offset) WARN_UNUSED;
589433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  virtual int Flush() WARN_UNUSED;
599433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
609433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // Short for SetLength(0); Flush(); Close();
619433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  void Erase();
629433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
639433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // Try to Flush(), then try to Close(); If either fails, call Erase().
649433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  int FlushCloseOrErase() WARN_UNUSED;
659433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
669433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // Try to Flush and Close(). Attempts both, but returns the first error.
679433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  int FlushClose() WARN_UNUSED;
68761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
69761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  // Bonus API.
70761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int Fd() const;
71761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  bool IsOpened() const;
728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  const std::string& GetPath() const {
738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    return file_path_;
748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  }
75761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  void DisableAutoClose();
769433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  bool ReadFully(void* buffer, size_t byte_count) WARN_UNUSED;
779433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  bool WriteFully(const void* buffer, size_t byte_count) WARN_UNUSED;
789433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
799433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // This enum is public so that we can define the << operator over it.
809433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  enum class GuardState {
819433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    kBase,           // Base, file has not been flushed or closed.
829433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    kFlushed,        // File has been flushed, but not closed.
839433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    kClosed,         // File has been flushed and closed.
849433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    kNoCheck         // Do not check for the current file instance.
859433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  };
869433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
8762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // WARNING: Only use this when you know what you're doing!
8862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  void MarkUnchecked();
8962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
909433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe protected:
919433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // If the guard state indicates checking (!=kNoCheck), go to the target state "target". Print the
929433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // given warning if the current state is or exceeds warn_threshold.
939433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  void moveTo(GuardState target, GuardState warn_threshold, const char* warning);
949433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
959433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // If the guard state indicates checking (<kNoCheck), and is below the target state "target", go
969433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // to "target." If the current state is higher (excluding kNoCheck) than the trg state, print the
979433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // warning.
989433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  void moveUp(GuardState target, const char* warning);
999433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
1009433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  // Forcefully sets the state to the given one. This can overwrite kNoCheck.
1019433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  void resetGuard(GuardState new_state) {
1029433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (kCheckSafeUsage) {
1039433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      guard_state_ = new_state;
1049433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
1059433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  }
1069433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
1079433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  GuardState guard_state_;
108761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
109761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes private:
110761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  int fd_;
111761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  std::string file_path_;
112761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  bool auto_close_;
113761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
114761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(FdFile);
115761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes};
116761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
1179433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampestd::ostream& operator<<(std::ostream& os, const FdFile::GuardState& kind);
1189433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
119761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}  // namespace unix_file
120761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes
121fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_
122