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