From f6f4b4b39f02d95b692ad22003490d1db9734f1c Mon Sep 17 00:00:00 2001 From: Yoshitaka Seto Date: Wed, 16 Jan 2019 17:47:48 +0900 Subject: [PATCH] AOSP: misc: use scandir with alphasort instead of readdir for consistency During the image generation, When using the e2fsdroid with src_dir, then dir files are listed with readdir, which will not guarantee the order across the machines/fielsystems. So instead using the scandir with alphasort option to list the files in sorted order. Bug: 122874817 Change-Id: I4b946c737319252b82c74a0e10360843503862a1 From AOSP commit: 4cbe059b48b46d6657e24e4cdef543da7537dba3 Reported-by: Yasuhiro Kubota Tested-by: Yasuhiro Kubota Signed-off-by: Vikram Dattu Thota Signed-off-by: Takuya Ogawa Signed-off-by: Yoshitaka Seto Signed-off-by: Theodore Ts'o --- misc/create_inode.c | 89 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/misc/create_inode.c b/misc/create_inode.c index b288935d7..0091b7237 100644 --- a/misc/create_inode.c +++ b/misc/create_inode.c @@ -19,6 +19,7 @@ #include #include #include /* for PATH_MAX */ +#include /* for scandir() and alphasort() */ #if defined HAVE_SYS_XATTR_H #include #elif defined HAVE_ATTR_XATTR_H @@ -717,7 +718,69 @@ static errcode_t path_append(struct file_info *target, const char *file) return 0; } -/* Copy files from source_dir to fs */ +#ifdef _WIN32 +static int scandir(const char *dir_name, struct dirent ***name_list, + int (*filter)(const struct dirent*), + int (*compar)(const struct dirent**, const struct dirent**)) { + DIR *dir; + struct dirent *dent; + struct dirent **temp_list = NULL; + size_t temp_list_size = 0; // unit: num of dirent + size_t num_dent = 0; + + dir = opendir(dir_name); + if (dir == NULL) { + return -1; + } + + while ((dent = readdir(dir))) { + if (filter != NULL && !(*filter)(dent)) + continue; + + // re-allocate the list + if (num_dent == temp_list_size) { + size_t new_list_size = temp_list_size + 32; + struct dirent **new_list = (struct dirent**)realloc( + temp_list, new_list_size * sizeof(struct dirent*)); + if (new_list == NULL) { + goto out; + } + temp_list_size = new_list_size; + temp_list = new_list; + } + // add the copy of dirent to the list + temp_list[num_dent] = (struct dirent*)malloc((dent->d_reclen + 3) & ~3); + memcpy(temp_list[num_dent], dent, dent->d_reclen); + num_dent++; + } + + if (compar != NULL) { + qsort(temp_list, num_dent, sizeof(struct dirent*), + (int (*)(const void*, const void*))compar); + } + + // release the temp list + *name_list = temp_list; + temp_list = NULL; + +out: + if (temp_list != NULL) { + while (num_dent > 0) { + free(temp_list[--num_dent]); + } + free(temp_list); + num_dent = -1; + } + closedir(dir); + return num_dent; +} + +static int alphasort(const struct dirent **a, const struct dirent **b) { + return strcoll((*a)->d_name, (*b)->d_name); +} +#endif + +/* Copy files from source_dir to fs in alphabetical order */ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino, const char *source_dir, ext2_ino_t root, struct hdlinks_s *hdlinks, @@ -725,8 +788,7 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino, struct fs_ops_callbacks *fs_callbacks) { const char *name; - DIR *dh; - struct dirent *dent; + struct dirent **dent; struct stat st; char *ln_target = NULL; unsigned int save_inode; @@ -735,6 +797,7 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino, int read_cnt; int hdlink; size_t cur_dir_path_len; + int i, num_dents; if (chdir(source_dir) < 0) { retval = errno; @@ -744,24 +807,25 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino, return retval; } - if (!(dh = opendir("."))) { + num_dents = scandir(".", &dent, NULL, alphasort); + + if (num_dents < 0) { retval = errno; com_err(__func__, retval, - _("while opening directory \"%s\""), source_dir); + _("while scanning directory \"%s\""), source_dir); return retval; } - while ((dent = readdir(dh))) { - if ((!strcmp(dent->d_name, ".")) || - (!strcmp(dent->d_name, ".."))) + for (i = 0; i < num_dents; free(dent[i]), i++) { + name = dent[i]->d_name; + if ((!strcmp(name, ".")) || (!strcmp(name, ".."))) continue; - if (lstat(dent->d_name, &st)) { + if (lstat(name, &st)) { retval = errno; com_err(__func__, retval, _("while lstat \"%s\""), - dent->d_name); + name); goto out; } - name = dent->d_name; /* Check for hardlinks */ save_inode = 0; @@ -953,7 +1017,8 @@ find_lnf: } out: - closedir(dh); + for (; i < num_dents; free(dent[i]), i++); + free(dent); return retval; } -- 2.39.2