]>
Commit | Line | Data |
---|---|---|
42e38653 DB |
1 | #ifndef UTIL_H |
2 | #define UTIL_H | |
3 | ||
58a834b1 | 4 | #include "config.h" |
fce2d171 | 5 | #include <cstdlib> |
60d98537 | 6 | #include <cstring> |
5e3b8687 | 7 | #include <cerrno> |
1b78aef5 DS |
8 | #include <string> |
9 | #include <vector> | |
72dbc915 FCE |
10 | #include <iostream> |
11 | #include <sstream> | |
12 | #include <stdexcept> | |
3f99432c | 13 | #include <cctype> |
e4e3d6b7 | 14 | #include <set> |
e1e8b44e | 15 | #include <iomanip> |
05fb3e0c | 16 | #include <map> |
a69b4b55 | 17 | extern "C" { |
52c2652f | 18 | #if ENABLE_NLS |
58a834b1 LB |
19 | #include <libintl.h> |
20 | #include <locale.h> | |
52c2652f | 21 | #endif |
a69b4b55 | 22 | #include <signal.h> |
f13fc0db | 23 | #include <stdint.h> |
aeb9cc10 | 24 | #include <spawn.h> |
e1e8b44e | 25 | #include <assert.h> |
3f95ed01 | 26 | #include <poll.h> |
f13fc0db | 27 | } |
1b78aef5 | 28 | |
3892d516 | 29 | #include "privilege.h" |
f2013cc9 | 30 | |
58a834b1 LB |
31 | #if ENABLE_NLS |
32 | #define _(string) gettext(string) | |
33 | #define _N(string, string_plural, count) \ | |
34 | ngettext((string), (string_plural), (count)) | |
35 | #else | |
36 | #define _(string) (string) | |
37 | #define _N(string, string_plural, count) \ | |
38 | ( (count) == 1 ? (string) : (string_plural) ) | |
39 | #endif | |
40 | #define _F(format, ...) autosprintf(_(format), __VA_ARGS__) | |
41 | #define _NF(format, format_plural, count, ...) \ | |
42 | autosprintf(_N((format), (format_plural), (count)), __VA_ARGS__) | |
43 | ||
72dbc915 | 44 | const char *get_home_directory(void); |
b12c8986 | 45 | size_t get_file_size(const std::string &path); |
a5751672 | 46 | size_t get_file_size(int fd); |
b12c8986 | 47 | bool file_exists (const std::string &path); |
e16dc041 JS |
48 | bool copy_file(const std::string& src, const std::string& dest, |
49 | bool verbose=false); | |
3b6f3bbb | 50 | int create_dir(const char *dir, int mode = 0777); |
98f552c2 | 51 | int remove_file_or_dir(const char *dir); |
3892d516 | 52 | extern "C" gid_t get_gid (const char *group_name); |
0da3e7a0 | 53 | bool in_group_id (gid_t target_gid); |
85007c04 | 54 | std::string getmemusage (); |
1b78aef5 | 55 | void tokenize(const std::string& str, std::vector<std::string>& tokens, |
49dbe419 DB |
56 | const std::string& delimiters); |
57 | void tokenize_full(const std::string& str, std::vector<std::string>& tokens, | |
1b78aef5 | 58 | const std::string& delimiters); |
91699a70 | 59 | void tokenize_cxx(const std::string& str, std::vector<std::string>& tokens); |
0a567f6d | 60 | std::string find_executable(const std::string& name); |
63b4fd14 | 61 | std::string find_executable(const std::string& name, |
05fb3e0c | 62 | const std::string& sysroot, |
0a567f6d | 63 | const std::map<std::string,std::string>& sysenv, |
63b4fd14 | 64 | const std::string& env_path = "PATH"); |
8c711d30 | 65 | const std::string cmdstr_quoted(const std::string& cmd); |
5eea6ed1 | 66 | const std::string cmdstr_join(const std::vector<std::string>& cmds); |
01cc94dc | 67 | int stap_waitpid(int verbose, pid_t pid); |
20f90026 | 68 | pid_t stap_spawn(int verbose, const std::vector<std::string>& args); |
aeb9cc10 | 69 | pid_t stap_spawn(int verbose, const std::vector<std::string>& args, |
e4e3d6b7 | 70 | posix_spawn_file_actions_t* fa, const std::vector<std::string>& envVec = std::vector<std::string> ()); |
645383d5 | 71 | pid_t stap_spawn_piped(int verbose, const std::vector<std::string>& args, |
e96f2257 | 72 | int* child_in=NULL, int* child_out=NULL, int* child_err=NULL); |
b13c6a37 JS |
73 | int stap_system(int verbose, const std::string& description, |
74 | const std::vector<std::string>& args, | |
ff520ff4 | 75 | bool null_out=false, bool null_err=false); |
b13c6a37 JS |
76 | inline int stap_system(int verbose, const std::vector<std::string>& args, |
77 | bool null_out=false, bool null_err=false) | |
78 | { return stap_system(verbose, args.front(), args, null_out, null_err); } | |
20f90026 | 79 | int stap_system_read(int verbose, const std::vector<std::string>& args, std::ostream& out); |
4cc40e82 | 80 | int kill_stap_spawn(int sig); |
c0d1b5a0 | 81 | void assert_regexp_match (const std::string& name, const std::string& value, const std::string& re); |
8aabf152 | 82 | int regexp_match (const std::string& value, const std::string& re, std::vector<std::string>& matches); |
37001baa | 83 | bool contains_glob_chars (const std::string &str); |
5750ecc6 FCE |
84 | std::string escape_glob_chars (const std::string& str); |
85 | std::string unescape_glob_chars (const std::string& str); | |
aeb9cc10 | 86 | std::string kernel_release_from_build_tree (const std::string &kernel_build_tree, int verbose = 0); |
daa75206 | 87 | std::string normalize_machine(const std::string& machine); |
081b45d1 | 88 | int elf_class_from_normalized_machine(const std::string& machine); |
2695da79 | 89 | std::string autosprintf(const char* format, ...) __attribute__ ((format (printf, 1, 2))); |
e4e3d6b7 | 90 | const std::set<std::string>& localization_variables(); |
28946fe7 | 91 | std::string get_self_path(); |
72dbc915 FCE |
92 | |
93 | // stringification generics | |
94 | ||
95 | ||
aca66a36 JS |
96 | template <typename IN> |
97 | inline std::string lex_cast(IN const & in) | |
72dbc915 | 98 | { |
aca66a36 JS |
99 | std::ostringstream ss; |
100 | if (!(ss << in)) | |
58a834b1 | 101 | throw std::runtime_error(_("bad lexical cast")); |
aca66a36 | 102 | return ss.str(); |
72dbc915 FCE |
103 | } |
104 | ||
105 | ||
aca66a36 JS |
106 | template <typename OUT> |
107 | inline OUT lex_cast(std::string const & in) | |
72dbc915 | 108 | { |
aca66a36 | 109 | std::istringstream ss(in); |
72dbc915 | 110 | OUT out; |
aca66a36 | 111 | if (!(ss >> out && ss.eof())) |
58a834b1 | 112 | throw std::runtime_error(_("bad lexical cast")); |
72dbc915 FCE |
113 | return out; |
114 | } | |
115 | ||
116 | ||
f13fc0db JS |
117 | // We want [u]int8_t to be treated numerically, not just extracting a char. |
118 | template <> | |
119 | inline int8_t lex_cast(std::string const & in) | |
120 | { | |
121 | int16_t out = lex_cast<int16_t>(in); | |
122 | if (out < -128 || out > 127) | |
58a834b1 | 123 | throw std::runtime_error(_("bad lexical cast")); |
f13fc0db JS |
124 | return out; |
125 | } | |
126 | template <> | |
127 | inline uint8_t lex_cast(std::string const & in) | |
128 | { | |
129 | uint16_t out = lex_cast<uint16_t>(in); | |
130 | if (out > 0xff && out < 0xff80) // don't error if it looks sign-extended | |
58a834b1 | 131 | throw std::runtime_error(_("bad lexical cast")); |
f13fc0db JS |
132 | return out; |
133 | } | |
134 | ||
135 | ||
aca66a36 JS |
136 | template <typename IN> |
137 | inline std::string | |
72dbc915 FCE |
138 | lex_cast_hex(IN const & in) |
139 | { | |
aca66a36 | 140 | std::ostringstream ss; |
49e1b0a1 | 141 | if (!(ss << std::showbase << std::hex << in << std::dec)) |
58a834b1 | 142 | throw std::runtime_error(_("bad lexical cast")); |
aca66a36 | 143 | return ss.str(); |
72dbc915 FCE |
144 | } |
145 | ||
e1e8b44e CM |
146 | //Convert binary data to hex data. |
147 | template <typename IN> | |
148 | inline std::string | |
149 | hex_dump(IN const & in, size_t len) | |
150 | { | |
151 | std::ostringstream ss; | |
152 | unsigned i; | |
153 | if (!(ss << std::hex << std::setfill('0'))) | |
154 | throw std::runtime_error(_("bad lexical cast")); | |
155 | ||
156 | for(i = 0; i < len; i++) | |
157 | { | |
158 | int temp = in[i]; | |
159 | ss << std::setw(2) << temp; | |
160 | } | |
161 | std::string hex = ss.str(); | |
162 | assert(hex.length() == 2 * len); | |
163 | return hex; | |
164 | } | |
72dbc915 FCE |
165 | |
166 | // Return as quoted string, so that when compiled as a C literal, it | |
167 | // would print to the user out nicely. | |
dff50e09 | 168 | template <typename IN> |
72dbc915 FCE |
169 | inline std::string |
170 | lex_cast_qstring(IN const & in) | |
171 | { | |
172 | std::stringstream ss; | |
72dbc915 | 173 | if (!(ss << in)) |
58a834b1 | 174 | throw std::runtime_error(_("bad lexical cast")); |
aca66a36 JS |
175 | return lex_cast_qstring(ss.str()); |
176 | } | |
177 | ||
178 | ||
179 | template <> | |
180 | inline std::string | |
181 | lex_cast_qstring(std::string const & in) | |
182 | { | |
183 | std::string out; | |
184 | out += '"'; | |
185 | for (const char *p = in.c_str(); *p; ++p) | |
72dbc915 | 186 | { |
aca66a36 | 187 | unsigned char c = *p; |
3f99432c FCE |
188 | if (! isprint(c)) |
189 | { | |
aca66a36 | 190 | out += '\\'; |
3f99432c | 191 | // quick & dirty octal converter |
aca66a36 JS |
192 | out += "01234567" [(c >> 6) & 0x07]; |
193 | out += "01234567" [(c >> 3) & 0x07]; | |
194 | out += "01234567" [(c >> 0) & 0x07]; | |
dff50e09 | 195 | } |
3f99432c FCE |
196 | else if (c == '"' || c == '\\') |
197 | { | |
aca66a36 JS |
198 | out += '\\'; |
199 | out += c; | |
3f99432c FCE |
200 | } |
201 | else | |
aca66a36 | 202 | out += c; |
72dbc915 | 203 | } |
aca66a36 JS |
204 | out += '"'; |
205 | return out; | |
72dbc915 | 206 | } |
73267b89 | 207 | |
c9efa5c9 JS |
208 | |
209 | // Delete all values from a map-like container and clear it | |
210 | // (The template is permissive -- be good!) | |
211 | template <typename T> | |
212 | void delete_map(T& t) | |
213 | { | |
214 | for (typename T::iterator i = t.begin(); i != t.end(); ++i) | |
215 | delete i->second; | |
216 | t.clear(); | |
217 | } | |
218 | ||
219 | ||
4cb10751 CM |
220 | // Automatically save a variable, and restore it at the |
221 | // end of the function. | |
222 | template <class V> | |
223 | class save_and_restore | |
224 | { | |
225 | V* ptr; | |
226 | V previous_value; | |
227 | ||
228 | public: | |
229 | // Optionally pass a second argument to the constructor to initialize the | |
230 | // variable to some value, after saving its old value. | |
231 | save_and_restore(V* ptr_in, V value_in): ptr(ptr_in), previous_value(*ptr_in) { *ptr_in = value_in; } | |
232 | save_and_restore(V*ptr_in): ptr(ptr_in), previous_value(*ptr_in){} | |
233 | ||
234 | // Retrieve the old value and restore it in the destructor | |
235 | ~save_and_restore() { *ptr = previous_value; } | |
236 | }; | |
237 | ||
238 | ||
60d98537 JS |
239 | // Returns whether a string starts with the given prefix |
240 | inline bool | |
241 | startswith(const std::string & s, const char * prefix) | |
242 | { | |
243 | return (s.compare(0, std::strlen(prefix), prefix) == 0); | |
244 | } | |
245 | ||
246 | ||
247 | // Returns whether a string ends with the given suffix | |
248 | inline bool | |
249 | endswith(const std::string & s, const char * suffix) | |
250 | { | |
251 | size_t s_len = s.size(), suffix_len = std::strlen(suffix); | |
252 | if (suffix_len > s_len) | |
253 | return false; | |
254 | return (s.compare(s_len - suffix_len, suffix_len, suffix) == 0); | |
255 | } | |
256 | ||
257 | ||
a69b4b55 JS |
258 | // Mask our usual signals for the life of this object. |
259 | struct stap_sigmasker { | |
260 | sigset_t old; | |
261 | stap_sigmasker() | |
262 | { | |
263 | sigset_t mask; | |
264 | sigemptyset (&mask); | |
265 | sigaddset (&mask, SIGHUP); | |
266 | sigaddset (&mask, SIGPIPE); | |
267 | sigaddset (&mask, SIGINT); | |
268 | sigaddset (&mask, SIGTERM); | |
269 | sigprocmask (SIG_BLOCK, &mask, &old); | |
270 | } | |
6d27dcff JS |
271 | stap_sigmasker(const sigset_t *mask) |
272 | { | |
273 | sigprocmask (SIG_BLOCK, mask, &old); | |
274 | } | |
a69b4b55 JS |
275 | ~stap_sigmasker() |
276 | { | |
277 | sigprocmask (SIG_SETMASK, &old, NULL); | |
278 | } | |
279 | }; | |
280 | ||
fce2d171 JS |
281 | // Convert a possibly-relative path to a full path |
282 | inline std::string | |
283 | resolve_path(const std::string& path) | |
284 | { | |
285 | std::string result(path); | |
286 | char* resolved_path = realpath(path.c_str(), NULL); | |
287 | if (resolved_path) | |
288 | { | |
289 | result = resolved_path; | |
290 | std::free(resolved_path); | |
291 | } | |
292 | return result; | |
293 | } | |
294 | ||
295 | ||
3f95ed01 JS |
296 | #ifndef HAVE_PPOLL |
297 | // This is a poor-man's ppoll; see the implementation for more details... | |
298 | int ppoll(struct pollfd *fds, nfds_t nfds, | |
299 | const struct timespec *timeout_ts, | |
300 | const sigset_t *sigmask); | |
301 | #endif | |
302 | ||
303 | ||
42e38653 | 304 | #endif // UTIL_H |
a69b4b55 | 305 | |
73267b89 | 306 | /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |