On Mon, Mar 18, 2002 at 03:26:13PM -0800, Dag-Erling Smorgrav wrote:
> des         2002/03/18 15:26:13 PST
> 
>   Modified files:
>     usr.bin/xinstall     xinstall.c 
>   Log:
>   Bump the cutoff mark for comparing files from 8 MB to 16 MB.
>   
>   Revision  Changes    Path
>   1.48      +3 -1      src/usr.bin/xinstall/xinstall.c
> 
OK, I think it's finally the time to borrow mmap(2) comparison in
chunks from OpenBSD (better viewed as -w diff):

%%%
Index: xinstall.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/xinstall/xinstall.c,v
retrieving revision 1.48
diff -u -p -r1.48 xinstall.c
--- xinstall.c  18 Mar 2002 23:26:13 -0000      1.48
+++ xinstall.c  20 Mar 2002 09:26:11 -0000
@@ -74,12 +74,11 @@ static const char sccsid[] = "From: @(#)
 #define MAP_FAILED ((void *)-1)        /* from <sys/mman.h> */
 #endif
 
-#define MAX_CMP_SIZE   (16 * 1024 * 1024)
-
 #define        DIRECTORY       0x01            /* Tell install it's a directory. */
 #define        SETFLAGS        0x02            /* Tell install to set flags. */
 #define        NOCHANGEBITS    (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
 #define        BACKUP_SUFFIX   ".old"
+#define        MAX_CMP_SIZE    (16 * 1024 * 1024)
 
 struct passwd *pp;
 struct group *gp;
@@ -523,6 +522,8 @@ compare(int from_fd, const char *from_na
        int to_fd, const char *to_name __unused, size_t to_len)
 {
        char *p, *q;
+       size_t len, remainder;
+       off_t from_off, to_off;
        int rv;
        int done_compare;
 
@@ -530,48 +531,60 @@ compare(int from_fd, const char *from_na
        if (from_len != to_len)
                return 1;
 
-       if (from_len <= MAX_CMP_SIZE) {
-               done_compare = 0;
-               if (trymmap(from_fd) && trymmap(to_fd)) {
-                       p = mmap(NULL, from_len, PROT_READ, MAP_SHARED, from_fd, 
(off_t)0);
+       done_compare = 0;
+       if (trymmap(from_fd) && trymmap(to_fd)) {
+               /*
+                * Compare two files being careful not to mmap
+                * more than 8M at a time.
+                */
+               from_off = to_off = (off_t)0;
+               remainder = from_len;
+               while (!rv && remainder > 0) {
+                       len = MIN(remainder, 8 * 1024 * 1024);
+
+                       p = mmap(NULL, len, PROT_READ, MAP_SHARED, from_fd, from_off);
                        if (p == (char *)MAP_FAILED)
                                goto out;
-                       q = mmap(NULL, from_len, PROT_READ, MAP_SHARED, to_fd, 
(off_t)0);
+                       q = mmap(NULL, len, PROT_READ, MAP_SHARED, to_fd, to_off);
                        if (q == (char *)MAP_FAILED) {
-                               munmap(p, from_len);
+                               munmap(p, len);
                                goto out;
                        }
 
-                       rv = memcmp(p, q, from_len);
-                       munmap(p, from_len);
-                       munmap(q, from_len);
-                       done_compare = 1;
-               }
-       out:
-               if (!done_compare) {
-                       char buf1[MAXBSIZE];
-                       char buf2[MAXBSIZE];
-                       int n1, n2;
-
-                       rv = 0;
-                       lseek(from_fd, 0, SEEK_SET);
-                       lseek(to_fd, 0, SEEK_SET);
-                       while (rv == 0) {
-                               n1 = read(from_fd, buf1, sizeof(buf1));
-                               if (n1 == 0)
-                                       break;          /* EOF */
-                               else if (n1 > 0) {
-                                       n2 = read(to_fd, buf2, n1);
-                                       if (n2 == n1)
-                                               rv = memcmp(buf1, buf2, n1);
-                                       else
-                                               rv = 1; /* out of sync */
-                               } else
-                                       rv = 1;         /* read failure */
-                       }
-                       lseek(from_fd, 0, SEEK_SET);
-                       lseek(to_fd, 0, SEEK_SET);
+                       rv = memcmp(p, q, len);
+                       munmap(p, len);
+                       munmap(q, len);
+
+                       from_off += len;
+                       to_off += len;
+                       remainder -= len;
+               }
+               done_compare = 1;
+       }
+out:
+       if (!done_compare && from_len <= MAX_CMP_SIZE) {
+               char buf1[MAXBSIZE];
+               char buf2[MAXBSIZE];
+               int n1, n2;
+
+               rv = 0;
+               lseek(from_fd, 0, SEEK_SET);
+               lseek(to_fd, 0, SEEK_SET);
+               while (rv == 0) {
+                       n1 = read(from_fd, buf1, sizeof(buf1));
+                       if (n1 == 0)
+                               break;          /* EOF */
+                       else if (n1 > 0) {
+                               n2 = read(to_fd, buf2, n1);
+                               if (n2 == n1)
+                                       rv = memcmp(buf1, buf2, n1);
+                               else
+                                       rv = 1; /* out of sync */
+                       } else
+                               rv = 1;         /* read failure */
                }
+               lseek(from_fd, 0, SEEK_SET);
+               lseek(to_fd, 0, SEEK_SET);
        } else
                rv = 1; /* don't bother in this case */
 
%%%
 

Cheers,
-- 
Ruslan Ermilov          Sysadmin and DBA,
[EMAIL PROTECTED]           Sunbay Software AG,
[EMAIL PROTECTED]          FreeBSD committer,
+380.652.512.251        Simferopol, Ukraine

http://www.FreeBSD.org  The Power To Serve
http://www.oracle.com   Enabling The Information Age

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to