Date: Thu, 18 Oct 2001 03:51:56 +0400 (MSD) From: "Andrew L. Neporada" <andr@dgap.mipt.ru> To: freebsd-bugs@freebsd.org Cc: freebsd-gnuts-submit@freebsd.org Subject: Re: bin/24732: cmp can not compare files lager 2GB but smaller 4GB Message-ID: <20011018034848.H24599-100000@nas.dgap.mipt.ru>
next in thread | raw e-mail | index | archive | help
Patch below 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 ;-(
diff -ruN cmp.orig/extern.h cmp/extern.h
--- cmp.orig/extern.h Sun Jul 2 13:28:37 2000
+++ cmp/extern.h Wed Oct 17 06:51:49 2001
@@ -40,9 +40,11 @@
#define DIFF_EXIT 1
#define ERR_EXIT 2 /* error exit code */
-void c_regular __P((int, char *, off_t, off_t, int, char *, off_t, off_t));
-void c_special __P((int, char *, off_t, int, char *, off_t));
-void diffmsg __P((char *, char *, off_t, off_t));
-void eofmsg __P((char *));
+void c_regular __P((int, char *, off_t, off_t, int, char *, off_t,
+ off_t));
+void c_special __P((int, char *, off_t, int, char *, off_t));
+void diffmsg __P((char *, char *, off_t, off_t));
+void eofmsg __P((char *));
+u_char * remmap __P((u_char *, int, off_t));
extern int lflag, sflag, xflag;
diff -ruN cmp.orig/regular.c cmp/regular.c
--- cmp.orig/regular.c Sun Jul 2 15:14:42 2000
+++ cmp/regular.c Thu Oct 18 02:48:34 2001
@@ -52,6 +52,7 @@
#include "extern.h"
#define ROUNDPAGE(i) ((i) & ~pagemask)
+#define MMAP_CHUNK (8*1024*1024)
void
c_regular(fd1, file1, skip1, len1, fd2, file2, skip2, len2)
@@ -59,10 +60,10 @@
char *file1, *file2;
off_t skip1, len1, skip2, len2;
{
- u_char ch, *p1, *p2;
+ u_char ch, *p1, *p2, *m1, *m2;
off_t byte, length, line;
int dfound;
- off_t pagemask, off1, off2;
+ off_t pagemask, off1, off2, st1, st2;
size_t pagesize;
if (skip1 > len1)
@@ -81,27 +82,25 @@
off2 = ROUNDPAGE(skip2);
length = MIN(len1, len2);
- if (length > SIZE_T_MAX)
- return (c_special(fd1, file1, skip1, fd2, file2, skip2));
+ dfound = 0;
+ st1 = skip1 - off1;
+ st2 = skip2 - off2;
- 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);
+ m1 = remmap(NULL, fd1, off1);
+ m2 = remmap(NULL, fd2, off2);
+ if (!m1 || !m2)
+ 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) {
+ p1 = m1 + st1;
+ p2 = m2 + st2;
+
+ for (byte = line = 1; length--; ++byte) {
if ((ch = *p1) != *p2) {
if (xflag) {
dfound = 1;
- (void)printf("%08qx %02x %02x\n", byte - 1, ch, *p2);
+ (void)printf("%08qx %02x %02x\n", byte - 1,
+ ch, *p2);
} else if (lflag) {
dfound = 1;
(void)printf("%6qd %3o %3o\n", byte, ch, *p2);
@@ -111,10 +110,41 @@
}
if (ch == '\n')
++line;
+ if (++st1 == MMAP_CHUNK) {
+ st1 = 0;
+ off1 += MMAP_CHUNK;
+ p1 = m1 = remmap(m1, fd1, off1);
+ } else
+ ++p1;
+ if (++st2 == MMAP_CHUNK) {
+ st2 = 0;
+ off2 += MMAP_CHUNK;
+ p2 = m2 = remmap(m2, fd2, off2);
+ } else
+ ++p2;
+ if (!m1 || !m2)
+ c_special(fd1, file1, skip1, fd2, file2, skip2);
+ /* NOTREACHED */
}
if (len1 != len2)
eofmsg (len1 > len2 ? file2 : file1);
if (dfound)
exit(DIFF_EXIT);
+}
+
+u_char *
+remmap(mem, fd, offset)
+ u_char *mem;
+ int fd;
+ off_t offset;
+{
+ if (mem)
+ munmap(mem, MMAP_CHUNK);
+ mem = (u_char *)mmap(NULL, MMAP_CHUNK, PROT_READ, MAP_SHARED, fd,
+ offset);
+ if (mem == (u_char *)MAP_FAILED)
+ return (NULL);
+ madvise(mem, MMAP_CHUNK, MADV_SEQUENTIAL);
+ return (mem);
}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011018034848.H24599-100000>
