aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoshitaka Seto <yoshitaka.seto@sony.com>2019-01-16 17:47:48 +0900
committerJiyong Park <jiyong@google.com>2019-02-12 01:14:18 +0900
commit4cbe059b48b46d6657e24e4cdef543da7537dba3 (patch)
treeb06d0c88bbb30a086e86db50dd51ed78e49d994e
parent2073e2bf4d91781f4c2c0d815f791d9f79ad5bfb (diff)
downloadandroid_external_e2fsprogs-4cbe059b48b46d6657e24e4cdef543da7537dba3.tar.gz
android_external_e2fsprogs-4cbe059b48b46d6657e24e4cdef543da7537dba3.tar.bz2
android_external_e2fsprogs-4cbe059b48b46d6657e24e4cdef543da7537dba3.zip
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. Reported-by: Yasuhiro Kubota <yasuhiro.1.kubota@sony.com> Signed-off-by: Vikram Dattu Thota <vikram.dattu@sony.com> Signed-off-by: Takuya Ogawa <takuya.ogawa@sony.com> Signed-off-by: Yoshitaka Seto <yoshitaka.seto@sony.com> Tested-by: Yasuhiro Kubota <yasuhiro.1.kubota@sony.com> Bug: 122874817 Change-Id: I4b946c737319252b82c74a0e10360843503862a1
-rw-r--r--misc/create_inode.c89
1 files changed, 77 insertions, 12 deletions
diff --git a/misc/create_inode.c b/misc/create_inode.c
index 05aa6363..0cbbd3ba 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;
}