blob: d0037fd31fa72657eb106a4d6d44d4fd7958344f [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_UTIL_FILE_H_
2#define AOS_UTIL_FILE_H_
Brian Silverman61175fb2016-03-13 15:35:56 -04003
Stephan Pleinesb1177672024-05-27 17:48:32 -07004#include <stdint.h>
Austin Schuhe3fc0532021-02-07 22:14:22 -08005#include <sys/stat.h>
James Kuszmaul0625b0d2022-09-21 11:38:48 -07006#include <sys/types.h>
davidjevans8b9b52f2021-09-17 08:57:30 -07007
Stephan Pleinesb1177672024-05-27 17:48:32 -07008#include <array>
davidjevans8b9b52f2021-09-17 08:57:30 -07009#include <memory>
James Kuszmaul5a88d412023-01-27 15:55:55 -080010#include <optional>
Brian Silverman61175fb2016-03-13 15:35:56 -040011#include <string>
James Kuszmaul3ae42262019-11-08 12:33:41 -080012#include <string_view>
Stephan Pleinesb1177672024-05-27 17:48:32 -070013#include <vector>
Austin Schuhcb108412019-10-13 16:09:54 -070014
davidjevans8b9b52f2021-09-17 08:57:30 -070015#include "absl/types/span.h"
Brian Silvermana9f2ec92020-10-06 18:00:53 -070016#include "glog/logging.h"
17
Philipp Schrader790cb542023-07-05 21:06:52 -070018#include "aos/scoped/scoped_fd.h"
19
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080020namespace aos::util {
Brian Silverman61175fb2016-03-13 15:35:56 -040021
22// Returns the complete contents of filename. LOG(FATAL)s if any errors are
23// encountered.
payton.rehlf8cb3932023-06-13 11:20:44 -070024std::string ReadFileToStringOrDie(const std::string_view filename);
25
26// Returns the complete contents of filename. Returns nullopt, but never dies
27// if any errors are encountered.
28std::optional<std::string> MaybeReadFileToString(
29 const std::string_view filename);
Brian Silverman61175fb2016-03-13 15:35:56 -040030
Adam Snaider96a0f4b2023-05-18 20:41:19 -070031// Returns the complete contents of filename as a byte vector. LOG(FATAL)s if
32// any errors are encountered.
33std::vector<uint8_t> ReadFileToVecOrDie(const std::string_view filename);
34
Alex Perrycb7da4b2019-08-28 19:35:56 -070035// Creates filename if it doesn't exist and sets the contents to contents.
James Kuszmaul3ae42262019-11-08 12:33:41 -080036void WriteStringToFileOrDie(const std::string_view filename,
Austin Schuhe3fc0532021-02-07 22:14:22 -080037 const std::string_view contents,
38 mode_t permissions = S_IRWXU);
Alex Perrycb7da4b2019-08-28 19:35:56 -070039
Brian Silvermana9f2ec92020-10-06 18:00:53 -070040// Returns true if it succeeds or false if the filesystem is full.
41bool MkdirPIfSpace(std::string_view path, mode_t mode);
42
43inline void MkdirP(std::string_view path, mode_t mode) {
44 CHECK(MkdirPIfSpace(path, mode));
45}
Austin Schuhfccb2d02020-01-26 16:11:19 -080046
James Kuszmaulf8178092020-05-10 18:46:45 -070047bool PathExists(std::string_view path);
48
Austin Schuhe991fe22020-11-18 16:53:39 -080049// Recursively removes everything in the provided path. Ignores any errors it
50// runs across.
51void UnlinkRecursive(std::string_view path);
52
Austin Schuhe4d1a682021-10-01 15:04:50 -070053enum class FileOptions { kReadable, kWriteable };
54
Pallavi Madhukar1d391462024-05-13 18:46:48 -070055enum class FileReaderErrorType { kFatal, kNonFatal };
56
davidjevans8b9b52f2021-09-17 08:57:30 -070057// Maps file from disk into memory
Austin Schuhe4d1a682021-10-01 15:04:50 -070058std::shared_ptr<absl::Span<uint8_t>> MMapFile(
59 const std::string &path, FileOptions options = FileOptions::kReadable);
davidjevans8b9b52f2021-09-17 08:57:30 -070060
James Kuszmaul0625b0d2022-09-21 11:38:48 -070061// Wrapper to handle reading the contents of a file into a buffer. Meant for
62// situations where the malloc'ing of ReadFileToStringOrDie is inappropriate,
63// but where you still want to read a file.
James Kuszmaul0625b0d2022-09-21 11:38:48 -070064class FileReader {
65 public:
Pallavi Madhukar1d391462024-05-13 18:46:48 -070066 // Opens the file for reading. Crashes if file does not open when flag is set
67 // to fatal (default). Logs error if file does not open and flag is non-fatal.
68 FileReader(std::string_view filename,
69 FileReaderErrorType error_type = FileReaderErrorType::kFatal);
James Kuszmaul0625b0d2022-09-21 11:38:48 -070070 // Reads the entire contents of the file into the internal buffer and returns
Austin Schuh73ff6412023-09-01 14:42:24 -070071 // a string_view of it. Returns nullopt if we failed to read the contents
72 // (currently only on EREMOTEIO). Note: The result may not be null-terminated.
73 std::optional<absl::Span<char>> ReadContents(absl::Span<char> buffer);
James Kuszmaul5a88d412023-01-27 15:55:55 -080074 // Returns the value of the file as a string, for a fixed-length file.
75 // Returns nullopt if the result is smaller than kSize. Ignores any
76 // bytes beyond kSize.
77 template <int kSize>
78 std::optional<std::array<char, kSize>> ReadString() {
79 std::array<char, kSize> result;
Austin Schuh73ff6412023-09-01 14:42:24 -070080 const std::optional<absl::Span<char>> used_span =
James Kuszmaul5a88d412023-01-27 15:55:55 -080081 ReadContents(absl::Span<char>(result.data(), result.size()));
Austin Schuh73ff6412023-09-01 14:42:24 -070082 if (!used_span.has_value()) {
83 return std::nullopt;
84 }
85
86 if (used_span->size() == kSize) {
James Kuszmaul5a88d412023-01-27 15:55:55 -080087 return result;
88 } else {
89 return std::nullopt;
90 }
James Kuszmaul0625b0d2022-09-21 11:38:48 -070091 }
James Kuszmaul5a88d412023-01-27 15:55:55 -080092 // Returns the value of the file as an integer. Crashes if it doesn't fit in a
93 // 32-bit integer. The value may start with 0x for a hex value, otherwise it
Austin Schuh73ff6412023-09-01 14:42:24 -070094 // must be base 10. Returns nullopt if we failed to read the file.
95 std::optional<int32_t> ReadInt32();
James Kuszmaul0625b0d2022-09-21 11:38:48 -070096
Pallavi Madhukar1d391462024-05-13 18:46:48 -070097 // Checks if file could be opened.
98 bool is_open() const { return file_.get() != -1; }
99
James Kuszmaul0625b0d2022-09-21 11:38:48 -0700100 private:
101 aos::ScopedFD file_;
James Kuszmaul0625b0d2022-09-21 11:38:48 -0700102};
103
James Kuszmaulfd43f4e2022-12-16 15:19:35 -0800104// Simple interface to allow opening a file for writing and then writing it
105// without any malloc's.
James Kuszmaulfd43f4e2022-12-16 15:19:35 -0800106class FileWriter {
107 public:
108 // The result of an individual call to WriteBytes().
109 // Because WriteBytes() may repeatedly call write() when partial writes occur,
110 // it is possible for a non-zero number of bytes to have been written while
111 // still having an error because a late call to write() failed.
112 struct WriteResult {
113 // Total number of bytes successfully written to the file.
114 size_t bytes_written;
115 // If the write was successful (return_code > 0), equal to bytes_written.
116 // Otherwise, equal to the return value of the final call to write.
117 int return_code;
118 };
119
120 FileWriter(std::string_view filename, mode_t permissions = S_IRWXU);
121
122 WriteResult WriteBytes(absl::Span<const uint8_t> bytes);
123 WriteResult WriteBytes(std::string_view bytes);
124 void WriteBytesOrDie(absl::Span<const uint8_t> bytes);
125 void WriteBytesOrDie(std::string_view bytes);
126 int fd() const { return file_.get(); }
127
128 private:
129 aos::ScopedFD file_;
130};
131
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800132} // namespace aos::util
Brian Silverman61175fb2016-03-13 15:35:56 -0400133
John Park33858a32018-09-28 23:05:48 -0700134#endif // AOS_UTIL_FILE_H_