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