summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h1
-rw-r--r--lib/list_sort.c3
-rw-r--r--lib/recursive_action.c71
-rw-r--r--scripts/bareboxenv.c15
-rw-r--r--scripts/include/linux/list_sort.h1
5 files changed, 81 insertions, 10 deletions
diff --git a/include/libbb.h b/include/libbb.h
index a362bd32d8..1f6afaa27a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -17,6 +17,7 @@ enum {
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 b7e74f260d..84c6f6465b 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -1,7 +1,6 @@
#ifndef __BAREBOX__
#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#define EXPORT_SYMBOL(x)
#else
#include <common.h>
#include <malloc.h>
diff --git a/lib/recursive_action.c b/lib/recursive_action.c
index 345d3db0ce..9505c86284 100644
--- a/lib/recursive_action.c
+++ b/lib/recursive_action.c
@@ -13,9 +13,28 @@
#include <linux/stat.h>
#include <malloc.h>
#include <libbb.h>
+#include <xfuncs.h>
+
+/*
+ * 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 <linux/list.h>
+#include <linux/list_sort.h>
+
+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 @@ static int true_action(const char *fileName, struct stat *statbuf,
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 recursive_action(const char *fileName,
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 @@ int recursive_action(const char *fileName,
/* 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);
+ }
+ }
+
+ 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);
}
- free(nextFile);
}
closedir(dir);
if ((flags & ACTION_DEPTHFIRST) &&
diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c
index 249e65b251..e95bdeaa5e 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 @@ enum {
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 @@ static char *concat_subpath_file(const char *path, const char *f)
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 <linux/list.h>
+#include <linux/list_sort.h>
+#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 0000000000..be889c9ae5
--- /dev/null
+++ b/scripts/include/linux/list_sort.h
@@ -0,0 +1 @@
+#include <../../include/linux/list_sort.h>