cmp.c

Go to the documentation of this file.
00001 /* cmp - compare two files              Author: Kees J. Bot.  */
00002 
00003 #include <sys/types.h>
00004 #include <fcntl.h>
00005 #include <stdlib.h>
00006 #include <unistd.h>
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <errno.h>
00010 
00011 _PROTOTYPE(void fatal, (char *label));
00012 _PROTOTYPE(int cmp, (int fd1, int fd2));
00013 _PROTOTYPE(void Usage, (void));
00014 _PROTOTYPE(int main, (int argc, char **argv));
00015 
00016 #define BLOCK   4096
00017 
00018 static int loud = 0, silent = 0;
00019 static char *name1, *name2;
00020 
00021 int main(argc, argv)
00022 int argc;
00023 char **argv;
00024 {
00025   int fd1, fd2;
00026 
00027   /* Process the '-l' or '-s' option. */
00028   while (argc > 1 && argv[1][0] == '-' && argv[1][1] != 0) {
00029         if (argv[1][2] != 0) Usage();
00030 
00031         switch (argv[1][1]) {
00032         case '-':
00033                 /* '--': no-op option. */
00034                 break;
00035         case 'l':
00036                 loud = 1;
00037                 break;
00038         case 's':
00039                 silent = 1;
00040                 break;
00041         default:
00042                 Usage();
00043         }
00044         argc--;
00045         argv++;
00046   }
00047   if (argc != 3) Usage();
00048 
00049   /* Open the first file, '-' means standard input. */
00050   if (argv[1][0] == '-' && argv[1][1] == 0) {
00051         name1 = "stdin";
00052         fd1 = 0;
00053   } else {
00054         name1 = argv[1];
00055         if ((fd1 = open(name1, 0)) < 0) fatal(name1);
00056   }
00057 
00058   /* Second file likewise. */
00059   if (argv[2][0] == '-' && argv[2][1] == 0) {
00060         name2 = "stdin";
00061         fd2 = 0;
00062   } else {
00063         name2 = argv[2];
00064         if ((fd2 = open(name2, 0)) < 0) fatal(name2);
00065   }
00066 
00067   exit(cmp(fd1, fd2));
00068 }
00069 
00070 int cmp(fd1, fd2)
00071 int fd1, fd2;
00072 {
00073   static char buf1[BLOCK], buf2[BLOCK];
00074   int n1 = 0, n2 = 0, i1 = 0, i2 = 0, c1, c2;
00075   off_t pos = 0, line = 1;
00076   int eof = 0, differ = 0;
00077 
00078   for (;;) {
00079         if (i1 == n1) {
00080                 pos += n1;
00081 
00082                 if ((n1 = read(fd1, buf1, sizeof(buf1))) <= 0) {
00083                         if (n1 < 0) fatal(name1);
00084                         eof |= 1;
00085                 }
00086                 i1 = 0;
00087         }
00088         if (i2 == n2) {
00089                 if ((n2 = read(fd2, buf2, sizeof(buf2))) <= 0) {
00090                         if (n2 < 0) fatal(name2);
00091                         eof |= 2;
00092                 }
00093                 i2 = 0;
00094         }
00095         if (eof != 0) break;
00096 
00097         c1 = buf1[i1++];
00098         c2 = buf2[i2++];
00099 
00100         if (c1 != c2) {
00101                 if (!loud) {
00102                         if (!silent) {
00103                                 printf("%s %s differ: char %ld, line %ld\n",
00104                                        name1, name2, pos + i1, line);
00105                         }
00106                         return(1);
00107                 }
00108                 printf("%10ld %3o %3o\n", pos + i1, c1 & 0xFF, c2 & 0xFF);
00109                 differ = 1;
00110         }
00111         if (c1 == '\n') line++;
00112   }
00113   if (eof == (1 | 2)) return(differ);
00114   if (!silent) fprintf(stderr, "cmp: EOF on %s\n", eof == 1 ? name1 : name2);
00115   return(1);
00116 }
00117 
00118 void fatal(label)
00119 char *label;
00120 {
00121   if (!silent) fprintf(stderr, "cmp: %s: %s\n", label, strerror(errno));
00122   exit(2);
00123 }
00124 
00125 void Usage()
00126 {
00127   fprintf(stderr, "Usage: cmp [-l | -s] file1 file2\n");
00128   exit(2);
00129 }

Generated on Fri Apr 14 22:57:04 2006 for minix by  doxygen 1.4.6