blob: 298fb03b1f45aba12c39a3074f7874bfcbde8aa2 [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
Andrew de los Reyes81ebcd82010-03-09 15:56:18 -08008#include <algorithm>
adlr@google.com3defe6a2009-12-04 20:57:17 +00009#include <set>
10#include <string>
11#include <vector>
12#include "update_engine/action.h"
13#include "update_engine/action_processor.h"
14
15namespace chromeos_update_engine {
16
17namespace utils {
18
Andrew de los Reyes970bb282009-12-09 16:34:04 -080019// Writes the data passed to path. The file at path will be overwritten if it
20// exists. Returns true on success, false otherwise.
21bool WriteFile(const char* path, const char* data, int data_len);
22
Andrew de los Reyesb10320d2010-03-31 16:44:44 -070023// Calls write() repeatedly until all count bytes at buf are written to
24// fd or an error occurs. Returns true on success.
25bool WriteAll(int fd, const void *buf, size_t count);
26
adlr@google.com3defe6a2009-12-04 20:57:17 +000027// Returns the entire contents of the file at path. Returns true on success.
28bool ReadFile(const std::string& path, std::vector<char>* out);
29bool ReadFileToString(const std::string& path, std::string* out);
30
31std::string ErrnoNumberAsString(int err);
32
33// Strips duplicate slashes, and optionally removes all trailing slashes.
34// Does not compact /./ or /../.
35std::string NormalizePath(const std::string& path, bool strip_trailing_slash);
36
37// Returns true if the file exists for sure. Returns false if it doesn't exist,
38// or an error occurs.
39bool FileExists(const char* path);
40
41// The last 6 chars of path must be XXXXXX. They will be randomly changed
42// and a non-existent path will be returned. Intentionally makes a copy
43// of the string passed in.
44// NEVER CALL THIS FUNCTION UNLESS YOU ARE SURE
45// THAT YOUR PROCESS WILL BE THE ONLY THING WRITING FILES IN THIS DIRECTORY.
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080046std::string TempFilename(std::string path);
adlr@google.com3defe6a2009-12-04 20:57:17 +000047
Andrew de los Reyesb10320d2010-03-31 16:44:44 -070048// Calls mkstemp() with the template passed. Returns the filename in the
49// out param filename. If fd is non-NULL, the file fd returned by mkstemp
50// is not close()d and is returned in the out param 'fd'. However, if
51// fd is NULL, the fd from mkstemp() will be closed.
52// The last six chars of the template must be XXXXXX.
53// Returns true on success.
54bool MakeTempFile(const std::string& filename_template,
55 std::string* filename,
56 int* fd);
57
adlr@google.com3defe6a2009-12-04 20:57:17 +000058// Deletes a directory and all its contents synchronously. Returns true
59// on success. This may be called with a regular file--it will just unlink it.
60// This WILL cross filesystem boundaries.
61bool RecursiveUnlinkDir(const std::string& path);
62
63// Synchronously mount or unmount a filesystem. Return true on success.
64// Mounts as ext3 with default options.
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080065bool MountFilesystem(const std::string& device, const std::string& mountpoint);
66bool UnmountFilesystem(const std::string& mountpoint);
adlr@google.com3defe6a2009-12-04 20:57:17 +000067
68// Log a string in hex to LOG(INFO). Useful for debugging.
69void HexDumpArray(const unsigned char* const arr, const size_t length);
70inline void HexDumpString(const std::string& str) {
71 HexDumpArray(reinterpret_cast<const unsigned char*>(str.data()), str.size());
72}
73inline void HexDumpVector(const std::vector<char>& vect) {
74 HexDumpArray(reinterpret_cast<const unsigned char*>(&vect[0]), vect.size());
75}
76
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080077extern const char* const kStatefulPartition;
adlr@google.com3defe6a2009-12-04 20:57:17 +000078
79bool StringHasSuffix(const std::string& str, const std::string& suffix);
80bool StringHasPrefix(const std::string& str, const std::string& prefix);
81
82template<typename KeyType, typename ValueType>
83bool MapContainsKey(const std::map<KeyType, ValueType>& m, const KeyType& k) {
84 return m.find(k) != m.end();
85}
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080086template<typename KeyType>
87bool SetContainsKey(const std::set<KeyType>& s, const KeyType& k) {
88 return s.find(k) != s.end();
89}
adlr@google.com3defe6a2009-12-04 20:57:17 +000090
91template<typename ValueType>
92std::set<ValueType> SetWithValue(const ValueType& value) {
93 std::set<ValueType> ret;
94 ret.insert(value);
95 return ret;
96}
97
Andrew de los Reyes0ce161b2010-02-22 15:27:01 -080098template<typename T>
99bool VectorContainsValue(const std::vector<T>& vect, const T& value) {
100 return std::find(vect.begin(), vect.end(), value) != vect.end();
101}
102
Andrew de los Reyesb10320d2010-03-31 16:44:44 -0700103template<typename T>
104bool VectorIndexOf(const std::vector<T>& vect, const T& value,
105 typename std::vector<T>::size_type* out_index) {
106 typename std::vector<T>::const_iterator it = std::find(vect.begin(),
107 vect.end(),
108 value);
109 if (it == vect.end()) {
110 return false;
111 } else {
112 *out_index = it - vect.begin();
113 return true;
114 }
115}
116
adlr@google.com3defe6a2009-12-04 20:57:17 +0000117// Returns the currently booted device. "/dev/sda1", for example.
118// This will not interpret LABEL= or UUID=. You'll need to use findfs
119// or something with equivalent funcionality to interpret those.
120const std::string BootDevice();
121
122} // namespace utils
123
124// Class to unmount FS when object goes out of scope
125class ScopedFilesystemUnmounter {
126 public:
127 explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
128 : mountpoint_(mountpoint) {}
129 ~ScopedFilesystemUnmounter() {
130 utils::UnmountFilesystem(mountpoint_);
131 }
132 private:
133 const std::string mountpoint_;
134};
135
136// Utility class to close a file descriptor
137class ScopedFdCloser {
138 public:
139 explicit ScopedFdCloser(int* fd) : fd_(fd), should_close_(true) {}
140 void set_should_close(bool should_close) { should_close_ = should_close; }
141 ~ScopedFdCloser() {
142 if (!should_close_)
143 return;
144 if (fd_ && (*fd_ >= 0)) {
145 close(*fd_);
146 *fd_ = -1;
147 }
148 }
149 private:
150 int* fd_;
151 bool should_close_;
152};
153
154// A little object to call ActionComplete on the ActionProcessor when
155// it's destructed.
156class ScopedActionCompleter {
157 public:
158 explicit ScopedActionCompleter(ActionProcessor* processor,
159 AbstractAction* action)
160 : processor_(processor),
161 action_(action),
162 success_(false),
163 should_complete_(true) {}
164 ~ScopedActionCompleter() {
165 if (should_complete_)
166 processor_->ActionComplete(action_, success_);
167 }
168 void set_success(bool success) {
169 success_ = success;
170 }
171 void set_should_complete(bool should_complete) {
172 should_complete_ = should_complete;
173 }
174 private:
175 ActionProcessor* processor_;
176 AbstractAction* action_;
177 bool success_;
178 bool should_complete_;
179 DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
180};
181
182} // namespace chromeos_update_engine
183
184#define TEST_AND_RETURN_FALSE_ERRNO(_x) \
185 do { \
186 bool _success = (_x); \
187 if (!_success) { \
188 std::string _msg = \
189 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
190 LOG(ERROR) << #_x " failed: " << _msg; \
191 return false; \
192 } \
193 } while (0)
194
195#define TEST_AND_RETURN_FALSE(_x) \
196 do { \
197 bool _success = (_x); \
198 if (!_success) { \
199 LOG(ERROR) << #_x " failed."; \
200 return false; \
201 } \
202 } while (0)
203
204#define TEST_AND_RETURN_ERRNO(_x) \
205 do { \
206 bool _success = (_x); \
207 if (!_success) { \
208 std::string _msg = \
209 chromeos_update_engine::utils::ErrnoNumberAsString(errno); \
210 LOG(ERROR) << #_x " failed: " << _msg; \
211 return; \
212 } \
213 } while (0)
214
215#define TEST_AND_RETURN(_x) \
216 do { \
217 bool _success = (_x); \
218 if (!_success) { \
219 LOG(ERROR) << #_x " failed."; \
220 return; \
221 } \
222 } while (0)
223
224
225
226#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_UTILS_H__