Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf script: Use openat for directory iteration

Rewrite the directory iteration to use openat so that large character
arrays aren't needed. The arrays are warned about potential buffer
overflows by GCC when the code exists in a single C file.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Veronika Molnarova <vmolnaro@redhat.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Link: https://lore.kernel.org/r/20241119011644.971342-7-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
f76f94dc 3f188942

+71 -27
+60 -27
tools/perf/builtin-script.c
··· 3535 3535 * which is covered well now. And new parsing code should be added to 3536 3536 * cover the future complex formats like event groups etc. 3537 3537 */ 3538 - static int check_ev_match(char *dir_name, char *scriptname, 3539 - struct perf_session *session) 3538 + static int check_ev_match(int dir_fd, const char *scriptname, struct perf_session *session) 3540 3539 { 3541 - char filename[MAXPATHLEN], evname[128]; 3542 - char line[BUFSIZ], *p; 3543 - struct evsel *pos; 3544 - int match, len; 3540 + char line[BUFSIZ]; 3545 3541 FILE *fp; 3546 3542 3547 - scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname); 3543 + { 3544 + char filename[FILENAME_MAX + 5]; 3545 + int fd; 3548 3546 3549 - fp = fopen(filename, "r"); 3550 - if (!fp) 3551 - return -1; 3547 + scnprintf(filename, sizeof(filename), "bin/%s-record", scriptname); 3548 + fd = openat(dir_fd, filename, O_RDONLY); 3549 + if (fd == -1) 3550 + return -1; 3551 + fp = fdopen(fd, "r"); 3552 + if (!fp) 3553 + return -1; 3554 + } 3552 3555 3553 3556 while (fgets(line, sizeof(line), fp)) { 3554 - p = skip_spaces(line); 3557 + char *p = skip_spaces(line); 3558 + 3555 3559 if (*p == '#') 3556 3560 continue; 3557 3561 3558 3562 while (strlen(p)) { 3563 + int match, len; 3564 + struct evsel *pos; 3565 + char evname[128]; 3566 + 3559 3567 p = strstr(p, "-e"); 3560 3568 if (!p) 3561 3569 break; ··· 3606 3598 int pathlen) 3607 3599 { 3608 3600 struct dirent *script_dirent, *lang_dirent; 3609 - char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 3601 + int scripts_dir_fd, lang_dir_fd; 3610 3602 DIR *scripts_dir, *lang_dir; 3611 3603 struct perf_session *session; 3612 3604 struct perf_data data = { ··· 3615 3607 }; 3616 3608 char *temp; 3617 3609 int i = 0; 3610 + const char *exec_path = get_argv_exec_path(); 3618 3611 3619 3612 session = perf_session__new(&data, NULL); 3620 3613 if (IS_ERR(session)) 3621 3614 return PTR_ERR(session); 3622 3615 3623 - snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 3616 + { 3617 + char scripts_path[PATH_MAX]; 3624 3618 3625 - scripts_dir = opendir(scripts_path); 3619 + snprintf(scripts_path, sizeof(scripts_path), "%s/scripts", exec_path); 3620 + scripts_dir_fd = open(scripts_path, O_DIRECTORY); 3621 + pr_err("Failed to open directory '%s'", scripts_path); 3622 + if (scripts_dir_fd == -1) { 3623 + perf_session__delete(session); 3624 + return -1; 3625 + } 3626 + } 3627 + scripts_dir = fdopendir(scripts_dir_fd); 3626 3628 if (!scripts_dir) { 3629 + close(scripts_dir_fd); 3627 3630 perf_session__delete(session); 3628 3631 return -1; 3629 3632 } 3630 3633 3631 - for_each_lang(scripts_path, scripts_dir, lang_dirent) { 3632 - scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, 3633 - lang_dirent->d_name); 3634 + while ((lang_dirent = readdir(scripts_dir)) != NULL) { 3635 + if (lang_dirent->d_type != DT_DIR && 3636 + (lang_dirent->d_type == DT_UNKNOWN && 3637 + !is_directory_at(scripts_dir_fd, lang_dirent->d_name))) 3638 + continue; 3639 + if (!strcmp(lang_dirent->d_name, ".") || !strcmp(lang_dirent->d_name, "..")) 3640 + continue; 3641 + 3634 3642 #ifndef HAVE_LIBPERL_SUPPORT 3635 - if (strstr(lang_path, "perl")) 3643 + if (strstr(lang_dirent->d_name, "perl")) 3636 3644 continue; 3637 3645 #endif 3638 3646 #ifndef HAVE_LIBPYTHON_SUPPORT 3639 - if (strstr(lang_path, "python")) 3647 + if (strstr(lang_dirent->d_name, "python")) 3640 3648 continue; 3641 3649 #endif 3642 3650 3643 - lang_dir = opendir(lang_path); 3644 - if (!lang_dir) 3651 + lang_dir_fd = openat(scripts_dir_fd, lang_dirent->d_name, O_DIRECTORY); 3652 + if (lang_dir_fd == -1) 3645 3653 continue; 3646 - 3647 - for_each_script(lang_path, lang_dir, script_dirent) { 3654 + lang_dir = fdopendir(lang_dir_fd); 3655 + if (!lang_dir) { 3656 + close(lang_dir_fd); 3657 + continue; 3658 + } 3659 + while ((script_dirent = readdir(lang_dir)) != NULL) { 3660 + if (script_dirent->d_type == DT_DIR) 3661 + continue; 3662 + if (script_dirent->d_type == DT_UNKNOWN && 3663 + is_directory_at(lang_dir_fd, script_dirent->d_name)) 3664 + continue; 3648 3665 /* Skip those real time scripts: xxxtop.p[yl] */ 3649 3666 if (strstr(script_dirent->d_name, "top.")) 3650 3667 continue; 3651 3668 if (i >= num) 3652 3669 break; 3653 - snprintf(scripts_path_array[i], pathlen, "%s/%s", 3654 - lang_path, 3670 + scnprintf(scripts_path_array[i], pathlen, "%s/scripts/%s/%s", 3671 + exec_path, 3672 + lang_dirent->d_name, 3655 3673 script_dirent->d_name); 3656 3674 temp = strchr(script_dirent->d_name, '.'); 3657 3675 snprintf(scripts_array[i], 3658 3676 (temp - script_dirent->d_name) + 1, 3659 3677 "%s", script_dirent->d_name); 3660 3678 3661 - if (check_ev_match(lang_path, 3662 - scripts_array[i], session)) 3679 + if (check_ev_match(lang_dir_fd, scripts_array[i], session)) 3663 3680 continue; 3664 3681 3665 3682 i++;
+10
tools/perf/util/path.c
··· 68 68 return S_ISDIR(st.st_mode); 69 69 } 70 70 71 + bool is_directory_at(int dir_fd, const char *path) 72 + { 73 + struct stat st; 74 + 75 + if (fstatat(dir_fd, path, &st, /*flags=*/0)) 76 + return false; 77 + 78 + return S_ISDIR(st.st_mode); 79 + } 80 + 71 81 bool is_executable_file(const char *base_path, const struct dirent *dent) 72 82 { 73 83 char path[PATH_MAX];
+1
tools/perf/util/path.h
··· 12 12 13 13 bool is_regular_file(const char *file); 14 14 bool is_directory(const char *base_path, const struct dirent *dent); 15 + bool is_directory_at(int dir_fd, const char *path); 15 16 bool is_executable_file(const char *base_path, const struct dirent *dent); 16 17 17 18 #endif /* _PERF_PATH_H */