]> sourceware.org Git - systemtap.git/blame - util.h
Kfail unsupported inode uprobes tests in unprivileged_probes.exp.
[systemtap.git] / util.h
CommitLineData
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 17extern "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 44const char *get_home_directory(void);
b12c8986 45size_t get_file_size(const std::string &path);
a5751672 46size_t get_file_size(int fd);
b12c8986 47bool file_exists (const std::string &path);
e16dc041
JS
48bool copy_file(const std::string& src, const std::string& dest,
49 bool verbose=false);
3b6f3bbb 50int create_dir(const char *dir, int mode = 0777);
98f552c2 51int remove_file_or_dir(const char *dir);
3892d516 52extern "C" gid_t get_gid (const char *group_name);
0da3e7a0 53bool in_group_id (gid_t target_gid);
85007c04 54std::string getmemusage ();
1b78aef5 55void tokenize(const std::string& str, std::vector<std::string>& tokens,
49dbe419
DB
56 const std::string& delimiters);
57void tokenize_full(const std::string& str, std::vector<std::string>& tokens,
1b78aef5 58 const std::string& delimiters);
91699a70 59void tokenize_cxx(const std::string& str, std::vector<std::string>& tokens);
0a567f6d 60std::string find_executable(const std::string& name);
63b4fd14 61std::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 65const std::string cmdstr_quoted(const std::string& cmd);
5eea6ed1 66const std::string cmdstr_join(const std::vector<std::string>& cmds);
01cc94dc 67int stap_waitpid(int verbose, pid_t pid);
20f90026 68pid_t stap_spawn(int verbose, const std::vector<std::string>& args);
aeb9cc10 69pid_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 71pid_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
73int 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
76inline 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 79int stap_system_read(int verbose, const std::vector<std::string>& args, std::ostream& out);
4cc40e82 80int kill_stap_spawn(int sig);
c0d1b5a0 81void assert_regexp_match (const std::string& name, const std::string& value, const std::string& re);
8aabf152 82int regexp_match (const std::string& value, const std::string& re, std::vector<std::string>& matches);
37001baa 83bool contains_glob_chars (const std::string &str);
5750ecc6
FCE
84std::string escape_glob_chars (const std::string& str);
85std::string unescape_glob_chars (const std::string& str);
aeb9cc10 86std::string kernel_release_from_build_tree (const std::string &kernel_build_tree, int verbose = 0);
daa75206 87std::string normalize_machine(const std::string& machine);
081b45d1 88int elf_class_from_normalized_machine(const std::string& machine);
2695da79 89std::string autosprintf(const char* format, ...) __attribute__ ((format (printf, 1, 2)));
e4e3d6b7 90const std::set<std::string>& localization_variables();
28946fe7 91std::string get_self_path();
72dbc915
FCE
92
93// stringification generics
94
95
aca66a36
JS
96template <typename IN>
97inline 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
106template <typename OUT>
107inline 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.
118template <>
119inline 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}
126template <>
127inline 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
136template <typename IN>
137inline std::string
72dbc915
FCE
138lex_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.
147template <typename IN>
148inline std::string
149hex_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 168template <typename IN>
72dbc915
FCE
169inline std::string
170lex_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
179template <>
180inline std::string
181lex_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!)
211template <typename T>
212void 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.
222template <class V>
223class 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
240inline bool
241startswith(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
248inline bool
249endswith(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.
259struct 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
282inline std::string
283resolve_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...
298int 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 : */
This page took 0.154192 seconds and 5 git commands to generate.