blob: 9354ba519ec9aa716a6755d539869d22db38c012 [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
Andrew de los Reyes0ce161b2010-02-22 15:27:01 -080083template<typename T>
84bool VectorContainsValue(const std::vector<T>& vect, const T& value) {
85 return std::find(vect.begin(), vect.end(), value) != vect.end();
86}
87
adlr@google.com3defe6a2009-12-04 20:57:17 +000088// Returns the currently booted device. "/dev/sda1", for example.
89// This will not interpret LABEL= or UUID=. You'll need to use findfs
90// or something with equivalent funcionality to interpret those.
91const std::string BootDevice();
92
93} // namespace utils
94
95// Class to unmount FS when object goes out of scope
96class ScopedFilesystemUnmounter {
97 public:
98 explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
99 : mountpoint_(mountpoint) {}
100 ~ScopedFilesystemUnmounter() {
101 utils::UnmountFilesystem(mountpoint_);
102 }
103 private:
104 const std::string mountpoint_;
105};
106
107// Utility class to close a file descriptor
108class ScopedFdCloser {
109 public:
110 explicit ScopedFdCloser(int* fd) : fd_(fd), should_close_(true) {}
111 void set_should_close(bool should_close) { should_close_ = should_close; }
112 ~ScopedFdCloser() {
113 if (!should_close_)
114 return;
115 if (fd_ && (*fd_ >= 0)) {
116 close(*fd_);
117 *fd_ = -1;
118 }
119 }
120 private:
121 int* fd_;
122 bool should_close_;
123};
124
125// A little object to call ActionComplete on the ActionProcessor when
126// it's destructed.
127class ScopedActionCompleter {
128 public:
129 explicit ScopedActionCompleter(ActionProcessor* processor,
130 AbstractAction* action)
131 : processor_(processor),
132 action_(action),
133 success_(false),
134 should_complete_(true) {}
135 ~ScopedActionCompleter() {
136 if (should_complete_)
137 processor_->ActionComplete(action_, success_);
138 }
139 void set_success(bool success) {
140 success_ = success;
141 }
142 void set_should_complete(bool should_complete) {
143 should_complete_ = should_complete;
144 }
145 private:
146 ActionProcessor* processor_;
147 AbstractAction* action_;
148 bool success_;
149 bool should_complete_;
150 DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
151};
152
153} // namespace chromeos_update_engine
154
155#define TEST_AND_RETURN_FALSE_ERRNO(_x) \
156 do { \
157 bool _success = (_x); \
158 if (!_success) { \
159 std::string _msg = \
160 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
161 LOG(ERROR) << #_x " failed: " << _msg; \
162 return false; \
163 } \
164 } while (0)
165
166#define TEST_AND_RETURN_FALSE(_x) \
167 do { \
168 bool _success = (_x); \
169 if (!_success) { \
170 LOG(ERROR) << #_x " failed."; \
171 return false; \
172 } \
173 } while (0)
174
175#define TEST_AND_RETURN_ERRNO(_x) \
176 do { \
177 bool _success = (_x); \
178 if (!_success) { \
179 std::string _msg = \
180 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
181 LOG(ERROR) << #_x " failed: " << _msg; \
182 return; \
183 } \
184 } while (0)
185
186#define TEST_AND_RETURN(_x) \
187 do { \
188 bool _success = (_x); \
189 if (!_success) { \
190 LOG(ERROR) << #_x " failed."; \
191 return; \
192 } \
193 } while (0)
194
195
196
197#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__