>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

Reply via email to