diff options
author | Jiyong Park <jiyong@google.com> | 2019-02-13 05:37:46 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-02-13 05:37:46 +0000 |
commit | bfe0f47fe1d6806b929896d60fb4916f642f1f50 (patch) | |
tree | 95f390b8228d8549ed13d5ae4ffad82d196bc122 | |
parent | 849299cdc876caea9cee8d15483efd3e46a2c83c (diff) | |
parent | 4cbe059b48b46d6657e24e4cdef543da7537dba3 (diff) | |
download | android_external_e2fsprogs-bfe0f47fe1d6806b929896d60fb4916f642f1f50.tar.gz android_external_e2fsprogs-bfe0f47fe1d6806b929896d60fb4916f642f1f50.tar.bz2 android_external_e2fsprogs-bfe0f47fe1d6806b929896d60fb4916f642f1f50.zip |
Merge "misc: use scandir with alphasort instead of readdir for consistency"
-rw-r--r-- | misc/create_inode.c | 89 |
1 files changed, 77 insertions, 12 deletions
diff --git a/misc/create_inode.c b/misc/create_inode.c index 7b3a8ee2..21ff9f10 100644 --- a/misc/create_inode.c +++ b/misc/create_inode.c @@ -19,6 +19,7 @@ #include <sys/types.h> #include <unistd.h> #include <limits.h> /* for PATH_MAX */ +#include <dirent.h> /* for scandir() and alphasort() */ #if defined HAVE_SYS_XATTR_H #include <sys/xattr.h> #elif defined HAVE_ATTR_XATTR_H @@ -714,7 +715,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, @@ -722,8 +785,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; @@ -732,6 +794,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; @@ -741,24 +804,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; @@ -950,7 +1014,8 @@ find_lnf: } out: - closedir(dh); + for (; i < num_dents; free(dent[i]), i++); + free(dent); return retval; } |