mirror of
https://github.com/torvalds/linux.git
synced 2026-03-14 00:56:20 +01:00
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>
This commit is contained in:
parent
3f1889422a
commit
f76f94dc78
3 changed files with 71 additions and 27 deletions
|
|
@ -3535,27 +3535,35 @@ static void free_dlarg(void)
|
|||
* which is covered well now. And new parsing code should be added to
|
||||
* cover the future complex formats like event groups etc.
|
||||
*/
|
||||
static int check_ev_match(char *dir_name, char *scriptname,
|
||||
struct perf_session *session)
|
||||
static int check_ev_match(int dir_fd, const char *scriptname, struct perf_session *session)
|
||||
{
|
||||
char filename[MAXPATHLEN], evname[128];
|
||||
char line[BUFSIZ], *p;
|
||||
struct evsel *pos;
|
||||
int match, len;
|
||||
char line[BUFSIZ];
|
||||
FILE *fp;
|
||||
|
||||
scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
|
||||
{
|
||||
char filename[FILENAME_MAX + 5];
|
||||
int fd;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp)
|
||||
return -1;
|
||||
scnprintf(filename, sizeof(filename), "bin/%s-record", scriptname);
|
||||
fd = openat(dir_fd, filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
fp = fdopen(fd, "r");
|
||||
if (!fp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
p = skip_spaces(line);
|
||||
char *p = skip_spaces(line);
|
||||
|
||||
if (*p == '#')
|
||||
continue;
|
||||
|
||||
while (strlen(p)) {
|
||||
int match, len;
|
||||
struct evsel *pos;
|
||||
char evname[128];
|
||||
|
||||
p = strstr(p, "-e");
|
||||
if (!p)
|
||||
break;
|
||||
|
|
@ -3598,7 +3606,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
|
|||
int pathlen)
|
||||
{
|
||||
struct dirent *script_dirent, *lang_dirent;
|
||||
char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
|
||||
int scripts_dir_fd, lang_dir_fd;
|
||||
DIR *scripts_dir, *lang_dir;
|
||||
struct perf_session *session;
|
||||
struct perf_data data = {
|
||||
|
|
@ -3607,51 +3615,76 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
|
|||
};
|
||||
char *temp;
|
||||
int i = 0;
|
||||
const char *exec_path = get_argv_exec_path();
|
||||
|
||||
session = perf_session__new(&data, NULL);
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
|
||||
{
|
||||
char scripts_path[PATH_MAX];
|
||||
|
||||
scripts_dir = opendir(scripts_path);
|
||||
snprintf(scripts_path, sizeof(scripts_path), "%s/scripts", exec_path);
|
||||
scripts_dir_fd = open(scripts_path, O_DIRECTORY);
|
||||
pr_err("Failed to open directory '%s'", scripts_path);
|
||||
if (scripts_dir_fd == -1) {
|
||||
perf_session__delete(session);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
scripts_dir = fdopendir(scripts_dir_fd);
|
||||
if (!scripts_dir) {
|
||||
close(scripts_dir_fd);
|
||||
perf_session__delete(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for_each_lang(scripts_path, scripts_dir, lang_dirent) {
|
||||
scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
|
||||
lang_dirent->d_name);
|
||||
while ((lang_dirent = readdir(scripts_dir)) != NULL) {
|
||||
if (lang_dirent->d_type != DT_DIR &&
|
||||
(lang_dirent->d_type == DT_UNKNOWN &&
|
||||
!is_directory_at(scripts_dir_fd, lang_dirent->d_name)))
|
||||
continue;
|
||||
if (!strcmp(lang_dirent->d_name, ".") || !strcmp(lang_dirent->d_name, ".."))
|
||||
continue;
|
||||
|
||||
#ifndef HAVE_LIBPERL_SUPPORT
|
||||
if (strstr(lang_path, "perl"))
|
||||
if (strstr(lang_dirent->d_name, "perl"))
|
||||
continue;
|
||||
#endif
|
||||
#ifndef HAVE_LIBPYTHON_SUPPORT
|
||||
if (strstr(lang_path, "python"))
|
||||
if (strstr(lang_dirent->d_name, "python"))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
lang_dir = opendir(lang_path);
|
||||
if (!lang_dir)
|
||||
lang_dir_fd = openat(scripts_dir_fd, lang_dirent->d_name, O_DIRECTORY);
|
||||
if (lang_dir_fd == -1)
|
||||
continue;
|
||||
|
||||
for_each_script(lang_path, lang_dir, script_dirent) {
|
||||
lang_dir = fdopendir(lang_dir_fd);
|
||||
if (!lang_dir) {
|
||||
close(lang_dir_fd);
|
||||
continue;
|
||||
}
|
||||
while ((script_dirent = readdir(lang_dir)) != NULL) {
|
||||
if (script_dirent->d_type == DT_DIR)
|
||||
continue;
|
||||
if (script_dirent->d_type == DT_UNKNOWN &&
|
||||
is_directory_at(lang_dir_fd, script_dirent->d_name))
|
||||
continue;
|
||||
/* Skip those real time scripts: xxxtop.p[yl] */
|
||||
if (strstr(script_dirent->d_name, "top."))
|
||||
continue;
|
||||
if (i >= num)
|
||||
break;
|
||||
snprintf(scripts_path_array[i], pathlen, "%s/%s",
|
||||
lang_path,
|
||||
scnprintf(scripts_path_array[i], pathlen, "%s/scripts/%s/%s",
|
||||
exec_path,
|
||||
lang_dirent->d_name,
|
||||
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);
|
||||
|
||||
if (check_ev_match(lang_path,
|
||||
scripts_array[i], session))
|
||||
if (check_ev_match(lang_dir_fd, scripts_array[i], session))
|
||||
continue;
|
||||
|
||||
i++;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,16 @@ bool is_directory(const char *base_path, const struct dirent *dent)
|
|||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
bool is_directory_at(int dir_fd, const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstatat(dir_fd, path, &st, /*flags=*/0))
|
||||
return false;
|
||||
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
bool is_executable_file(const char *base_path, const struct dirent *dent)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ int path__join3(char *bf, size_t size, const char *path1, const char *path2, con
|
|||
|
||||
bool is_regular_file(const char *file);
|
||||
bool is_directory(const char *base_path, const struct dirent *dent);
|
||||
bool is_directory_at(int dir_fd, const char *path);
|
||||
bool is_executable_file(const char *base_path, const struct dirent *dent);
|
||||
|
||||
#endif /* _PERF_PATH_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue