Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/cmp/special.c
Show All 30 Lines | |||||
#ifndef lint | #ifndef lint | ||||
static char sccsid[] = "@(#)special.c 8.3 (Berkeley) 4/2/94"; | static char sccsid[] = "@(#)special.c 8.3 (Berkeley) 4/2/94"; | ||||
#endif | #endif | ||||
#endif | #endif | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <unistd.h> | |||||
#include "extern.h" | #include "extern.h" | ||||
static int | |||||
skip_helper(int fd, const char *file, off_t skip) { | |||||
char buf[MAXBSIZE]; | |||||
int r; | |||||
size_t n; | |||||
while (skip) { | |||||
n = MIN(skip, (off_t)(sizeof buf)); | |||||
r = read(fd, buf, n); | |||||
if (r <= 0) { | |||||
if (r < 0) | |||||
err(ERR_EXIT, "%s", file); | |||||
return 1; | |||||
} | |||||
skip -= n; | |||||
} | |||||
return 0; | |||||
} | |||||
static int | |||||
read_helper(int fd, const char *file, | |||||
u_char *buf, size_t size, | |||||
u_char **cur, u_char **lim) | |||||
{ | |||||
int r; | |||||
*cur = *lim = buf; | |||||
r = read(fd, *cur, size); | |||||
if (r <= 0) { | |||||
if (r < 0) | |||||
err(ERR_EXIT, "%s", file); | |||||
return 1; | |||||
} | |||||
*lim += r; | |||||
return 0; | |||||
} | |||||
void | void | ||||
c_special(int fd1, const char *file1, off_t skip1, | c_special(int fd1, const char *file1, off_t skip1, | ||||
int fd2, const char *file2, off_t skip2) | int fd2, const char *file2, off_t skip2) | ||||
{ | { | ||||
int ch1, ch2; | |||||
off_t byte, line; | off_t byte, line; | ||||
FILE *fp1, *fp2; | int dfound, tryfast; | ||||
int dfound; | u_char b1[MAXBSIZE], b2[MAXBSIZE]; | ||||
u_char *p1, *p2, *e1, *e2; | |||||
size_t len; | |||||
int eof1, eof2; | |||||
if ((fp1 = fdopen(fd1, "r")) == NULL) | |||||
err(ERR_EXIT, "%s", file1); | |||||
if ((fp2 = fdopen(fd2, "r")) == NULL) | |||||
err(ERR_EXIT, "%s", file2); | |||||
dfound = 0; | dfound = 0; | ||||
while (skip1--) | |||||
if (getc(fp1) == EOF) | if ((eof1 = skip_helper(fd1, file1, skip1))) | ||||
goto eof; | goto eof; | ||||
while (skip2--) | if ((eof2 = skip_helper(fd2, file2, skip2))) | ||||
if (getc(fp2) == EOF) | |||||
goto eof; | goto eof; | ||||
for (byte = line = 1;; ++byte) { | p1 = e1 = b1; | ||||
ch1 = getc(fp1); | p2 = e2 = b2; | ||||
ch2 = getc(fp2); | byte = line = 1; | ||||
if (ch1 == EOF || ch2 == EOF) | tryfast = 1; | ||||
for (;;) { | |||||
if (p1 == e1) | |||||
eof1 = read_helper(fd1, file1, b1, sizeof b1, &p1, &e1); | |||||
if (p2 == e2) | |||||
eof2 = read_helper(fd2, file2, b2, sizeof b2, &p2, &e2); | |||||
if (eof1 || eof2) | |||||
break; | break; | ||||
if (ch1 != ch2) { | len = MIN(e1 - p1, e2 - p2); | ||||
if (xflag) { | if (c_chunk(file1, file2, p1, p2, len, &byte, &line, &tryfast)) | ||||
dfound = 1; | dfound = 1; | ||||
(void)printf("%08llx %02x %02x\n", | p1 += len; | ||||
(long long)byte - 1, ch1, ch2); | p2 += len; | ||||
} else 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)) | eof: if (eof1) { | ||||
err(ERR_EXIT, "%s", file1); | if (!eof2) | ||||
if (ferror(fp2)) | |||||
err(ERR_EXIT, "%s", file2); | |||||
if (feof(fp1)) { | |||||
if (!feof(fp2)) | |||||
eofmsg(file1); | eofmsg(file1); | ||||
} else | } else | ||||
if (feof(fp2)) | if (eof2) | ||||
eofmsg(file2); | eofmsg(file2); | ||||
fclose(fp2); | |||||
fclose(fp1); | |||||
if (dfound) | if (dfound) | ||||
exit(DIFF_EXIT); | exit(DIFF_EXIT); | ||||
} | } |