* Copyright (c) 1987 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1987, 1990 Regents of the University of California.\n\
static char sccsid
[] = "@(#)cmp.c 5.3 (Berkeley) 6/1/90";
int all
, fd1
, fd2
, silent
;
u_char buf1
[MAXBSIZE
], buf2
[MAXBSIZE
];
while ((ch
= getopt(argc
, argv
, "-ls")) != EOF
)
case 'l': /* print all differences */
case 's': /* silent run */
case '-': /* must be after any flags */
if (argc
< 2 || argc
> 4)
"cmp: only one of -l and -s may be specified.\n");
if (strcmp(file1
= argv
[0], "-") == 0)
else if ((fd1
= open(file1
, O_RDONLY
, 0)) < 0)
if (strcmp(file2
= argv
[1], "-") == 0)
else if ((fd2
= open(file2
, O_RDONLY
, 0)) < 0)
"cmp: standard input may only be specified once.\n");
/* handle skip arguments */
skip(otoi(argv
[2]), fd1
, file1
);
skip(otoi(argv
[3]), fd2
, file2
);
* skip first part of file
register int rlen
, nread
;
for (; dist
; dist
-= rlen
) {
rlen
= MIN(dist
, sizeof(buf1
));
if ((nread
= read(fd
, buf1
, rlen
)) != rlen
) {
register u_char
*p1
, *p2
;
register int cnt
, len1
, len2
;
register long byte
, line
;
for (byte
= 0, line
= 1; ; ) {
switch (len1
= read(fd1
, buf1
, MAXBSIZE
)) {
* read of file 1 just failed, find out
* if there's anything left in file 2
switch (read(fd2
, buf2
, 1)) {
exit(dfound
? EXITDIFF
: EXITNODIFF
);
* file1 might be stdio, which means that a read of less than
* MAXBSIZE might not mean an EOF. So, read whatever we read
if ((len2
= read(fd2
, buf2
, len1
)) == -1)
if (bcmp(buf1
, buf2
, len2
)) {
for (p1
= buf1
, p2
= buf2
, cnt
= len2
; cnt
--;
} else for (p1
= buf1
, p2
= buf2
; ; ++p1
, ++p2
) {
printf("%s %s differ: char %ld, line %ld\n", file1
, file2
, byte
, line
);
* here's the real performance problem, we've got to
* count the stupid lines, which means that -l is a
* *much* faster version, i.e., unless you really
* *want* to know the line number, run -s or -l.
for (p1
= buf1
, cnt
= len2
; cnt
--; )
* couldn't read as much from file2 as from file1; checked
* here because there might be a difference before we got
* to this point, which would have precedence.
* octal/decimal string to u_long
base
= (*s
== '0') ? 8 : 10;
for (val
= 0; isdigit(*s
); ++s
)
val
= val
* base
+ *s
- '0';
* print I/O error message and die
(void) fprintf(stderr
, "cmp: %s: %s\n",
filename
, strerror(errno
));
* print end-of-file message and exit indicating the files were different
/* 32V put this message on stdout, S5 does it on stderr. */
/* POSIX.2 currently does it on stdout-- Hooray! */
(void) printf("cmp: EOF on %s\n", filename
);
fputs("usage: cmp [-ls] file1 file2 [skip1] [skip2]\n", stderr
);