diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-trace.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7674153c4bbe..7e744f774047 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -469,6 +469,49 @@ static int list_available_scripts(const struct option *opt __used, | |||
469 | exit(0); | 469 | exit(0); |
470 | } | 470 | } |
471 | 471 | ||
472 | static char *get_script_path(const char *script_root, const char *suffix) | ||
473 | { | ||
474 | struct dirent *script_next, *lang_next, script_dirent, lang_dirent; | ||
475 | char scripts_path[MAXPATHLEN]; | ||
476 | char script_path[MAXPATHLEN]; | ||
477 | DIR *scripts_dir, *lang_dir; | ||
478 | char lang_path[MAXPATHLEN]; | ||
479 | char *str, *__script_root; | ||
480 | char *path = NULL; | ||
481 | |||
482 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | ||
483 | |||
484 | scripts_dir = opendir(scripts_path); | ||
485 | if (!scripts_dir) | ||
486 | return NULL; | ||
487 | |||
488 | for_each_lang(scripts_dir, lang_dirent, lang_next) { | ||
489 | snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, | ||
490 | lang_dirent.d_name); | ||
491 | lang_dir = opendir(lang_path); | ||
492 | if (!lang_dir) | ||
493 | continue; | ||
494 | |||
495 | for_each_script(lang_dir, script_dirent, script_next) { | ||
496 | __script_root = strdup(script_dirent.d_name); | ||
497 | str = ends_with(__script_root, suffix); | ||
498 | if (str) { | ||
499 | *str = '\0'; | ||
500 | if (strcmp(__script_root, script_root)) | ||
501 | continue; | ||
502 | snprintf(script_path, MAXPATHLEN, "%s/%s", | ||
503 | lang_path, script_dirent.d_name); | ||
504 | path = strdup(script_path); | ||
505 | free(__script_root); | ||
506 | break; | ||
507 | } | ||
508 | free(__script_root); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | return path; | ||
513 | } | ||
514 | |||
472 | static const char * const annotate_usage[] = { | 515 | static const char * const annotate_usage[] = { |
473 | "perf trace [<options>] <command>", | 516 | "perf trace [<options>] <command>", |
474 | NULL | 517 | NULL |
@@ -494,8 +537,47 @@ static const struct option options[] = { | |||
494 | 537 | ||
495 | int cmd_trace(int argc, const char **argv, const char *prefix __used) | 538 | int cmd_trace(int argc, const char **argv, const char *prefix __used) |
496 | { | 539 | { |
497 | int err; | ||
498 | struct perf_session *session; | 540 | struct perf_session *session; |
541 | const char *suffix = NULL; | ||
542 | const char **__argv; | ||
543 | char *script_path; | ||
544 | int i, err; | ||
545 | |||
546 | if (argc >= 2 && strncmp(argv[1], "rec", strlen("rec")) == 0) { | ||
547 | if (argc < 3) { | ||
548 | fprintf(stderr, | ||
549 | "Please specify a record script\n"); | ||
550 | return -1; | ||
551 | } | ||
552 | suffix = RECORD_SUFFIX; | ||
553 | } | ||
554 | |||
555 | if (argc >= 2 && strncmp(argv[1], "rep", strlen("rep")) == 0) { | ||
556 | if (argc < 3) { | ||
557 | fprintf(stderr, | ||
558 | "Please specify a report script\n"); | ||
559 | return -1; | ||
560 | } | ||
561 | suffix = REPORT_SUFFIX; | ||
562 | } | ||
563 | |||
564 | if (suffix) { | ||
565 | script_path = get_script_path(argv[2], suffix); | ||
566 | if (!script_path) { | ||
567 | fprintf(stderr, "script not found\n"); | ||
568 | return -1; | ||
569 | } | ||
570 | |||
571 | __argv = malloc((argc + 1) * sizeof(const char *)); | ||
572 | __argv[0] = "/bin/sh"; | ||
573 | __argv[1] = script_path; | ||
574 | for (i = 3; i < argc; i++) | ||
575 | __argv[i - 1] = argv[i]; | ||
576 | __argv[argc - 1] = NULL; | ||
577 | |||
578 | execvp("/bin/sh", (char **)__argv); | ||
579 | exit(-1); | ||
580 | } | ||
499 | 581 | ||
500 | symbol__init(0); | 582 | symbol__init(0); |
501 | 583 | ||