From 5d5a6a48e9529fccac9e4c3487577276f8da69ef Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Mon, 29 Jan 2018 12:10:53 +0100 Subject: [PATCH] Process included directories in alphabetical order readdir() and FindFirstFile()/FindNextFile() do not define any ordering on the entries they return. Use sorted scandir() instead on Unix-likes. (cherry picked from commit c2734538945d284a21bc8ad17404fca1eecdcf86) --- src/util/profile/prof_parse.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c index 1baceea9e..6c77f3a0c 100644 --- a/src/util/profile/prof_parse.c +++ b/src/util/profile/prof_parse.c @@ -241,12 +241,18 @@ static int valid_name(const char *filename) } return 1; } +#ifndef _WIN32 +static int valid_name_scandir(const struct dirent *d) +{ + return valid_name(d->d_name); +} +#endif /* * Include files within dirname. Only files with names ending in ".conf", or * consisting entirely of alphanumeric characters, dashes, and underscores are * included. This restriction avoids including editor backup files, .rpmsave - * files, and the like. + * files, and the like. Files are processed in alphanumeric order. */ static errcode_t parse_include_dir(const char *dirname, struct profile_node *root_section) @@ -287,18 +293,17 @@ cleanup: #else /* not _WIN32 */ - DIR *dir; char *pathname; errcode_t retval = 0; - struct dirent *ent; + struct dirent **namelist; + int num_ents, i; - dir = opendir(dirname); - if (dir == NULL) + num_ents = scandir(dirname, &namelist, &valid_name_scandir, &alphasort); + if (num_ents == -1) return PROF_FAIL_INCLUDE_DIR; - while ((ent = readdir(dir)) != NULL) { - if (!valid_name(ent->d_name)) - continue; - if (asprintf(&pathname, "%s/%s", dirname, ent->d_name) < 0) { + + for (i = 0; i < num_ents; i++) { + if (asprintf(&pathname, "%s/%s", dirname, namelist[i]->d_name) < 0) { retval = ENOMEM; break; } @@ -307,7 +312,8 @@ cleanup: if (retval) break; } - closedir(dir); + + free(namelist); return retval; #endif /* not _WIN32 */ }