perf script: Use readdir() instead of deprecated readdir_r()

The readdir() function is thread safe as long as just one thread uses a
DIR, which is the case in 'perf script', so, to avoid breaking the build
with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().

See: http://man7.org/linux/man-pages/man3/readdir.3.html

"However, in modern implementations (including the glibc implementation),
concurrent calls to readdir() that specify different directory streams
are thread-safe.  In cases where multiple threads must read from the
same directory stream, using readdir() with external synchronization is
still preferable to the use of the deprecated readdir_r(3) function."

Noticed while building on a Fedora Rawhide docker container.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-mt3xz7n2hl49ni2vx7kuq74g@git.kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 2515e614
...@@ -1415,21 +1415,19 @@ static int is_directory(const char *base_path, const struct dirent *dent) ...@@ -1415,21 +1415,19 @@ static int is_directory(const char *base_path, const struct dirent *dent)
return S_ISDIR(st.st_mode); return S_ISDIR(st.st_mode);
} }
#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \
while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ while ((lang_dirent = readdir(scripts_dir)) != NULL) \
lang_next) \ if ((lang_dirent->d_type == DT_DIR || \
if ((lang_dirent.d_type == DT_DIR || \ (lang_dirent->d_type == DT_UNKNOWN && \
(lang_dirent.d_type == DT_UNKNOWN && \ is_directory(scripts_path, lang_dirent))) && \
is_directory(scripts_path, &lang_dirent))) && \ (strcmp(lang_dirent->d_name, ".")) && \
(strcmp(lang_dirent.d_name, ".")) && \ (strcmp(lang_dirent->d_name, "..")))
(strcmp(lang_dirent.d_name, "..")))
#define for_each_script(lang_path, lang_dir, script_dirent) \
#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ while ((script_dirent = readdir(lang_dir)) != NULL) \
while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ if (script_dirent->d_type != DT_DIR && \
script_next) \ (script_dirent->d_type != DT_UNKNOWN || \
if (script_dirent.d_type != DT_DIR && \ !is_directory(lang_path, script_dirent)))
(script_dirent.d_type != DT_UNKNOWN || \
!is_directory(lang_path, &script_dirent)))
#define RECORD_SUFFIX "-record" #define RECORD_SUFFIX "-record"
...@@ -1575,7 +1573,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused, ...@@ -1575,7 +1573,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
const char *s __maybe_unused, const char *s __maybe_unused,
int unset __maybe_unused) int unset __maybe_unused)
{ {
struct dirent *script_next, *lang_next, script_dirent, lang_dirent; struct dirent *script_dirent, *lang_dirent;
char scripts_path[MAXPATHLEN]; char scripts_path[MAXPATHLEN];
DIR *scripts_dir, *lang_dir; DIR *scripts_dir, *lang_dir;
char script_path[MAXPATHLEN]; char script_path[MAXPATHLEN];
...@@ -1590,19 +1588,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused, ...@@ -1590,19 +1588,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
if (!scripts_dir) if (!scripts_dir)
return -1; return -1;
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { for_each_lang(scripts_path, scripts_dir, lang_dirent) {
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
lang_dirent.d_name); lang_dirent->d_name);
lang_dir = opendir(lang_path); lang_dir = opendir(lang_path);
if (!lang_dir) if (!lang_dir)
continue; continue;
for_each_script(lang_path, lang_dir, script_dirent, script_next) { for_each_script(lang_path, lang_dir, script_dirent) {
script_root = get_script_root(&script_dirent, REPORT_SUFFIX); script_root = get_script_root(script_dirent, REPORT_SUFFIX);
if (script_root) { if (script_root) {
desc = script_desc__findnew(script_root); desc = script_desc__findnew(script_root);
snprintf(script_path, MAXPATHLEN, "%s/%s", snprintf(script_path, MAXPATHLEN, "%s/%s",
lang_path, script_dirent.d_name); lang_path, script_dirent->d_name);
read_script_info(desc, script_path); read_script_info(desc, script_path);
free(script_root); free(script_root);
} }
...@@ -1690,7 +1688,7 @@ static int check_ev_match(char *dir_name, char *scriptname, ...@@ -1690,7 +1688,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
*/ */
int find_scripts(char **scripts_array, char **scripts_path_array) int find_scripts(char **scripts_array, char **scripts_path_array)
{ {
struct dirent *script_next, *lang_next, script_dirent, lang_dirent; struct dirent *script_dirent, *lang_dirent;
char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
DIR *scripts_dir, *lang_dir; DIR *scripts_dir, *lang_dir;
struct perf_session *session; struct perf_session *session;
...@@ -1713,9 +1711,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array) ...@@ -1713,9 +1711,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
return -1; return -1;
} }
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { for_each_lang(scripts_path, scripts_dir, lang_dirent) {
snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
lang_dirent.d_name); lang_dirent->d_name);
#ifdef NO_LIBPERL #ifdef NO_LIBPERL
if (strstr(lang_path, "perl")) if (strstr(lang_path, "perl"))
continue; continue;
...@@ -1729,16 +1727,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array) ...@@ -1729,16 +1727,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
if (!lang_dir) if (!lang_dir)
continue; continue;
for_each_script(lang_path, lang_dir, script_dirent, script_next) { for_each_script(lang_path, lang_dir, script_dirent) {
/* Skip those real time scripts: xxxtop.p[yl] */ /* Skip those real time scripts: xxxtop.p[yl] */
if (strstr(script_dirent.d_name, "top.")) if (strstr(script_dirent->d_name, "top."))
continue; continue;
sprintf(scripts_path_array[i], "%s/%s", lang_path, sprintf(scripts_path_array[i], "%s/%s", lang_path,
script_dirent.d_name); script_dirent->d_name);
temp = strchr(script_dirent.d_name, '.'); temp = strchr(script_dirent->d_name, '.');
snprintf(scripts_array[i], snprintf(scripts_array[i],
(temp - script_dirent.d_name) + 1, (temp - script_dirent->d_name) + 1,
"%s", script_dirent.d_name); "%s", script_dirent->d_name);
if (check_ev_match(lang_path, if (check_ev_match(lang_path,
scripts_array[i], session)) scripts_array[i], session))
...@@ -1756,7 +1754,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array) ...@@ -1756,7 +1754,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
static char *get_script_path(const char *script_root, const char *suffix) static char *get_script_path(const char *script_root, const char *suffix)
{ {
struct dirent *script_next, *lang_next, script_dirent, lang_dirent; struct dirent *script_dirent, *lang_dirent;
char scripts_path[MAXPATHLEN]; char scripts_path[MAXPATHLEN];
char script_path[MAXPATHLEN]; char script_path[MAXPATHLEN];
DIR *scripts_dir, *lang_dir; DIR *scripts_dir, *lang_dir;
...@@ -1769,21 +1767,21 @@ static char *get_script_path(const char *script_root, const char *suffix) ...@@ -1769,21 +1767,21 @@ static char *get_script_path(const char *script_root, const char *suffix)
if (!scripts_dir) if (!scripts_dir)
return NULL; return NULL;
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { for_each_lang(scripts_path, scripts_dir, lang_dirent) {
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
lang_dirent.d_name); lang_dirent->d_name);
lang_dir = opendir(lang_path); lang_dir = opendir(lang_path);
if (!lang_dir) if (!lang_dir)
continue; continue;
for_each_script(lang_path, lang_dir, script_dirent, script_next) { for_each_script(lang_path, lang_dir, script_dirent) {
__script_root = get_script_root(&script_dirent, suffix); __script_root = get_script_root(script_dirent, suffix);
if (__script_root && !strcmp(script_root, __script_root)) { if (__script_root && !strcmp(script_root, __script_root)) {
free(__script_root); free(__script_root);
closedir(lang_dir); closedir(lang_dir);
closedir(scripts_dir); closedir(scripts_dir);
snprintf(script_path, MAXPATHLEN, "%s/%s", snprintf(script_path, MAXPATHLEN, "%s/%s",
lang_path, script_dirent.d_name); lang_path, script_dirent->d_name);
return strdup(script_path); return strdup(script_path);
} }
free(__script_root); free(__script_root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment