blob: 2dae1138d06f9c5dda5bb7e50f646de68e58d8a8 [file] [log] [blame]
Rob Landley7aa651a2012-11-13 17:14:08 -06001/* cmp.c - Compare two files.
Timothy Elliottae079d22012-02-06 01:28:40 -08002 *
3 * Copyright 2012 Timothy Elliott <tle@holymonkey.com>
4 *
Rob Landleyf91b7c82012-08-25 18:08:51 -05005 * See http://opengroup.org/onlinepubs/9699919799/utilities/cmp.html
Timothy Elliottae079d22012-02-06 01:28:40 -08006
7USE_CMP(NEWTOY(cmp, "<2>2ls", TOYFLAG_USR|TOYFLAG_BIN))
8
9config CMP
Rob Landley7aa651a2012-11-13 17:14:08 -060010 bool "cmp"
11 default y
12 help
13 usage: cmp [-l] [-s] FILE1 FILE2
Timothy Elliottae079d22012-02-06 01:28:40 -080014
Rob Landley7aa651a2012-11-13 17:14:08 -060015 Compare the contents of two files.
Timothy Elliottae079d22012-02-06 01:28:40 -080016
Rob Landley7aa651a2012-11-13 17:14:08 -060017 -l show all differing bytes
18 -s silent
Timothy Elliottae079d22012-02-06 01:28:40 -080019*/
20
Rob Landleyc0e56ed2012-10-08 00:02:30 -050021#define FOR_cmp
Timothy Elliottae079d22012-02-06 01:28:40 -080022#include "toys.h"
23
Rob Landleyc0e56ed2012-10-08 00:02:30 -050024GLOBALS(
Rob Landley7aa651a2012-11-13 17:14:08 -060025 int fd;
26 char *name;
Rob Landleyf7c1de32012-02-07 22:25:59 -060027)
Timothy Elliottae079d22012-02-06 01:28:40 -080028
Rob Landley7aa651a2012-11-13 17:14:08 -060029// This handles opening the file and
Rob Landleyf7c1de32012-02-07 22:25:59 -060030
31void do_cmp(int fd, char *name)
Rob Landleye0bd6912012-02-07 21:32:32 -060032{
Rob Landley7aa651a2012-11-13 17:14:08 -060033 int i, len1, len2, min_len, size = sizeof(toybuf)/2;
34 long byte_no = 1, line_no = 1;
35 char *buf2 = toybuf+size;
Rob Landleyf7c1de32012-02-07 22:25:59 -060036
Rob Landley7aa651a2012-11-13 17:14:08 -060037 // First time through, cache the data and return.
38 if (!TT.fd) {
39 TT.name = name;
40 // On return the old filehandle is closed, and this assures that even
41 // if we were called with stdin closed, the new filehandle != 0.
42 TT.fd = dup(fd);
43 return;
44 }
Timothy Elliottae079d22012-02-06 01:28:40 -080045
Rob Landley7aa651a2012-11-13 17:14:08 -060046 for (;;) {
47 len1 = readall(TT.fd, toybuf, size);
48 len2 = readall(fd, buf2, size);
Timothy Elliottae079d22012-02-06 01:28:40 -080049
Rob Landley7aa651a2012-11-13 17:14:08 -060050 min_len = len1 < len2 ? len1 : len2;
51 for (i=0; i<min_len; i++) {
52 if (toybuf[i] != buf2[i]) {
53 toys.exitval = 1;
54 if (toys.optflags & FLAG_l)
55 printf("%ld %o %o\n", byte_no, toybuf[i], buf2[i]);
56 else {
57 if (!(toys.optflags & FLAG_s)) {
58 printf("%s %s differ: char %ld, line %ld\n",
59 TT.name, name, byte_no, line_no);
60 toys.exitval++;
61 }
62 goto out;
63 }
64 }
65 byte_no++;
66 if (toybuf[i] == '\n') line_no++;
67 }
68 if (len1 != len2) {
69 if (!(toys.optflags & FLAG_s))
70 fprintf(stderr, "cmp: EOF on %s\n", len1 < len2 ? TT.name : name);
71 toys.exitval = 1;
72 break;
73 }
74 if (len1 < 1) break;
75 }
Rob Landley03a8f742012-03-02 08:33:01 -060076out:
Rob Landley7aa651a2012-11-13 17:14:08 -060077 if (CFG_TOYBOX_FREE) close(TT.fd);
Timothy Elliottae079d22012-02-06 01:28:40 -080078}
79
80void cmp_main(void)
81{
Rob Landley784eb9c2014-10-14 14:16:34 -050082 loopfiles_rw(toys.optargs, O_CLOEXEC, 0, toys.optflags&FLAG_s, do_cmp);
Timothy Elliottae079d22012-02-06 01:28:40 -080083}
84