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