diff --git a/Makefile b/Makefile index 1299d9e..832469a 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ SRC = \ cat.c \ chmod.c \ chown.c \ + cmp.c \ date.c \ dirname.c \ echo.c \ diff --git a/cmp.1 b/cmp.1 new file mode 100644 index 0000000..700805a --- /dev/null +++ b/cmp.1 @@ -0,0 +1,25 @@ +.TH CMP 1 sbase\-VERSION +.SH NAME +CMP \- compare two files +.SH SYNOPSIS +.B cmp +.RB [ \-ls ] +.RI file1 +.RI file2 +.SH DESCRIPTION +.B cmp +compares two files byte by byte. If the files differ, cmp prints the byte and +line number at which the difference occurred. +.P +The status code is 0 if the files are identical, and 1 if not. If an error +occurred the status code is 2. +.SH OPTIONS +.TP +.B \-l +prints the byte number, and the differing bytes (in octal), for each difference. +.TP +.B \-s +prints nothing, only returns status. +.SH SEE ALSO +.IR comm (1), +.IR diff (1) diff --git a/cmp.c b/cmp.c new file mode 100644 index 0000000..ee54752 --- /dev/null +++ b/cmp.c @@ -0,0 +1,63 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include "util.h" + +static bool lflag = false; +static bool sflag = false; + +int +main(int argc, char *argv[]) +{ + bool same = true; + char c; + int b[2], i; + long line = 1, n = 1; + FILE *fp[2]; + + if((c = getopt(argc, argv, "ls")) != -1) + switch(c) { + case 'l': + lflag = true; + break; + case 's': + sflag = true; + break; + default: + exit(2); + } + if(optind != argc-2) { + eprintf("usage: %s [-ls] file1 file2\n", argv[0]); + exit(2); + } + for(i = 0; i < 2; i++) + if(!(fp[i] = fopen(argv[optind+i], "r"))) { + eprintf("fopen %s:", argv[optind+i]); + exit(2); + } + for(n = 1; ((b[0] = getc(fp[0])) != EOF) | ((b[1] = getc(fp[1])) != EOF); n++) { + if(b[0] == '\n') + line++; + if(b[0] == b[1]) + continue; + for(i = 0; i < 2; i++) + if(b[i] == EOF) { + fprintf(stderr, "cmp: EOF on %s\n", argv[optind+i]); + return 1; + } + if(!lflag) { + if(!sflag) + printf("%s %s differ: char %ld, line %ld\n", + argv[optind], argv[optind+1], n, line); + return 1; + } + else { + printf("%4ld %3o %3o\n", n, b[0], b[1]); + same = false; + } + } + return same ? 0 : 1; +}