Import NetBSD cmp

Change-Id: I0e7f6c69742db475ddba6a9159f167a53d151169
This commit is contained in:
David van Moolenbroek 2015-09-20 11:18:45 +00:00
parent 93d36fc9d8
commit e7ca52fbf9
13 changed files with 636 additions and 178 deletions

View file

@ -4,7 +4,7 @@
SUBDIR= add_route arp at backup btrace \ SUBDIR= add_route arp at backup btrace \
cawf cdprobe \ cawf cdprobe \
ci cleantmp cmp co \ ci cleantmp co \
compress crc cron crontab \ compress crc cron crontab \
decomp16 DESCRIBE devmand devsize dhcpd \ decomp16 DESCRIBE devmand devsize dhcpd \
dhrystone diff diskctl \ dhrystone diff diskctl \

View file

@ -1,4 +0,0 @@
PROG= cmp
MAN=
.include <bsd.prog.mk>

View file

@ -1,129 +0,0 @@
/* cmp - compare two files Author: Kees J. Bot. */
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
void fatal(char *label);
int cmp(int fd1, int fd2);
void Usage(void);
int main(int argc, char **argv);
#define BLOCK 4096
static int loud = 0, silent = 0;
static char *name1, *name2;
int main(argc, argv)
int argc;
char **argv;
{
int fd1, fd2;
/* Process the '-l' or '-s' option. */
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) {
if (argv[1][2] != 0) Usage();
switch (argv[1][1]) {
case '-':
/* '--': no-op option. */
break;
case 'l':
loud = 1;
break;
case 's':
silent = 1;
break;
default:
Usage();
}
argc--;
argv++;
}
if (argc != 3) Usage();
/* Open the first file, '-' means standard input. */
if (argv[1][0] == '-' && argv[1][1] == 0) {
name1 = "stdin";
fd1 = 0;
} else {
name1 = argv[1];
if ((fd1 = open(name1, 0)) < 0) fatal(name1);
}
/* Second file likewise. */
if (argv[2][0] == '-' && argv[2][1] == 0) {
name2 = "stdin";
fd2 = 0;
} else {
name2 = argv[2];
if ((fd2 = open(name2, 0)) < 0) fatal(name2);
}
exit(cmp(fd1, fd2));
}
int cmp(fd1, fd2)
int fd1, fd2;
{
static char buf1[BLOCK], buf2[BLOCK];
int n1 = 0, n2 = 0, i1 = 0, i2 = 0, c1, c2;
off_t pos = 0, line = 1;
int eof = 0, differ = 0;
for (;;) {
if (i1 == n1) {
pos += n1;
if ((n1 = read(fd1, buf1, sizeof(buf1))) <= 0) {
if (n1 < 0) fatal(name1);
eof |= 1;
}
i1 = 0;
}
if (i2 == n2) {
if ((n2 = read(fd2, buf2, sizeof(buf2))) <= 0) {
if (n2 < 0) fatal(name2);
eof |= 2;
}
i2 = 0;
}
if (eof != 0) break;
c1 = buf1[i1++];
c2 = buf2[i2++];
if (c1 != c2) {
if (!loud) {
if (!silent) {
printf("%s %s differ: char %d, line %d\n",
name1, name2, pos + i1, line);
}
return(1);
}
printf("%10d %3o %3o\n", pos + i1, c1 & 0xFF, c2 & 0xFF);
differ = 1;
}
if (c1 == '\n') line++;
}
if (eof == (1 | 2)) return(differ);
if (!silent) fprintf(stderr, "cmp: EOF on %s\n", eof == 1 ? name1 : name2);
return(1);
}
void fatal(label)
char *label;
{
if (!silent) fprintf(stderr, "cmp: %s: %s\n", label, strerror(errno));
exit(2);
}
void Usage()
{
fprintf(stderr, "Usage: cmp [-l | -s] file1 file2\n");
exit(2);
}

View file

@ -1,6 +1,6 @@
MAN= at.1 \ MAN= at.1 \
bsfilt.1 cawf.1 chgrp.1 \ bsfilt.1 cawf.1 chgrp.1 \
cmp.1 compress.1 \ compress.1 \
crc.1 crontab.1 \ crc.1 crontab.1 \
dhrystone.1 dosdir.1 dosread.1 doswrite.1 \ dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
eject.1 \ eject.1 \

View file

@ -1,42 +0,0 @@
.TH CMP 1
.SH NAME
cmp \- compare two files
.SH SYNOPSIS
\fBcmp\fR [\fB\-ls\fR] \fIfile1 file2\fR
.br
.de FL
.TP
\\fB\\$1\\fR
\\$2
..
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.SH OPTIONS
.TP 5
.B \-l
# Loud mode. Print bytes that differ (in octal)
.TP 5
.B \-s
# Silent mode. Print nothing, just return exit status
.SH EXAMPLES
.TP 20
.B cmp file1 file2
# Tell whether the files are the same
.TP 20
.B cmp \-l file1 file2
# Print all corresponding bytes that differ
.SH DESCRIPTION
.PP
Two files are compared.
If they are identical, exit status 0 is returned.
If they differ, exit status 1 is returned.
If the files cannot be opened, exit status 2 is returned.
If one of the file arguments is \-, then
\fIstdin\fR is compared to
the other file.
.SH "SEE ALSO"
.BR comm (1),
.BR diff (1).

View file

@ -6,7 +6,7 @@
SUBDIR= asa \ SUBDIR= asa \
banner basename \ banner basename \
bzip2 bzip2recover cal calendar \ bzip2 bzip2recover cal calendar \
checknr chpass cksum col colcrt colrm \ checknr chpass cksum cmp col colcrt colrm \
column comm csplit ctags cut \ column comm csplit ctags cut \
deroff dirname du \ deroff dirname du \
env expand \ env expand \

7
usr.bin/cmp/Makefile Normal file
View file

@ -0,0 +1,7 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.4 1997/01/09 20:18:26 tls Exp $
PROG= cmp
SRCS= cmp.c misc.c regular.c special.c
.include <bsd.prog.mk>

105
usr.bin/cmp/cmp.1 Normal file
View file

@ -0,0 +1,105 @@
.\" $NetBSD: cmp.1,v 1.9 2003/08/07 11:13:21 agc Exp $
.\"
.\" Copyright (c) 1987, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 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. 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
.\" SUCH DAMAGE.
.\"
.\" @(#)cmp.1 8.1 (Berkeley) 6/6/93
.\"
.Dd June 6, 1993
.Dt CMP 1
.Os
.Sh NAME
.Nm cmp
.Nd compare two files
.Sh SYNOPSIS
.Nm
.Op Fl l | Fl s
.Ar file1 file2
.Op Ar skip1 Op Ar skip2
.Sh DESCRIPTION
The cmp utility compares two files of any type and writes the results
to the standard output.
By default,
.Nm
is silent if the files are the same; if they differ, the byte
and line number at which the first difference occurred is reported.
.Pp
Bytes and lines are numbered beginning with one.
.Pp
The following options are available:
.Bl -tag -width flag
.It Fl l
Print the byte number (decimal) and the differing
byte values (octal) for each difference.
.It Fl s
Print nothing for differing files; return exit
status only.
.El
.Pp
The optional arguments
.Ar skip1
and
.Ar skip2
are the byte offsets from the beginning of
.Ar file1
and
.Ar file2 ,
respectively, where the comparison will begin.
The offset is decimal by default, but may be expressed as an hexadecimal
or octal value by preceding it with a leading ``0x'' or ``0''.
.Pp
The
.Nm
utility exits with one of the following values:
.Bl -tag -width 4n
.It 0
The files are identical.
.It 1
The files are different; this includes the case
where one file is identical to the first part of
the other.
In the latter case, if the
.Fl s
option has not been specified,
.Nm
writes to standard output that EOF was reached in the shorter
file (before any differences were found).
.It \*[Gt]1
An error occurred.
.El
.Sh SEE ALSO
.Xr diff 1 ,
.Xr diff3 1
.Sh STANDARDS
The
.Nm
utility is expected to be
.St -p1003.2
compatible.

164
usr.bin/cmp/cmp.c Normal file
View file

@ -0,0 +1,164 @@
/* $NetBSD: cmp.c,v 1.18 2011/08/29 14:14:11 joerg Exp $ */
/*
* Copyright (c) 1987, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. 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
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1987, 1990, 1993, 1994\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)cmp.c 8.3 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: cmp.c,v 1.18 2011/08/29 14:14:11 joerg Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include "extern.h"
int lflag, sflag;
__dead static void usage(void);
int
main(int argc, char *argv[])
{
struct stat sb1, sb2;
off_t skip1 = 0, skip2 = 0;
int ch, fd1, fd2, special;
const char *file1, *file2;
setlocale(LC_ALL, "");
while ((ch = getopt(argc, argv, "ls")) != -1)
switch (ch) {
case 'l': /* print all differences */
lflag = 1;
break;
case 's': /* silent run */
sflag = 1;
break;
case '?':
default:
usage();
}
argv += optind;
argc -= optind;
if (lflag && sflag)
errx(ERR_EXIT, "only one of -l and -s may be specified");
if (argc < 2 || argc > 4)
usage();
/* Backward compatibility -- handle "-" meaning stdin. */
special = 0;
if (strcmp(file1 = argv[0], "-") == 0) {
special = 1;
fd1 = 0;
file1 = "stdin";
}
else if ((fd1 = open(file1, O_RDONLY, 0)) < 0) {
if (!sflag)
warn("%s", file1);
exit(ERR_EXIT);
}
if (strcmp(file2 = argv[1], "-") == 0) {
if (special)
errx(ERR_EXIT,
"standard input may only be specified once");
special = 1;
fd2 = 0;
file2 = "stdin";
}
else if ((fd2 = open(file2, O_RDONLY, 0)) < 0) {
if (!sflag)
warn("%s", file2);
exit(ERR_EXIT);
}
if (argc > 2) {
char *ep;
errno = 0;
skip1 = strtoq(argv[2], &ep, 0);
if (errno || ep == argv[2])
usage();
if (argc == 4) {
skip2 = strtoq(argv[3], &ep, 0);
if (errno || ep == argv[3])
usage();
}
}
if (!special) {
if (fstat(fd1, &sb1))
err(ERR_EXIT, "%s", file1);
if (!S_ISREG(sb1.st_mode))
special = 1;
else {
if (fstat(fd2, &sb2))
err(ERR_EXIT, "%s", file2);
if (!S_ISREG(sb2.st_mode))
special = 1;
}
}
if (special)
c_special(fd1, file1, skip1, fd2, file2, skip2);
else
c_regular(fd1, file1, skip1, sb1.st_size,
fd2, file2, skip2, sb2.st_size);
exit(0);
}
static void
usage(void)
{
(void)fprintf(stderr,
"usage: cmp [-l | -s] file1 file2 [skip1 [skip2]]\n");
exit(ERR_EXIT);
}

44
usr.bin/cmp/extern.h Normal file
View file

@ -0,0 +1,44 @@
/* $NetBSD: extern.h,v 1.9 2011/08/29 14:14:11 joerg Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. 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
* SUCH DAMAGE.
*
* @(#)extern.h 8.3 (Berkeley) 4/2/94
*/
#define OK_EXIT 0
#define DIFF_EXIT 1
#define ERR_EXIT 2 /* error exit code */
void c_regular(int, const char *, off_t, off_t, int, const char *, off_t, off_t);
void c_special(int, const char *, off_t, int, const char *, off_t);
__dead void diffmsg(const char *, const char *, off_t, off_t);
__dead void eofmsg(const char *, off_t, off_t);
__dead void errmsg(const char *, off_t, off_t);
extern int lflag, sflag;

84
usr.bin/cmp/misc.c Normal file
View file

@ -0,0 +1,84 @@
/* $NetBSD: misc.c,v 1.12 2009/04/11 12:16:12 lukem Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. 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
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: misc.c,v 1.12 2009/04/11 12:16:12 lukem Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include "extern.h"
void
errmsg(const char *file, off_t byte, off_t line)
{
if (lflag)
err(ERR_EXIT, "%s: char %lld, line %lld", file,
(long long)byte, (long long)line);
else
err(ERR_EXIT, "%s", file);
}
void
eofmsg(const char *file, off_t byte, off_t line)
{
if (!sflag) {
if (!lflag)
warnx("EOF on %s", file);
else {
if (line > 0)
warnx("EOF on %s: char %lld, line %lld",
file, (long long)byte, (long long)line);
else
warnx("EOF on %s: char %lld",
file, (long long)byte);
}
}
exit(DIFF_EXIT);
}
void
diffmsg(const char *file1, const char *file2, off_t byte, off_t line)
{
if (!sflag)
(void)printf("%s %s differ: char %lld, line %lld\n",
file1, file2, (long long)byte, (long long)line);
exit(DIFF_EXIT);
}

118
usr.bin/cmp/regular.c Normal file
View file

@ -0,0 +1,118 @@
/* $NetBSD: regular.c,v 1.24 2013/11/20 17:19:14 kleink Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. 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
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)regular.c 8.3 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: regular.c,v 1.24 2013/11/20 17:19:14 kleink Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <err.h>
#include <limits.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "extern.h"
void
c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
int fd2, const char *file2, off_t skip2, off_t len2)
{
u_char ch, *p1, *p2;
off_t byte, length, line;
int dfound;
size_t blk_sz, blk_cnt;
if (sflag && len1 != len2)
exit(1);
if (skip1 > len1)
eofmsg(file1, len1 + 1, 0);
len1 -= skip1;
if (skip2 > len2)
eofmsg(file2, len2 + 1, 0);
len2 -= skip2;
byte = line = 1;
dfound = 0;
length = MIN(len1, len2);
for (blk_sz = 1024 * 1024; length != 0; length -= blk_sz) {
if ((uintmax_t)blk_sz > (uintmax_t)length)
blk_sz = length;
p1 = mmap(NULL, blk_sz, PROT_READ, MAP_FILE|MAP_SHARED,
fd1, skip1);
if (p1 == MAP_FAILED)
goto mmap_failed;
p2 = mmap(NULL, blk_sz, PROT_READ, MAP_FILE|MAP_SHARED,
fd2, skip2);
if (p2 == MAP_FAILED) {
munmap(p1, blk_sz);
goto mmap_failed;
}
blk_cnt = blk_sz;
for (; blk_cnt--; ++p1, ++p2, ++byte) {
if ((ch = *p1) != *p2) {
if (!lflag) {
diffmsg(file1, file2, byte, line);
/* NOTREACHED */
}
dfound = 1;
(void)printf("%6lld %3o %3o\n",
(long long)byte, ch, *p2);
}
if (ch == '\n')
++line;
}
munmap(p1 - blk_sz, blk_sz);
munmap(p2 - blk_sz, blk_sz);
skip1 += blk_sz;
skip2 += blk_sz;
}
if (len1 != len2)
eofmsg(len1 > len2 ? file2 : file1, byte, line);
if (dfound)
exit(DIFF_EXIT);
return;
mmap_failed:
c_special(fd1, file1, skip1, fd2, file2, skip2);
}

111
usr.bin/cmp/special.c Normal file
View file

@ -0,0 +1,111 @@
/* $NetBSD: special.c,v 1.14 2011/11/28 10:10:10 wiz Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. 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
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)special.c 8.3 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: special.c,v 1.14 2011/11/28 10:10:10 wiz Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include "extern.h"
void
c_special(int fd1, const char *file1, off_t skip1, int fd2, const char *file2, off_t skip2)
{
int ch1, ch2;
off_t byte, line;
FILE *fp1, *fp2;
int dfound;
dfound = 0;
if ((fp1 = fdopen(fd1, "r")) == NULL)
err(ERR_EXIT, "%s", file1);
if ((fp2 = fdopen(fd2, "r")) == NULL)
err(ERR_EXIT, "%s", file2);
for (byte = line = 1; skip1--; byte++) {
ch1 = getc(fp1);
if (ch1 == EOF)
goto eof;
if (ch1 == '\n')
line++;
}
for (byte = line = 1; skip2--; byte++) {
ch2 = getc(fp2);
if (ch2 == EOF)
goto eof;
if (ch2 == '\n')
line++;
}
dfound = 0;
for (byte = line = 1;; ++byte) {
ch1 = getc(fp1);
ch2 = getc(fp2);
if (ch1 == EOF || ch2 == EOF)
break;
if (ch1 != ch2) {
if (lflag) {
dfound = 1;
(void)printf("%6lld %3o %3o\n", (long long)byte,
ch1, ch2);
} else
diffmsg(file1, file2, byte, line);
/* NOTREACHED */
}
if (ch1 == '\n')
++line;
}
eof:
if (ferror(fp1))
errmsg(file1, byte, line);
if (ferror(fp2))
errmsg(file2, byte, line);
if (feof(fp1)) {
if (!feof(fp2))
eofmsg(file1, byte, line);
} else
if (feof(fp2))
eofmsg(file2, byte, line);
(void)fclose(fp1);
(void)fclose(fp2);
if (dfound)
exit(DIFF_EXIT);
}