Merge branch 'next/drivers' into HEAD
[deliverable/linux.git] / tools / perf / builtin-script.c
index 2d6e3b226aad511ef04ba5d0bd20bf039c7e1ddb..1be843aa1546ed1df603119e3cec193d04cf0673 100644 (file)
@@ -14,6 +14,7 @@
 #include "util/util.h"
 #include "util/evlist.h"
 #include "util/evsel.h"
+#include "util/sort.h"
 #include <linux/bitmap.h>
 
 static char const              *script_name;
@@ -430,9 +431,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
        printf("\n");
 }
 
-static int default_start_script(const char *script __unused,
-                               int argc __unused,
-                               const char **argv __unused)
+static int default_start_script(const char *script __maybe_unused,
+                               int argc __maybe_unused,
+                               const char **argv __maybe_unused)
 {
        return 0;
 }
@@ -442,8 +443,8 @@ static int default_stop_script(void)
        return 0;
 }
 
-static int default_generate_script(struct pevent *pevent __unused,
-                                  const char *outfile __unused)
+static int default_generate_script(struct pevent *pevent __maybe_unused,
+                                  const char *outfile __maybe_unused)
 {
        return 0;
 }
@@ -474,7 +475,7 @@ static int cleanup_scripting(void)
 
 static const char *input_name;
 
-static int process_sample_event(struct perf_tool *tool __used,
+static int process_sample_event(struct perf_tool *tool __maybe_unused,
                                union perf_event *event,
                                struct perf_sample *sample,
                                struct perf_evsel *evsel,
@@ -534,7 +535,7 @@ static struct perf_tool perf_script = {
 
 extern volatile int session_done;
 
-static void sig_handler(int sig __unused)
+static void sig_handler(int sig __maybe_unused)
 {
        session_done = 1;
 }
@@ -644,8 +645,8 @@ static void list_available_languages(void)
        fprintf(stderr, "\n");
 }
 
-static int parse_scriptname(const struct option *opt __used,
-                           const char *str, int unset __used)
+static int parse_scriptname(const struct option *opt __maybe_unused,
+                           const char *str, int unset __maybe_unused)
 {
        char spec[PATH_MAX];
        const char *script, *ext;
@@ -690,8 +691,8 @@ static int parse_scriptname(const struct option *opt __used,
        return 0;
 }
 
-static int parse_output_fields(const struct option *opt __used,
-                           const char *arg, int unset __used)
+static int parse_output_fields(const struct option *opt __maybe_unused,
+                           const char *arg, int unset __maybe_unused)
 {
        char *tok;
        int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
@@ -982,8 +983,9 @@ static char *get_script_root(struct dirent *script_dirent, const char *suffix)
        return script_root;
 }
 
-static int list_available_scripts(const struct option *opt __used,
-                                 const char *s __used, int unset __used)
+static int list_available_scripts(const struct option *opt __maybe_unused,
+                                 const char *s __maybe_unused,
+                                 int unset __maybe_unused)
 {
        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
        char scripts_path[MAXPATHLEN];
@@ -1030,6 +1032,61 @@ static int list_available_scripts(const struct option *opt __used,
        exit(0);
 }
 
+/*
+ * Return -1 if none is found, otherwise the actual scripts number.
+ *
+ * Currently the only user of this function is the script browser, which
+ * will list all statically runnable scripts, select one, execute it and
+ * show the output in a perf browser.
+ */
+int find_scripts(char **scripts_array, char **scripts_path_array)
+{
+       struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+       char scripts_path[MAXPATHLEN];
+       DIR *scripts_dir, *lang_dir;
+       char lang_path[MAXPATHLEN];
+       char *temp;
+       int i = 0;
+
+       snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
+
+       scripts_dir = opendir(scripts_path);
+       if (!scripts_dir)
+               return -1;
+
+       for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+               snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
+                        lang_dirent.d_name);
+#ifdef NO_LIBPERL
+               if (strstr(lang_path, "perl"))
+                       continue;
+#endif
+#ifdef NO_LIBPYTHON
+               if (strstr(lang_path, "python"))
+                       continue;
+#endif
+
+               lang_dir = opendir(lang_path);
+               if (!lang_dir)
+                       continue;
+
+               for_each_script(lang_path, lang_dir, script_dirent, script_next) {
+                       /* Skip those real time scripts: xxxtop.p[yl] */
+                       if (strstr(script_dirent.d_name, "top."))
+                               continue;
+                       sprintf(scripts_path_array[i], "%s/%s", lang_path,
+                               script_dirent.d_name);
+                       temp = strchr(script_dirent.d_name, '.');
+                       snprintf(scripts_array[i],
+                               (temp - script_dirent.d_name) + 1,
+                               "%s", script_dirent.d_name);
+                       i++;
+               }
+       }
+
+       return i;
+}
+
 static char *get_script_path(const char *script_root, const char *suffix)
 {
        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
@@ -1142,6 +1199,8 @@ static const struct option options[] = {
                     parse_output_fields),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                     "system-wide collection from all CPUs"),
+       OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
+                  "only consider these symbols"),
        OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
        OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
                   "only display events for these comms"),
@@ -1153,21 +1212,26 @@ static const struct option options[] = {
        OPT_END()
 };
 
-static bool have_cmd(int argc, const char **argv)
+static int have_cmd(int argc, const char **argv)
 {
        char **__argv = malloc(sizeof(const char *) * argc);
 
-       if (!__argv)
-               die("malloc");
+       if (!__argv) {
+               pr_err("malloc failed\n");
+               return -1;
+       }
+
        memcpy(__argv, argv, sizeof(const char *) * argc);
        argc = parse_options(argc, (const char **)__argv, record_options,
                             NULL, PARSE_OPT_STOP_AT_NON_OPTION);
        free(__argv);
 
-       return argc != 0;
+       system_wide = (argc == 0);
+
+       return 0;
 }
 
-int cmd_script(int argc, const char **argv, const char *prefix __used)
+int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        char *rec_script_path = NULL;
        char *rep_script_path = NULL;
@@ -1231,13 +1295,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
 
                if (pipe(live_pipe) < 0) {
                        perror("failed to create pipe");
-                       exit(-1);
+                       return -1;
                }
 
                pid = fork();
                if (pid < 0) {
                        perror("failed to fork");
-                       exit(-1);
+                       return -1;
                }
 
                if (!pid) {
@@ -1249,13 +1313,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                        if (is_top_script(argv[0])) {
                                system_wide = true;
                        } else if (!system_wide) {
-                               system_wide = !have_cmd(argc - rep_args,
-                                                       &argv[rep_args]);
+                               if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
+                                       err = -1;
+                                       goto out;
+                               }
                        }
 
                        __argv = malloc((argc + 6) * sizeof(const char *));
-                       if (!__argv)
-                               die("malloc");
+                       if (!__argv) {
+                               pr_err("malloc failed\n");
+                               err = -ENOMEM;
+                               goto out;
+                       }
 
                        __argv[j++] = "/bin/sh";
                        __argv[j++] = rec_script_path;
@@ -1277,8 +1346,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                close(live_pipe[1]);
 
                __argv = malloc((argc + 4) * sizeof(const char *));
-               if (!__argv)
-                       die("malloc");
+               if (!__argv) {
+                       pr_err("malloc failed\n");
+                       err = -ENOMEM;
+                       goto out;
+               }
+
                j = 0;
                __argv[j++] = "/bin/sh";
                __argv[j++] = rep_script_path;
@@ -1303,12 +1376,20 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
 
                if (!rec_script_path)
                        system_wide = false;
-               else if (!system_wide)
-                       system_wide = !have_cmd(argc - 1, &argv[1]);
+               else if (!system_wide) {
+                       if (have_cmd(argc - 1, &argv[1]) != 0) {
+                               err = -1;
+                               goto out;
+                       }
+               }
 
                __argv = malloc((argc + 2) * sizeof(const char *));
-               if (!__argv)
-                       die("malloc");
+               if (!__argv) {
+                       pr_err("malloc failed\n");
+                       err = -ENOMEM;
+                       goto out;
+               }
+
                __argv[j++] = "/bin/sh";
                __argv[j++] = script_path;
                if (system_wide)
@@ -1357,18 +1438,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                input = open(session->filename, O_RDONLY);      /* input_name */
                if (input < 0) {
                        perror("failed to open file");
-                       exit(-1);
+                       return -1;
                }
 
                err = fstat(input, &perf_stat);
                if (err < 0) {
                        perror("failed to stat file");
-                       exit(-1);
+                       return -1;
                }
 
                if (!perf_stat.st_size) {
                        fprintf(stderr, "zero-sized file, nothing to do!\n");
-                       exit(0);
+                       return 0;
                }
 
                scripting_ops = script_spec__lookup(generate_script_lang);
This page took 0.036956 seconds and 5 git commands to generate.