oprof_start_util.cpp

Go to the documentation of this file.
00001 
00012 #include <dirent.h>
00013 #include <unistd.h>
00014 #include <glob.h>
00015 
00016 #include <cerrno>
00017 #include <vector>
00018 #include <cmath>
00019 #include <sstream>
00020 #include <iostream>
00021 #include <fstream>
00022 #include <cstdlib>
00023 
00024 #include <qfiledialog.h>
00025 #include <qmessagebox.h>
00026 
00027 #include "op_file.h"
00028 #include "file_manip.h"
00029 #include "child_reader.h"
00030 #include "op_libiberty.h"
00031 
00032 #include "oprof_start.h"
00033 #include "oprof_start_util.h"
00034 
00035 using namespace std;
00036 
00037 namespace {
00038 
00039 // return the ~ expansion suffixed with a '/'
00040 string const get_config_dir()
00041 {
00042     return "/root";
00043 }
00044 
00045 string daemon_pid;
00046 
00047 } // namespace anon
00048 
00049 daemon_status::daemon_status()
00050     : running(false),
00051       nr_interrupts(0)
00052 {
00053     int HZ;
00054     if (!daemon_pid.empty()) {
00055         string proc_filename = string("/proc/") + daemon_pid + "/exe";
00056         string const exec = op_realpath(proc_filename);
00057         if (exec == proc_filename)
00058             daemon_pid.erase();
00059         else
00060             running = true;
00061     }
00062 
00063     if (daemon_pid.empty()) {
00064         DIR * dir;
00065         struct dirent * dirent;
00066 
00067         if (!(dir = opendir("/proc"))) {
00068             perror("oprofiled: /proc directory could not be opened. ");
00069             exit(EXIT_FAILURE);
00070         }
00071 
00072         while ((dirent = readdir(dir))) {
00073             string const exec =
00074                 op_realpath(string("/proc/")
00075                                + dirent->d_name + "/exe");
00076             string const name = op_basename(exec);
00077             if (name != "oprofiled")
00078                 continue;
00079 
00080             daemon_pid = dirent->d_name;
00081             running = true;
00082         }
00083 
00084         closedir(dir);
00085     }
00086 
00087     HZ = sysconf(_SC_CLK_TCK);
00088     if (HZ == -1) {
00089         perror("oprofiled: Unable to determine clock ticks per second. ");
00090         exit(EXIT_FAILURE);
00091     }
00092 
00093     if (daemon_pid.empty())
00094         return;
00095 
00096     nr_interrupts = 0;
00097 
00098     switch (op_get_interface()) {
00099     case OP_INTERFACE_24:
00100         {
00101             ifstream ifs3("/proc/sys/dev/oprofile/nr_interrupts");
00102             if (ifs3)
00103                 ifs3 >> nr_interrupts;
00104         }
00105         break;
00106     case OP_INTERFACE_26:
00107         {
00108             static unsigned int old_sum_interrupts;
00109             unsigned int sum_interrupts = 0;
00110             glob_t file_names;
00111 
00112             file_names.gl_offs = 0;
00113             glob("/dev/oprofile/stats/cpu*/sample_received",
00114                  GLOB_DOOFFS, NULL, &file_names);
00115 
00116             for (size_t i = 0; i < file_names.gl_pathc; ++i) {
00117                 ifstream ifs3(file_names.gl_pathv[i]);
00118                 if (ifs3) {
00119                     unsigned int file_interrupts;
00120                     ifs3 >> file_interrupts;
00121                     sum_interrupts += file_interrupts;
00122                 }
00123             }
00124             if (old_sum_interrupts > sum_interrupts)
00125                 // occur if we stop/restart daemon.
00126                 old_sum_interrupts = 0;
00127             nr_interrupts = sum_interrupts - old_sum_interrupts;
00128             old_sum_interrupts = sum_interrupts;
00129             globfree(&file_names);
00130         }
00131         break;
00132     default:
00133         break;
00134     }
00135 }
00136 
00137 
00144 string const get_config_filename(string const & filename)
00145 {
00146     return get_config_dir() + "/" + filename;
00147 }
00148 
00149 
00155 bool check_and_create_config_dir()
00156 {
00157     string dir = get_config_filename(".oprofile");
00158 
00159     char * name = xstrdup(dir.c_str());
00160 
00161     if (create_dir(name)) {
00162         ostringstream out;
00163         out << "unable to create " << dir << " directory ";
00164         out << "cause: " << strerror(errno);
00165         QMessageBox::warning(0, 0, out.str().c_str());
00166 
00167         free(name);
00168 
00169         return false;
00170     }
00171 
00172     free(name);
00173     return true;
00174 }
00175 
00176 
00187 string const format(string const & orig, uint const maxlen)
00188 {
00189     string text(orig);
00190 
00191     istringstream ss(text);
00192     vector<string> lines;
00193 
00194     string oline;
00195     string line;
00196 
00197     while (getline(ss, oline)) {
00198         if (line.size() + oline.size() < maxlen) {
00199             lines.push_back(line + oline);
00200             line.erase();
00201         } else {
00202             lines.push_back(line);
00203             line.erase();
00204             string s;
00205             string word;
00206             istringstream oss(oline);
00207             while (oss >> word) {
00208                 if (line.size() + word.size() > maxlen) {
00209                     lines.push_back(line);
00210                     line.erase();
00211                 }
00212                 line += word + " ";
00213             }
00214         }
00215     }
00216 
00217     if (line.size())
00218         lines.push_back(line);
00219 
00220     string ret;
00221 
00222     for(vector<string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
00223         ret += *it + "\n";
00224 
00225     return ret;
00226 }
00227 
00228 
00240 int do_exec_command(string const & cmd, vector<string> const & args)
00241 {
00242     ostringstream err;
00243     bool ok = true;
00244 
00245     // verify arguments
00246     for (vector<string>::const_iterator cit = args.begin();
00247         cit != args.end(); ++cit) {
00248         if (verify_argument(*cit))
00249             continue;
00250 
00251         QMessageBox::warning(0, 0,
00252             string(
00253             "Could not execute: Argument \"" + *cit +
00254             "\" contains shell metacharacters.\n").c_str());
00255         return EINVAL;
00256     }
00257 
00258     child_reader reader(cmd, args);
00259     if (reader.error())
00260         ok = false;
00261 
00262     if (ok)
00263         reader.get_data(cout, err);
00264 
00265     int ret = reader.terminate_process();
00266     if (ret) {
00267         string error = reader.error_str() + "\n";
00268         error += "Failed: \n" + err.str() + "\n";
00269         string cmdline = cmd;
00270         for (vector<string>::const_iterator cit = args.begin();
00271              cit != args.end(); ++cit) {
00272             cmdline += " " + *cit + " ";
00273         }
00274         error += "\n\nCommand was :\n\n" + cmdline + "\n";
00275 
00276         QMessageBox::warning(0, 0, format(error, 50).c_str());
00277     }
00278 
00279     return ret;
00280 }
00281 
00282 
00291 string const do_open_file_or_dir(string const & base_dir, bool dir_only)
00292 {
00293     QString result;
00294 
00295     if (dir_only) {
00296         result = QFileDialog::getExistingDirectory(base_dir.c_str(), 0,
00297             "open_file_or_dir", "Get directory name", true);
00298     } else {
00299         result = QFileDialog::getOpenFileName(base_dir.c_str(), 0, 0,
00300             "open_file_or_dir", "Get filename");
00301     }
00302 
00303     if (result.isNull())
00304         return string();
00305     else
00306         return result.latin1();
00307 }
00308 
00323 bool verify_argument(string const & str)
00324 {
00325     if (str.find_first_not_of(
00326         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00327         "abcdefghijklmnopqrstuvwxyz0123456789_:=-+%,./")
00328         != string::npos)
00329         return false;
00330     return true;
00331 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1