PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/user/oprofile/oprofile-0.9.2.1rc1/gui/oprof_start_util.cpp

https://bitbucket.org/thelearninglabs/uclinux-distro-tll-public
C++ | 330 lines | 209 code | 54 blank | 67 comment | 38 complexity | 64734b1323120a8bafdaabb5d986fae7 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-3.0, Unlicense, GPL-2.0, GPL-3.0, CC-BY-SA-3.0, AGPL-1.0, ISC, MIT, 0BSD, LGPL-2.0
  1. /**
  2. * @file oprof_start_util.cpp
  3. * Miscellaneous helpers for the GUI start
  4. *
  5. * @remark Copyright 2002 OProfile authors
  6. * @remark Read the file COPYING
  7. *
  8. * @author Philippe Elie
  9. * @author John Levon
  10. */
  11. #include <dirent.h>
  12. #include <unistd.h>
  13. #include <glob.h>
  14. #include <cerrno>
  15. #include <vector>
  16. #include <cmath>
  17. #include <sstream>
  18. #include <iostream>
  19. #include <fstream>
  20. #include <qfiledialog.h>
  21. #include <qmessagebox.h>
  22. #include "op_file.h"
  23. #include "file_manip.h"
  24. #include "child_reader.h"
  25. #include "op_libiberty.h"
  26. #include "oprof_start.h"
  27. #include "oprof_start_util.h"
  28. using namespace std;
  29. namespace {
  30. // return the ~ expansion suffixed with a '/'
  31. string const get_config_dir()
  32. {
  33. return "/root";
  34. }
  35. string daemon_pid;
  36. } // namespace anon
  37. daemon_status::daemon_status()
  38. : running(false),
  39. nr_interrupts(0)
  40. {
  41. int HZ;
  42. if (!daemon_pid.empty()) {
  43. string proc_filename = string("/proc/") + daemon_pid + "/exe";
  44. string const exec = op_realpath(proc_filename);
  45. if (exec == proc_filename)
  46. daemon_pid.erase();
  47. else
  48. running = true;
  49. }
  50. if (daemon_pid.empty()) {
  51. DIR * dir;
  52. struct dirent * dirent;
  53. if (!(dir = opendir("/proc"))) {
  54. perror("oprofiled: /proc directory could not be opened. ");
  55. exit(EXIT_FAILURE);
  56. }
  57. while ((dirent = readdir(dir))) {
  58. string const exec =
  59. op_realpath(string("/proc/")
  60. + dirent->d_name + "/exe");
  61. string const name = op_basename(exec);
  62. if (name != "oprofiled")
  63. continue;
  64. daemon_pid = dirent->d_name;
  65. running = true;
  66. }
  67. closedir(dir);
  68. }
  69. HZ = sysconf(_SC_CLK_TCK);
  70. if (HZ == -1) {
  71. perror("oprofiled: Unable to determine clock ticks per second. ");
  72. exit(EXIT_FAILURE);
  73. }
  74. if (daemon_pid.empty())
  75. return;
  76. nr_interrupts = 0;
  77. switch (op_get_interface()) {
  78. case OP_INTERFACE_24:
  79. {
  80. ifstream ifs3("/proc/sys/dev/oprofile/nr_interrupts");
  81. if (ifs3)
  82. ifs3 >> nr_interrupts;
  83. }
  84. break;
  85. case OP_INTERFACE_26:
  86. {
  87. static unsigned int old_sum_interrupts;
  88. unsigned int sum_interrupts = 0;
  89. glob_t file_names;
  90. file_names.gl_offs = 0;
  91. glob("/dev/oprofile/stats/cpu*/sample_received",
  92. GLOB_DOOFFS, NULL, &file_names);
  93. for (size_t i = 0; i < file_names.gl_pathc; ++i) {
  94. ifstream ifs3(file_names.gl_pathv[i]);
  95. if (ifs3) {
  96. unsigned int file_interrupts;
  97. ifs3 >> file_interrupts;
  98. sum_interrupts += file_interrupts;
  99. }
  100. }
  101. if (old_sum_interrupts > sum_interrupts)
  102. // occur if we stop/restart daemon.
  103. old_sum_interrupts = 0;
  104. nr_interrupts = sum_interrupts - old_sum_interrupts;
  105. old_sum_interrupts = sum_interrupts;
  106. globfree(&file_names);
  107. }
  108. break;
  109. default:
  110. break;
  111. }
  112. }
  113. /**
  114. * get_config_filename - get absolute filename of file in user $HOME
  115. * @param filename the relative filename
  116. *
  117. * Get the absolute path of a file in a user's home directory.
  118. */
  119. string const get_config_filename(string const & filename)
  120. {
  121. return get_config_dir() + "/" + filename;
  122. }
  123. /**
  124. * check_and_create_config_dir - make sure config dir is accessible
  125. *
  126. * Returns %true if the dir is accessible.
  127. */
  128. bool check_and_create_config_dir()
  129. {
  130. string dir = get_config_filename(".oprofile");
  131. char * name = xstrdup(dir.c_str());
  132. if (create_dir(name)) {
  133. ostringstream out;
  134. out << "unable to create " << dir << " directory ";
  135. out << "cause: " << strerror(errno);
  136. QMessageBox::warning(0, 0, out.str().c_str());
  137. free(name);
  138. return false;
  139. }
  140. free(name);
  141. return true;
  142. }
  143. /**
  144. * format - re-format a string
  145. * @param orig string to format
  146. * @param maxlen width of line
  147. *
  148. * Re-formats a string to fit into a certain width,
  149. * breaking lines at spaces between words.
  150. *
  151. * Returns the formatted string
  152. */
  153. string const format(string const & orig, uint const maxlen)
  154. {
  155. string text(orig);
  156. istringstream ss(text);
  157. vector<string> lines;
  158. string oline;
  159. string line;
  160. while (getline(ss, oline)) {
  161. if (line.size() + oline.size() < maxlen) {
  162. lines.push_back(line + oline);
  163. line.erase();
  164. } else {
  165. lines.push_back(line);
  166. line.erase();
  167. string s;
  168. string word;
  169. istringstream oss(oline);
  170. while (oss >> word) {
  171. if (line.size() + word.size() > maxlen) {
  172. lines.push_back(line);
  173. line.erase();
  174. }
  175. line += word + " ";
  176. }
  177. }
  178. }
  179. if (line.size())
  180. lines.push_back(line);
  181. string ret;
  182. for(vector<string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
  183. ret += *it + "\n";
  184. return ret;
  185. }
  186. /**
  187. * do_exec_command - execute a command
  188. * @param cmd command name
  189. * @param args arguments to command
  190. *
  191. * Execute a command synchronously. An error message is shown
  192. * if the command returns a non-zero status, which is also returned.
  193. *
  194. * The arguments are verified and will refuse to execute if they contain
  195. * shell metacharacters.
  196. */
  197. int do_exec_command(string const & cmd, vector<string> const & args)
  198. {
  199. ostringstream err;
  200. bool ok = true;
  201. // verify arguments
  202. for (vector<string>::const_iterator cit = args.begin();
  203. cit != args.end(); ++cit) {
  204. if (verify_argument(*cit))
  205. continue;
  206. QMessageBox::warning(0, 0,
  207. string(
  208. "Could not execute: Argument \"" + *cit +
  209. "\" contains shell metacharacters.\n").c_str());
  210. return EINVAL;
  211. }
  212. child_reader reader(cmd, args);
  213. if (reader.error())
  214. ok = false;
  215. if (ok)
  216. reader.get_data(cout, err);
  217. int ret = reader.terminate_process();
  218. if (ret) {
  219. string error = reader.error_str() + "\n";
  220. error += "Failed: \n" + err.str() + "\n";
  221. string cmdline = cmd;
  222. for (vector<string>::const_iterator cit = args.begin();
  223. cit != args.end(); ++cit) {
  224. cmdline += " " + *cit + " ";
  225. }
  226. error += "\n\nCommand was :\n\n" + cmdline + "\n";
  227. QMessageBox::warning(0, 0, format(error, 50).c_str());
  228. }
  229. return ret;
  230. }
  231. /**
  232. * do_open_file_or_dir - open file/directory
  233. * @param base_dir directory to start at
  234. * @param dir_only directory or filename to select
  235. *
  236. * Select a file or directory. The selection is returned;
  237. * an empty string if the selection was cancelled.
  238. */
  239. string const do_open_file_or_dir(string const & base_dir, bool dir_only)
  240. {
  241. QString result;
  242. if (dir_only) {
  243. result = QFileDialog::getExistingDirectory(base_dir.c_str(), 0,
  244. "open_file_or_dir", "Get directory name", true);
  245. } else {
  246. result = QFileDialog::getOpenFileName(base_dir.c_str(), 0, 0,
  247. "open_file_or_dir", "Get filename");
  248. }
  249. if (result.isNull())
  250. return string();
  251. else
  252. return result.latin1();
  253. }
  254. /**
  255. * verify_argument - check string for potentially dangerous characters
  256. *
  257. * This function returns false if the string contains dangerous shell
  258. * metacharacters.
  259. *
  260. * WWW Security FAQ dangerous chars:
  261. *
  262. * & ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r
  263. *
  264. * David Wheeler: ! #
  265. *
  266. * We allow '-' because we disallow whitespace. We allow ':' and '='
  267. */
  268. bool verify_argument(string const & str)
  269. {
  270. if (str.find_first_not_of(
  271. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  272. "abcdefghijklmnopqrstuvwxyz0123456789_:=-+%,./")
  273. != string::npos)
  274. return false;
  275. return true;
  276. }