>diff -urpN bbox bbox.patched >a.patch
I left off the N, because there were no new files
and as the non-reference directory was configured
and buildable there was a lot of noise. The patch
follows. Sadly, it is against the 1.11 we use now,
but I don't think there's been any activity in the
md5 utility source, so it ought to just apply there.
And the rest (usage, config.in) is trivial.
-- Jim
diff -urp busybox.ref/coreutils/Config.in busybox/coreutils/Config.in
--- busybox.ref/coreutils/Config.in 2008-10-15 11:01:16.000000000
-0700
+++ busybox/coreutils/Config.in 2009-06-19 17:09:40.000000000 -0700
@@ -808,4 +808,13 @@ config FEATURE_MD5_SHA1_SUM_CHECK
-s and -w are useful options when verifying checksums.
+config FEATURE_MD5_SHA1_SUM_PARALLEL
+ bool "Allow paralleled jobs when checking (-c)"
+ default n
+ depends on FEATURE_MD5_SHA1_SUM_CHECK
+ help
+ Saying yes here will enable the -jN option that allows
+ for N file checks to be in parallel. (Useful for
+ multi-CPU/core machines.) Requires fork(2) be usable.
+
endmenu
diff -urp busybox.ref/coreutils/md5_sha1_sum.c
busybox/coreutils/md5_sha1_sum.c
--- busybox.ref/coreutils/md5_sha1_sum.c 2008-10-15
11:01:16.000000000 -0700
+++ busybox/coreutils/md5_sha1_sum.c 2009-06-19 16:35:05.000000000
-0700
@@ -13,6 +13,7 @@ typedef enum { HASH_SHA1, HASH_MD5 } has
#define FLAG_SILENT 1
#define FLAG_CHECK 2
#define FLAG_WARN 4
+#define FLAG_JOBS 8
/* This might be useful elsewhere */
static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
@@ -80,18 +81,26 @@ int md5_sha1_sum_main(int argc ATTRIBUTE
int return_value = EXIT_SUCCESS;
uint8_t *hash_value;
unsigned flags;
+ int jobs = 0, jobcount = 0, child, status;
+ char *jargp;
+ static const char waitfailed[] = {"wait(2) failed"};
hash_algo_t hash_algo = ENABLE_MD5SUM
? (ENABLE_SHA1SUM ? (applet_name[0] == 'm' ? HASH_MD5 :
HASH_SHA1) : HASH_MD5)
: HASH_SHA1;
if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
- flags = getopt32(argv, "scw");
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_PARALLEL)
+ flags = getopt32(argv, "scwj:", &jargp);
+ else
+ flags = getopt32(argv, "scw");
else optind = 1;
argv += optind;
//argc -= optind;
if (!*argv)
*--argv = (char*)"-";
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_PARALLEL && (flags & FLAG_JOBS))
+ jobs = atoi(jargp);
if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK))
{
if (flags & FLAG_SILENT) {
bb_error_msg_and_die
@@ -129,31 +138,69 @@ int md5_sha1_sum_main(int argc ATTRIBUTE
bb_error_msg("invalid format");
}
count_failed++;
- return_value = EXIT_FAILURE;
free(line);
continue;
}
*filename_ptr = '\0';
filename_ptr += 2;
- hash_value = hash_file(filename_ptr, hash_algo);
-
- if (hash_value && (strcmp((char*)hash_value,
line) == 0)) {
- if (!(flags & FLAG_SILENT))
- printf("%s: OK\n",
filename_ptr);
- } else {
- if (!(flags & FLAG_SILENT))
- printf("%s: FAILED\n",
filename_ptr);
- count_failed++;
- return_value = EXIT_FAILURE;
- }
- /* possible free(NULL) */
- free(hash_value);
+ if (ENABLE_FEATURE_MD5_SHA1_SUM_PARALLEL &&
jobs) {
+ while (jobcount >= jobs) { // Slots all full?
+ if ((child = wait(&status)) > 0) { // Reap
one.
+ jobcount--;
+ if (!WIFEXITED(status) ||
WEXITSTATUS(status))
+ count_failed++;
+ } else {
+ bb_error_msg_and_die(waitfailed);
+ }
+ }
+
+ if (!(child = fork())) { // Child
+ hash_value = hash_file(filename_ptr,
hash_algo);
+ if (hash_value &&
(strcmp((char*)hash_value, line) == 0)) {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: OK\n", filename_ptr);
+ } else {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: FAILED\n",
filename_ptr);
+ exit(1);
+ }
+ exit(0);
+ } else if (child > 0) { // Parent
+ jobcount++;
+ } else { // Fork failed.
+ bb_error_msg_and_die("fork(2) failed");
+ }
+ } else { // No parallel jobs, use old inline
code.
+ hash_value = hash_file(filename_ptr,
hash_algo);
+ if (hash_value && (strcmp((char*)hash_value,
line) == 0)) {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: OK\n",
filename_ptr);
+ } else {
+ if (!(flags & FLAG_SILENT))
+ printf("%s: FAILED\n",
filename_ptr);
+ count_failed++;
+ }
+ /* possible free(NULL) */
+ free(hash_value);
+ }
free(line);
}
- if (count_failed && !(flags & FLAG_SILENT)) {
+ while (jobcount) { // Wait for stragglers and reap them.
+ if ((child = wait(&status)) > 0) {
+ jobcount--;
+ if (!WIFEXITED(status) || WEXITSTATUS(status))
+ count_failed++;
+ } else {
+ bb_error_msg_and_die(waitfailed);
+ }
+ }
+ if (count_failed) {
+ return_value = EXIT_FAILURE;
+ if (!(flags & FLAG_SILENT)) {
bb_error_msg("WARNING: %d of %d computed
checksums did NOT match",
count_failed,
count_total);
+ }
}
/*
if (fclose_if_not_stdin(pre_computed_stream) == EOF) {
diff -urp busybox.ref/include/usage.h busybox/include/usage.h
--- busybox.ref/include/usage.h 2008-11-06 13:50:25.000000000 -0800
+++ busybox/include/usage.h 2009-06-19 16:56:09.000000000 -0700
@@ -2369,6 +2369,8 @@
"\n -p Use prefix to speed translations" \
"\n -V Verify file context on disk matches defaults" \
+#define md5_sha1_sum_parallel \
+ USE_FEATURE_MD5_SHA1_SUM_PARALLEL("\n -j<N> N parallel jobs
when checking")
#define md5sum_trivial_usage \
"[OPTION] [FILEs...]" \
USE_FEATURE_MD5_SHA1_SUM_CHECK("\n or: md5sum [OPTION] -c
[FILE]")
@@ -2377,6 +2379,7 @@
USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \
"\nOptions:" \
"\n -c Check MD5 sums against given list" \
+ md5_sha1_sum_parallel \
"\n -s Don't output anything, status code shows
success" \
"\n -w Warn about improperly formatted MD5 checksum
lines") \
@@ -3544,6 +3547,7 @@
USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \
"\nOptions:" \
"\n -c Check SHA1 sums against given list" \
+ md5_sha1_sum_parallel \
"\n -s Don't output anything, status code shows
success" \
"\n -w Warn about improperly formatted SHA1 checksum
lines" \
)
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox