Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Mar 2002 11:33:59 +0200
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Dag-Erling Smorgrav <des@FreeBSD.org>
Cc:        Bruce Evans <bde@FreeBSD.org>, current@FreeBSD.org
Subject:   Re: cvs commit: src/usr.bin/xinstall xinstall.c
Message-ID:  <20020320093359.GB2503@sunbay.com>
In-Reply-To: <200203182326.g2INQDb71549@freefall.freebsd.org>
References:  <200203182326.g2INQDb71549@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		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 majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020320093359.GB2503>