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 ChangesPath
> 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 - 1.48
+++ xinstall.c 20 Mar 2002 09:26:11 -
@@ -74,12 +74,11 @@ static const char sccsid[] = "From: @(#)
#define MAP_FAILED ((void *)-1)/* from */
#endif
-#define MAX_CMP_SIZE (16 * 1024 * 1024)
-
#defineDIRECTORY 0x01/* Tell install it's a directory. */
#defineSETFLAGS0x02/* Tell install to set flags. */
#defineNOCHANGEBITS(UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
#defineBACKUP_SUFFIX ".old"
+#defineMAX_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)
+