diff --git a/include/libbb.h b/include/libbb.h index a362bd3..1f6afaa 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -17,6 +17,7 @@ ACTION_FOLLOWLINKS = (1 << 1), ACTION_DEPTHFIRST = (1 << 2), /*ACTION_REVERSE = (1 << 3), - unused */ + ACTION_SORT = (1 << 4), }; int recursive_action(const char *fileName, unsigned flags, diff --git a/lib/list_sort.c b/lib/list_sort.c index b7e74f2..84c6f64 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c @@ -1,7 +1,6 @@ #ifndef __BAREBOX__ #include -#include -#include +#define EXPORT_SYMBOL(x) #else #include #include diff --git a/lib/recursive_action.c b/lib/recursive_action.c index 345d3db..9505c86 100644 --- a/lib/recursive_action.c +++ b/lib/recursive_action.c @@ -13,9 +13,28 @@ #include #include #include +#include + +/* + * Sorting not required for barebox itself currently, support for it is only added + * for generating reproducible envfs images on the build host. + */ +#define DO_SORT(flags) 0 + +#else + +#define DO_SORT(flags) ((flags) & ACTION_SORT) #endif +#include +#include + +struct dirlist { + char *dirname; + struct list_head list; +}; + /* * Walk down all the directories under the specified * location, and do something (something specified @@ -33,6 +52,19 @@ return 1; } +static int cmp_dirlist(void *priv, struct list_head *a, struct list_head *b) +{ + struct dirlist *ra, *rb; + + if (a == b) + return 0; + + ra = list_entry(a, struct dirlist, list); + rb = list_entry(b, struct dirlist, list); + + return strcmp(ra->dirname, rb->dirname); +} + /* fileAction return value of 0 on any file in directory will make * recursive_action() return 0, but it doesn't stop directory traversal * (fileAction/dirAction will be called on each file). @@ -58,6 +90,8 @@ int status; DIR *dir; struct dirent *next; + struct dirlist *entry, *entry_tmp; + LIST_HEAD(dirs); if (!fileAction) fileAction = true_action; if (!dirAction) dirAction = true_action; @@ -106,19 +140,40 @@ /* To trigger: "find -exec rm -rf {} \;" */ goto done_nak_warn; } + status = 1; while ((next = readdir(dir)) != NULL) { - char *nextFile; - - nextFile = concat_subpath_file(fileName, next->d_name); + char *nextFile = concat_subpath_file(fileName, next->d_name); if (nextFile == NULL) continue; - /* now descend into it, forcing recursion. */ - if (!recursive_action(nextFile, flags | ACTION_RECURSE, - fileAction, dirAction, userData, depth+1)) { - status = 0; + + if (DO_SORT(flags)) { + struct dirlist *e = xmalloc(sizeof(*e)); + e->dirname = nextFile; + list_add(&e->list, &dirs); + } else { + /* descend into it, forcing recursion. */ + if (!recursive_action(nextFile, flags | ACTION_RECURSE, + fileAction, dirAction, userData, depth+1)) { + status = 0; + } + free(nextFile); } - free(nextFile); + } + + if (DO_SORT(flags)) { + list_sort(NULL, &dirs, &cmp_dirlist); + + list_for_each_entry_safe(entry, entry_tmp, &dirs, list){ + /* descend into it, forcing recursion. */ + if (!recursive_action(entry->dirname, flags | ACTION_RECURSE, + fileAction, dirAction, userData, depth+1)) { + status = 0; + } + + list_del(&entry->list); + free(entry->dirname); + } } closedir(dir); if ((flags & ACTION_DEPTHFIRST) && diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index 249e65b..e95bdea 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -34,6 +34,7 @@ #include "compiler.h" #define debug(...) +#define printk_once(...) /* Find out if the last character of a string matches the one given. * Don't underrun the buffer if the string length is 0. @@ -54,6 +55,7 @@ ACTION_FOLLOWLINKS = (1 << 1), ACTION_DEPTHFIRST = (1 << 2), /*ACTION_REVERSE = (1 << 3), - unused */ + ACTION_SORT = (1 << 4), }; int recursive_action(const char *fileName, unsigned flags, @@ -95,6 +97,19 @@ return concat_path_file(path, f); } +static char *xstrdup(const char *s) +{ + int len = strlen(s) + 1; + char *d = xmalloc(len); + + memcpy(d, s, len); + + return d; +} + +#include +#include +#include "../lib/list_sort.c" #include "../lib/recursive_action.c" #include "../include/envfs.h" #include "../crypto/crc32.c" diff --git a/scripts/include/linux/list_sort.h b/scripts/include/linux/list_sort.h new file mode 100644 index 0000000..be889c9 --- /dev/null +++ b/scripts/include/linux/list_sort.h @@ -0,0 +1 @@ +#include <../../include/linux/list_sort.h>