From nobody@FreeBSD.org  Tue Jan 30 02:26:14 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 6561337B6B9
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Jan 2001 02:26:13 -0800 (PST)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.1/8.11.1) id f0UAQDc99382;
	Tue, 30 Jan 2001 02:26:13 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200101301026.f0UAQDc99382@freefall.freebsd.org>
Date: Tue, 30 Jan 2001 02:26:13 -0800 (PST)
From: kazarov@izmiran.rssi.ru
To: freebsd-gnats-submit@FreeBSD.org
Subject: cmp can not compare files lager 2GB but smaller 4GB
X-Send-Pr-Version: www-1.0

>Number:         24732
>Category:       bin
>Synopsis:       cmp can not compare files lager 2GB but smaller 4GB
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    dwmalone
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jan 30 02:30:01 PST 2001
>Closed-Date:    Wed Nov 21 02:48:08 PST 2001
>Last-Modified:  Wed Nov 21 02:48:38 PST 2001
>Originator:     Dmitry Kazarov
>Release:        FreeBSD-4.2-STABLE
>Organization:
IZMIRAN
>Environment:
>Description:
in /usr/src/usr.bin/cmp/regular.c, line 84, length of files is compared with SIZE_T_MAX which is equal to 0xFFFFFFFF (4GB-1). 
But man mmap says:
BUGS
     len is limited to 2GB.  Mmapping slightly more than 2GB doesn't work, but
     it is possible to map a window of size (filesize % 2GB) for file sizes of
     slightly less than 2G, 4GB, 6GB and 8GB.
And tests shows that cmp cannot mmap two files of silze greate about 1213MB (on my system).
So constant should be decreased to 1GB
>How-To-Repeat:
user$ dd if=/dev/zero of=tmp seek=2048k bs=1k count=1
1+0 records in
1+0 records out
1024 bytes transferred in 0.000258 secs (3969471 bytes/sec)
user$ ln tmp tmp.l
user$ cmp tmp tmp.l
cmp: tmp: Invalid argument
>Fix:
*** regular.c.orig Tue Jan 30 12:36:35 2001
--- regular.c Tue Jan 30 12:37:15 2001
*************** c_regular(fd1, file1, skip1, len1, fd2, 
*** 81,87 ****
  off2 = ROUNDPAGE(skip2);
  
  length = MIN(len1, len2);
! if (length > SIZE_T_MAX)
  return (c_special(fd1, file1, skip1, fd2, file2, skip2));
  
  if ((p1 = (u_char *)mmap(NULL, (size_t)len1 + skip1 % pagesize,
--- 81,87 ----
  off2 = ROUNDPAGE(skip2);
  
  length = MIN(len1, len2);
! if (length > ( 1024*1024*1024 ) ) /* 1GB */
  return (c_special(fd1, file1, skip1, fd2, file2, skip2));
  
  if ((p1 = (u_char *)mmap(NULL, (size_t)len1 + skip1 % pagesize,


>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: kazarov@izmiran.rssi.ru
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB
Date: Wed, 31 Jan 2001 01:02:21 +1100 (EST)

 On Tue, 30 Jan 2001 kazarov@izmiran.rssi.ru wrote:
 
 > And tests shows that cmp cannot mmap two files of silze greate about 1213MB (on my system).
 
 This seems about right for i386's.  Two files have to be mapped below the
 kernel start address of 3G, so their size is limited to 1.5GB.  Big files,
 at least, have to be mapped after libraries, so there size is further
 limited.
 
 > So constant should be decreased to 1GB
 
 This is rather machine-dependent, and probably too large to be optimal
 anyway.
 
 To fix the machine-dependencies, I think cmp should just try to mmap
 both files and fall back to c_special() if this fails.  Note that
 the current check against SIZE_T_MAX is just to prevent overflow,
 but it is broken in several ways:
 (1) It SIZE_T_MAX with MIN(len1, len2), but it needs to compare with
     MAX(len1, len2) to prevent overflow when the lengths are cast to
     size_t.
 (2) It needs comapare SIZE_T_MAX with
     MAX(len1 + skip1 % pagesize, len2 + skip2 % pagesize) to prevent
     overflow when the adjusted lengths are passed to mmap().
 The casts in (1) are bogus anyway.  They are unnecessary if a prototype
 for mmap() is in scope and are in the wrong place otherwise (the whole
 adjusted lengths should be cast).
 
 Bruce
 
 

From: "Dmitry Kazarov" <kazarov@izmiran.rssi.ru>
To: "Bruce Evans" <bde@zeta.org.au>
Cc: <freebsd-gnats-submit@FreeBSD.org>
Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB
Date: Tue, 30 Jan 2001 17:59:23 +0300

 > > So constant should be decreased to 1GB
 >
 > This is rather machine-dependent, and probably too large to be optimal
 > anyway.
 >
 > To fix the machine-dependencies, I think cmp should just try to mmap
 > both files and fall back to c_special() if this fails.  Note that
 > the current check against SIZE_T_MAX is just to prevent overflow,
 > but it is broken in several ways:
 > (1) It SIZE_T_MAX with MIN(len1, len2), but it needs to compare with
 >     MAX(len1, len2) to prevent overflow when the lengths are cast to
 >     size_t.
 > (2) It needs comapare SIZE_T_MAX with
 >     MAX(len1 + skip1 % pagesize, len2 + skip2 % pagesize) to prevent
 >     overflow when the adjusted lengths are passed to mmap().
 > The casts in (1) are bogus anyway.  They are unnecessary if a prototype
 > for mmap() is in scope and are in the wrong place otherwise (the whole
 > adjusted lengths should be cast).
 
 Hi, Bruce,
 Sorry, I do not understand why compare MAX(...) to SIZE_T_MAX.
 IMHO, mmap maps the file into process memory so both files together should
 fit into process accessible address space which is less then SIZE_T_MAX (my
 expirements with cmp showed that is about 2430MB, on Solaris 2.4 it was 2GB
 only).
 So it's nessesary to compare (len1+skip1%pagesize + len2+skip2%pagesize) to
 2430MB (for my system).
 Cause, reverting to c_special on mmap failure could be a better way but,
 IMHO, the best solution would be proposal of Poul-Henning Kamp
 <phk@FreeBSD.org> ( http://www.freebsd.org/cgi/query-pr.cgi?pr=18589 ):
 "Add a loop around the mmap/compare operation which operates on some
 moderate amount of data each iteration."
 
 Sincerely Yours
 Dmitry
 
 
 

From: Bruce Evans <bde@zeta.org.au>
To: Dmitry Kazarov <kazarov@izmiran.rssi.ru>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB
Date: Wed, 31 Jan 2001 04:24:15 +1100 (EST)

 On Tue, 30 Jan 2001, Dmitry Kazarov wrote:
 
 > Sorry, I do not understand why compare MAX(...) to SIZE_T_MAX.
 > IMHO, mmap maps the file into process memory so both files together should
 > fit into process accessible address space which is less then SIZE_T_MAX (my
 > expirements with cmp showed that is about 2430MB, on Solaris 2.4 it was 2GB
 > only).
 
 mmap()'s `len' arg has type size_t, so lengths larger than SIZE_T_MAX
 can't be passed to mmap() for it to check (and fail on).
 
 > So it's nessesary to compare (len1+skip1%pagesize + len2+skip2%pagesize) to
 > 2430MB (for my system).
 
 mmap() will check this if the full lengths can be passed to it.  Since
 their are 2 mmap()s, there is a machine-dependent amount of space
 between them.  PAGE_SIZE is probably sufficient, but you have to look
 at the implementation to tell.  Your 2430MB must have some slop for this.
 
 > Cause, reverting to c_special on mmap failure could be a better way but,
 > IMHO, the best solution would be proposal of Poul-Henning Kamp
 > <phk@FreeBSD.org> ( http://www.freebsd.org/cgi/query-pr.cgi?pr=18589 ):
 > "Add a loop around the mmap/compare operation which operates on some
 > moderate amount of data each iteration."
 
 I agree.  cp uses 8MB for the moderate amount.  So does xinstall for
 its file comparison function.  xinstall also falls back to read()
 when mmap() fails, and has a -M flag to prevent use of mmap().
 
 Bruce
 
 
Responsible-Changed-From-To: freebsd-bugs->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Tue Jun 5 12:27:03 PDT 2001 
Responsible-Changed-Why:  
I'll have a look at this one since I had a look at size limits in tail. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=24732 

From: "Andrew L. Neporada" <andr@dgap.mipt.ru>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB
Date: Thu, 18 Oct 2001 03:33:15 +0400 (MSD)

   This message is in MIME format.  The first part should be readable text,
   while the remaining parts are likely unreadable without MIME-aware tools.
   Send mail to mime@docserver.cac.washington.edu for more info.
 
 --0-1101869596-1003361595=:24272
 Content-Type: TEXT/PLAIN; charset=US-ASCII
 
 Attached  patch solves (I hope) this problem. Basic idea of the patch --
 to mmap() some moderate amount (8MB) of data rather then entire file
 (this idea belongs to phk@FreeBSD.org -- see bin/18589).
 
 				Andrew.
 
 P.S. Patch was made against RELENG_4 sources
 (extern.h v 1.1.1.1.14.1 and regular.c v 1.7.2.2). Unfortunately
 anoncvs.freebsd.org is down ;-(
 
 
 
 --0-1101869596-1003361595=:24272
 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="cmp.diff"
 Content-Transfer-Encoding: BASE64
 Content-ID: <20011018033315.B24272@nas.dgap.mipt.ru>
 Content-Description: cmp.diff
 Content-Disposition: attachment; filename="cmp.diff"
 
 ZGlmZiAtcnVOIGNtcC5vcmlnL2V4dGVybi5oIGNtcC9leHRlcm4uaA0KLS0t
 IGNtcC5vcmlnL2V4dGVybi5oCVN1biBKdWwgIDIgMTM6Mjg6MzcgMjAwMA0K
 KysrIGNtcC9leHRlcm4uaAlXZWQgT2N0IDE3IDA2OjUxOjQ5IDIwMDENCkBA
 IC00MCw5ICs0MCwxMSBAQA0KICNkZWZpbmUgRElGRl9FWElUCTENCiAjZGVm
 aW5lIEVSUl9FWElUCTIJLyogZXJyb3IgZXhpdCBjb2RlICovDQogDQotdm9p
 ZAljX3JlZ3VsYXIgX19QKChpbnQsIGNoYXIgKiwgb2ZmX3QsIG9mZl90LCBp
 bnQsIGNoYXIgKiwgb2ZmX3QsIG9mZl90KSk7DQotdm9pZAljX3NwZWNpYWwg
 X19QKChpbnQsIGNoYXIgKiwgb2ZmX3QsIGludCwgY2hhciAqLCBvZmZfdCkp
 Ow0KLXZvaWQJZGlmZm1zZyBfX1AoKGNoYXIgKiwgY2hhciAqLCBvZmZfdCwg
 b2ZmX3QpKTsNCi12b2lkCWVvZm1zZyBfX1AoKGNoYXIgKikpOw0KK3ZvaWQJ
 CWNfcmVndWxhciBfX1AoKGludCwgY2hhciAqLCBvZmZfdCwgb2ZmX3QsIGlu
 dCwgY2hhciAqLCBvZmZfdCwNCisJCQkgICAgICAgb2ZmX3QpKTsNCit2b2lk
 CQljX3NwZWNpYWwgX19QKChpbnQsIGNoYXIgKiwgb2ZmX3QsIGludCwgY2hh
 ciAqLCBvZmZfdCkpOw0KK3ZvaWQJCWRpZmZtc2cgX19QKChjaGFyICosIGNo
 YXIgKiwgb2ZmX3QsIG9mZl90KSk7DQordm9pZAkJZW9mbXNnIF9fUCgoY2hh
 ciAqKSk7DQordV9jaGFyICoJcmVtbWFwIF9fUCgodV9jaGFyICosIGludCwg
 b2ZmX3QpKTsNCiANCiBleHRlcm4gaW50IGxmbGFnLCBzZmxhZywgeGZsYWc7
 DQpkaWZmIC1ydU4gY21wLm9yaWcvcmVndWxhci5jIGNtcC9yZWd1bGFyLmMN
 Ci0tLSBjbXAub3JpZy9yZWd1bGFyLmMJU3VuIEp1bCAgMiAxNToxNDo0MiAy
 MDAwDQorKysgY21wL3JlZ3VsYXIuYwlUaHUgT2N0IDE4IDAyOjQ4OjM0IDIw
 MDENCkBAIC01Miw2ICs1Miw3IEBADQogI2luY2x1ZGUgImV4dGVybi5oIg0K
 IA0KICNkZWZpbmUgUk9VTkRQQUdFKGkpICgoaSkgJiB+cGFnZW1hc2spDQor
 I2RlZmluZQlNTUFQX0NIVU5LCSg4KjEwMjQqMTAyNCkNCiANCiB2b2lkDQog
 Y19yZWd1bGFyKGZkMSwgZmlsZTEsIHNraXAxLCBsZW4xLCBmZDIsIGZpbGUy
 LCBza2lwMiwgbGVuMikNCkBAIC01OSwxMCArNjAsMTAgQEANCiAJY2hhciAq
 ZmlsZTEsICpmaWxlMjsNCiAJb2ZmX3Qgc2tpcDEsIGxlbjEsIHNraXAyLCBs
 ZW4yOw0KIHsNCi0JdV9jaGFyIGNoLCAqcDEsICpwMjsNCisJdV9jaGFyIGNo
 LCAqcDEsICpwMiwgKm0xLCAqbTI7DQogCW9mZl90IGJ5dGUsIGxlbmd0aCwg
 bGluZTsNCiAJaW50IGRmb3VuZDsNCi0Jb2ZmX3QgcGFnZW1hc2ssIG9mZjEs
 IG9mZjI7DQorCW9mZl90IHBhZ2VtYXNrLCBvZmYxLCBvZmYyLCBzdDEsIHN0
 MjsNCiAJc2l6ZV90IHBhZ2VzaXplOw0KIA0KIAlpZiAoc2tpcDEgPiBsZW4x
 KQ0KQEAgLTgxLDI3ICs4MiwyNSBAQA0KIAlvZmYyID0gUk9VTkRQQUdFKHNr
 aXAyKTsNCiANCiAJbGVuZ3RoID0gTUlOKGxlbjEsIGxlbjIpOw0KLQlpZiAo
 bGVuZ3RoID4gU0laRV9UX01BWCkNCi0JCXJldHVybiAoY19zcGVjaWFsKGZk
 MSwgZmlsZTEsIHNraXAxLCBmZDIsIGZpbGUyLCBza2lwMikpOw0KKwlkZm91
 bmQgPSAwOw0KKwlzdDEgPSBza2lwMSAtIG9mZjE7DQorCXN0MiA9IHNraXAy
 IC0gb2ZmMjsNCiANCi0JaWYgKChwMSA9ICh1X2NoYXIgKiltbWFwKE5VTEws
 IChzaXplX3QpbGVuMSArIHNraXAxICUgcGFnZXNpemUsDQotCSAgICBQUk9U
 X1JFQUQsIE1BUF9TSEFSRUQsIGZkMSwgb2ZmMSkpID09ICh1X2NoYXIgKilN
 QVBfRkFJTEVEKQ0KLQkJZXJyKEVSUl9FWElULCAiJXMiLCBmaWxlMSk7DQot
 DQotCW1hZHZpc2UocDEsIGxlbjEgKyBza2lwMSAlIHBhZ2VzaXplLCBNQURW
 X1NFUVVFTlRJQUwpOw0KLQlpZiAoKHAyID0gKHVfY2hhciAqKW1tYXAoTlVM
 TCwgKHNpemVfdClsZW4yICsgc2tpcDIgJSBwYWdlc2l6ZSwNCi0JICAgIFBS
 T1RfUkVBRCwgTUFQX1NIQVJFRCwgZmQyLCBvZmYyKSkgPT0gKHVfY2hhciAq
 KU1BUF9GQUlMRUQpDQotCQllcnIoRVJSX0VYSVQsICIlcyIsIGZpbGUyKTsN
 Ci0JbWFkdmlzZShwMiwgbGVuMiArIHNraXAyICUgcGFnZXNpemUsIE1BRFZf
 U0VRVUVOVElBTCk7DQorCW0xID0gcmVtbWFwKE5VTEwsIGZkMSwgb2ZmMSk7
 DQorCW0yID0gcmVtbWFwKE5VTEwsIGZkMiwgb2ZmMik7DQorCWlmICghbTEg
 fHwgIW0yKQ0KKwkJY19zcGVjaWFsKGZkMSwgZmlsZTEsIHNraXAxLCBmZDIs
 IGZpbGUyLCBza2lwMik7DQorCQkvKiBOT1RSRUFDSEVEICovDQogDQotCWRm
 b3VuZCA9IDA7DQotCXAxICs9IHNraXAxIC0gb2ZmMTsNCi0JcDIgKz0gc2tp
 cDIgLSBvZmYyOw0KLQlmb3IgKGJ5dGUgPSBsaW5lID0gMTsgbGVuZ3RoLS07
 ICsrcDEsICsrcDIsICsrYnl0ZSkgew0KKwlwMSA9IG0xICsgc3QxOw0KKwlw
 MiA9IG0yICsgc3QyOw0KKw0KKwlmb3IgKGJ5dGUgPSBsaW5lID0gMTsgbGVu
 Z3RoLS07ICsrYnl0ZSkgew0KIAkJaWYgKChjaCA9ICpwMSkgIT0gKnAyKSB7
 DQogCQkJaWYgKHhmbGFnKSB7DQogCQkJCWRmb3VuZCA9IDE7DQotCQkJCSh2
 b2lkKXByaW50ZigiJTA4cXggJTAyeCAlMDJ4XG4iLCBieXRlIC0gMSwgY2gs
 ICpwMik7DQorCQkJCSh2b2lkKXByaW50ZigiJTA4cXggJTAyeCAlMDJ4XG4i
 LCBieXRlIC0gMSwNCisJCQkJCSAgICAgY2gsICpwMik7DQogCQkJfSBlbHNl
 IGlmIChsZmxhZykgew0KIAkJCQlkZm91bmQgPSAxOw0KIAkJCQkodm9pZClw
 cmludGYoIiU2cWQgJTNvICUzb1xuIiwgYnl0ZSwgY2gsICpwMik7DQpAQCAt
 MTExLDEwICsxMTAsNDEgQEANCiAJCX0NCiAJCWlmIChjaCA9PSAnXG4nKQ0K
 IAkJCSsrbGluZTsNCisJCWlmICgrK3N0MSA9PSBNTUFQX0NIVU5LKSB7DQor
 CQkJc3QxID0gMDsNCisJCQlvZmYxICs9IE1NQVBfQ0hVTks7DQorCQkJcDEg
 PSBtMSA9IHJlbW1hcChtMSwgZmQxLCBvZmYxKTsNCisJCX0gZWxzZQ0KKwkJ
 CSsrcDE7DQorCQlpZiAoKytzdDIgPT0gTU1BUF9DSFVOSykgew0KKwkJCXN0
 MiA9IDA7DQorCQkJb2ZmMiArPSBNTUFQX0NIVU5LOw0KKwkJCXAyID0gbTIg
 PSByZW1tYXAobTIsIGZkMiwgb2ZmMik7DQorCQl9IGVsc2UNCisJCQkrK3Ay
 Ow0KKwkJaWYgKCFtMSB8fCAhbTIpDQorCQkJY19zcGVjaWFsKGZkMSwgZmls
 ZTEsIHNraXAxLCBmZDIsIGZpbGUyLCBza2lwMik7DQorCQkJLyogTk9UUkVB
 Q0hFRCAqLw0KIAl9DQogDQogCWlmIChsZW4xICE9IGxlbjIpDQogCQllb2Zt
 c2cgKGxlbjEgPiBsZW4yID8gZmlsZTIgOiBmaWxlMSk7DQogCWlmIChkZm91
 bmQpDQogCQlleGl0KERJRkZfRVhJVCk7DQorfQ0KKw0KK3VfY2hhciAqDQor
 cmVtbWFwKG1lbSwgZmQsIG9mZnNldCkNCisJdV9jaGFyCSptZW07DQorCWlu
 dAlmZDsNCisJb2ZmX3QJb2Zmc2V0Ow0KK3sNCisJaWYgKG1lbSkNCisJCW11
 bm1hcChtZW0sIE1NQVBfQ0hVTkspOw0KKwltZW0gPSAodV9jaGFyICopbW1h
 cChOVUxMLCBNTUFQX0NIVU5LLCBQUk9UX1JFQUQsIE1BUF9TSEFSRUQsIGZk
 LA0KKwkJCSAgICAgb2Zmc2V0KTsNCisJaWYgKG1lbSA9PSAodV9jaGFyICop
 TUFQX0ZBSUxFRCkNCisJCXJldHVybiAoTlVMTCk7DQorCW1hZHZpc2UobWVt
 LCBNTUFQX0NIVU5LLCBNQURWX1NFUVVFTlRJQUwpOw0KKwlyZXR1cm4gKG1l
 bSk7DQogfQ0K
 --0-1101869596-1003361595=:24272--

From: David Malone <dwmalone@maths.tcd.ie>
To: freebsd-gnats-submit@FreeBSD.org
Cc: kazarov@izmiran.rssi.ru, andr@dgap.mipt.ru, bde@zeta.org.au
Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB
Date: Mon, 29 Oct 2001 16:49:43 +0000

 I've produced a version of Andrew's patch which just mmaps the
 things in 8MB chunks. For reasons I don't understand, this actually
 seems to make c_regular faster (uses about half as much user time).
 
 I'll commit this later in the week, unless anyone has any objections.
 
 	David.
 
 
 Index: regular.c
 ===================================================================
 RCS file: /cvs/FreeBSD-CVS/src/usr.bin/cmp/regular.c,v
 retrieving revision 1.10
 diff -u -r1.10 regular.c
 --- regular.c	20 Jun 2000 20:28:40 -0000	1.10
 +++ regular.c	29 Oct 2001 16:27:07 -0000
 @@ -51,6 +51,9 @@
  
  #include "extern.h"
  
 +static u_char *remmap __P((u_char *, int, off_t));
 +#define MMAP_CHUNK (8*1024*1024)
 +
  #define ROUNDPAGE(i) ((i) & ~pagemask)
  
  void
 @@ -59,7 +62,7 @@
  	char *file1, *file2;
  	off_t skip1, len1, skip2, len2;
  {
 -	u_char ch, *p1, *p2;
 +	u_char ch, *p1, *p2, *m1, *m2, *e1, *e2;
  	off_t byte, length, line;
  	int dfound;
  	off_t pagemask, off1, off2;
 @@ -81,23 +84,24 @@
  	off2 = ROUNDPAGE(skip2);
  
  	length = MIN(len1, len2);
 -	if (length > SIZE_T_MAX)
 -		return (c_special(fd1, file1, skip1, fd2, file2, skip2));
  
 -	if ((p1 = (u_char *)mmap(NULL, (size_t)len1 + skip1 % pagesize,
 -	    PROT_READ, MAP_SHARED, fd1, off1)) == (u_char *)MAP_FAILED)
 -		err(ERR_EXIT, "%s", file1);
 -
 -	madvise(p1, len1 + skip1 % pagesize, MADV_SEQUENTIAL);
 -	if ((p2 = (u_char *)mmap(NULL, (size_t)len2 + skip2 % pagesize,
 -	    PROT_READ, MAP_SHARED, fd2, off2)) == (u_char *)MAP_FAILED)
 -		err(ERR_EXIT, "%s", file2);
 -	madvise(p2, len2 + skip2 % pagesize, MADV_SEQUENTIAL);
 +	if ((m1 = remmap(NULL, fd1, off1)) == NULL)
 +		c_special(fd1, file1, skip1, fd2, file2, skip2);
 +		/* NOTREACHED */
 +
 +	if ((m2 = remmap(NULL, fd2, off2)) == NULL) {
 +		munmap(m1, MMAP_CHUNK);
 +		c_special(fd1, file1, skip1, fd2, file2, skip2);
 +		/* NOTREACHED */
 +	}
  
  	dfound = 0;
 -	p1 += skip1 - off1;
 -	p2 += skip2 - off2;
 -	for (byte = line = 1; length--; ++p1, ++p2, ++byte) {
 +	e1 = m1 + MMAP_CHUNK;
 +	e2 = m2 + MMAP_CHUNK;
 +	p1 = m1 + (skip1 - off1);
 +	p2 = m2 + (skip2 - off2);
 +
 +	for (byte = line = 1; length--; ++byte) {
  		if ((ch = *p1) != *p2) {
  			if (xflag) {
  				dfound = 1;
 @@ -111,10 +115,41 @@
  		}
  		if (ch == '\n')
  			++line;
 +		if (++p1 == e1) {
 +			off1 += MMAP_CHUNK;
 +			if ((p1 = m1 = remmap(m1, fd1, off1)) == NULL) {
 +				munmap(m2, MMAP_CHUNK);
 +				err(ERR_EXIT, "remmap %s", file1);
 +			}
 +			e1 = m1 + MMAP_CHUNK;
 +		}
 +		if (++p2 == e2) {
 +			off2 += MMAP_CHUNK;
 +			if ((p2 = m2 = remmap(m2, fd2, off2)) == NULL) {
 +				munmap(m1, MMAP_CHUNK);
 +				err(ERR_EXIT, "remmap %s", file2);
 +			}
 +			e2 = m2 + MMAP_CHUNK;
 +		}
  	}
  
  	if (len1 != len2)
  		eofmsg (len1 > len2 ? file2 : file1);
  	if (dfound)
  		exit(DIFF_EXIT);
 +}
 +
 +static u_char *
 +remmap(mem, fd, offset)
 +	u_char  *mem;
 +	int     fd;
 +	off_t   offset;
 +{
 +	if (mem != NULL)
 +		munmap(mem, MMAP_CHUNK);
 +	mem = mmap(NULL, MMAP_CHUNK, PROT_READ, MAP_SHARED, fd, offset);
 +	if (mem == MAP_FAILED)
 +		return (NULL);
 +	madvise(mem, MMAP_CHUNK, MADV_SEQUENTIAL);
 +	return (mem);
  }
State-Changed-From-To: open->closed 
State-Changed-By: dwmalone 
State-Changed-When: Wed Nov 21 02:48:08 PST 2001 
State-Changed-Why:  
Fix committed to both -current and -stable. Thanks! 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=24732 
>Unformatted:
