blob: de998f414ba93410a70c4b8ffcfcd7bb56c3f971 [file] [log] [blame]
adlr@google.com3defe6a2009-12-04 20:57:17 +00001// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__
7
8#include <set>
9#include <string>
10#include <vector>
11#include "update_engine/action.h"
12#include "update_engine/action_processor.h"
13
14namespace chromeos_update_engine {
15
16namespace utils {
17
Andrew de los Reyes970bb282009-12-09 16:34:04 -080018// Writes the data passed to path. The file at path will be overwritten if it
19// exists. Returns true on success, false otherwise.
20bool WriteFile(const char* path, const char* data, int data_len);
21
adlr@google.com3defe6a2009-12-04 20:57:17 +000022// Returns the entire contents of the file at path. Returns true on success.
23bool ReadFile(const std::string& path, std::vector<char>* out);
24bool ReadFileToString(const std::string& path, std::string* out);
25
26std::string ErrnoNumberAsString(int err);
27
28// Strips duplicate slashes, and optionally removes all trailing slashes.
29// Does not compact /./ or /../.
30std::string NormalizePath(const std::string& path, bool strip_trailing_slash);
31
32// Returns true if the file exists for sure. Returns false if it doesn't exist,
33// or an error occurs.
34bool FileExists(const char* path);
35
36// The last 6 chars of path must be XXXXXX. They will be randomly changed
37// and a non-existent path will be returned. Intentionally makes a copy
38// of the string passed in.
39// NEVER CALL THIS FUNCTION UNLESS YOU ARE SURE
40// THAT YOUR PROCESS WILL BE THE ONLY THING WRITING FILES IN THIS DIRECTORY.
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080041std::string TempFilename(std::string path);
adlr@google.com3defe6a2009-12-04 20:57:17 +000042
43// Deletes a directory and all its contents synchronously. Returns true
44// on success. This may be called with a regular file--it will just unlink it.
45// This WILL cross filesystem boundaries.
46bool RecursiveUnlinkDir(const std::string& path);
47
48// Synchronously mount or unmount a filesystem. Return true on success.
49// Mounts as ext3 with default options.
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080050bool MountFilesystem(const std::string& device, const std::string& mountpoint);
51bool UnmountFilesystem(const std::string& mountpoint);
adlr@google.com3defe6a2009-12-04 20:57:17 +000052
53// Log a string in hex to LOG(INFO). Useful for debugging.
54void HexDumpArray(const unsigned char* const arr, const size_t length);
55inline void HexDumpString(const std::string& str) {
56 HexDumpArray(reinterpret_cast<const unsigned char*>(str.data()), str.size());
57}
58inline void HexDumpVector(const std::vector<char>& vect) {
59 HexDumpArray(reinterpret_cast<const unsigned char*>(&vect[0]), vect.size());
60}
61
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080062extern const char* const kStatefulPartition;
adlr@google.com3defe6a2009-12-04 20:57:17 +000063
64bool StringHasSuffix(const std::string& str, const std::string& suffix);
65bool StringHasPrefix(const std::string& str, const std::string& prefix);
66
67template<typename KeyType, typename ValueType>
68bool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) {
69 return m.find(k) != m.end();
70}
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080071template<typename KeyType>
72bool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) {
73 return s.find(k) != s.end();
74}
adlr@google.com3defe6a2009-12-04 20:57:17 +000075
76template<typename ValueType>
77std::set<ValueType> SetWithValue(const ValueType& value) {
78 std::set<ValueType> ret;
79 ret.insert(value);
80 return ret;
81}
82
83// Returns the currently booted device. "/dev/sda1", for example.
84// This will not interpret LABEL= or UUID=. You'll need to use findfs
85// or something with equivalent funcionality to interpret those.
86const std::string BootDevice();
87
88} // namespace utils
89
90// Class to unmount FS when object goes out of scope
91class ScopedFilesystemUnmounter {
92 public:
93 explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
94 : mountpoint_(mountpoint) {}
95 ~ScopedFilesystemUnmounter() {
96 utils::UnmountFilesystem(mountpoint_);
97 }
98 private:
99 const std::string mountpoint_;
100};
101
102// Utility class to close a file descriptor
103class ScopedFdCloser {
104 public:
105 explicit ScopedFdCloser(int* fd) : fd_(fd), should_close_(true) {}
106 void set_should_close(bool should_close) { should_close_ = should_close; }
107 ~ScopedFdCloser() {
108 if (!should_close_)
109 return;
110 if (fd_ && (*fd_ >= 0)) {
111 close(*fd_);
112 *fd_ = -1;
113 }
114 }
115 private:
116 int* fd_;
117 bool should_close_;
118};
119
120// A little object to call ActionComplete on the ActionProcessor when
121// it's destructed.
122class ScopedActionCompleter {
123 public:
124 explicit ScopedActionCompleter(ActionProcessor* processor,
125 AbstractAction* action)
126 : processor_(processor),
127 action_(action),
128 success_(false),
129 should_complete_(true) {}
130 ~ScopedActionCompleter() {
131 if (should_complete_)
132 processor_->ActionComplete(action_, success_);
133 }
134 void set_success(bool success) {
135 success_ = success;
136 }
137 void set_should_complete(bool should_complete) {
138 should_complete_ = should_complete;
139 }
140 private:
141 ActionProcessor* processor_;
142 AbstractAction* action_;
143 bool success_;
144 bool should_complete_;
145 DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
146};
147
148} // namespace chromeos_update_engine
149
150#define TEST_AND_RETURN_FALSE_ERRNO(_x) \
151 do { \
152 bool _success = (_x); \
153 if (!_success) { \
154 std::string _msg = \
155 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
156 LOG(ERROR) << #_x " failed: " << _msg; \
157 return false; \
158 } \
159 } while (0)
160
161#define TEST_AND_RETURN_FALSE(_x) \
162 do { \
163 bool _success = (_x); \
164 if (!_success) { \
165 LOG(ERROR) << #_x " failed."; \
166 return false; \
167 } \
168 } while (0)
169
170#define TEST_AND_RETURN_ERRNO(_x) \
171 do { \
172 bool _success = (_x); \
173 if (!_success) { \
174 std::string _msg = \
175 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
176 LOG(ERROR) << #_x " failed: " << _msg; \
177 return; \
178 } \
179 } while (0)
180
181#define TEST_AND_RETURN(_x) \
182 do { \
183 bool _success = (_x); \
184 if (!_success) { \
185 LOG(ERROR) << #_x " failed."; \
186 return; \
187 } \
188 } while (0)
189
190
191
192#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__