Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 1 | /* cmp.c - Compare two files. |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 2 | * |
| 3 | * Copyright 2012 Timothy Elliott <tle@holymonkey.com> |
| 4 | * |
Rob Landley | f91b7c8 | 2012-08-25 18:08:51 -0500 | [diff] [blame] | 5 | * See http://opengroup.org/onlinepubs/9699919799/utilities/cmp.html |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 6 | |
| 7 | USE_CMP(NEWTOY(cmp, "<2>2ls", TOYFLAG_USR|TOYFLAG_BIN)) |
| 8 | |
| 9 | config CMP |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 10 | bool "cmp" |
| 11 | default y |
| 12 | help |
| 13 | usage: cmp [-l] [-s] FILE1 FILE2 |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 14 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 15 | Compare the contents of two files. |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 16 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 17 | -l show all differing bytes |
| 18 | -s silent |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 19 | */ |
| 20 | |
Rob Landley | c0e56ed | 2012-10-08 00:02:30 -0500 | [diff] [blame] | 21 | #define FOR_cmp |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 22 | #include "toys.h" |
| 23 | |
Rob Landley | c0e56ed | 2012-10-08 00:02:30 -0500 | [diff] [blame] | 24 | GLOBALS( |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 25 | int fd; |
| 26 | char *name; |
Rob Landley | f7c1de3 | 2012-02-07 22:25:59 -0600 | [diff] [blame] | 27 | ) |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 28 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 29 | // This handles opening the file and |
Rob Landley | f7c1de3 | 2012-02-07 22:25:59 -0600 | [diff] [blame] | 30 | |
| 31 | void do_cmp(int fd, char *name) |
Rob Landley | e0bd691 | 2012-02-07 21:32:32 -0600 | [diff] [blame] | 32 | { |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 33 | int i, len1, len2, min_len, size = sizeof(toybuf)/2; |
| 34 | long byte_no = 1, line_no = 1; |
| 35 | char *buf2 = toybuf+size; |
Rob Landley | f7c1de3 | 2012-02-07 22:25:59 -0600 | [diff] [blame] | 36 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 37 | // 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 Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 45 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 46 | for (;;) { |
| 47 | len1 = readall(TT.fd, toybuf, size); |
| 48 | len2 = readall(fd, buf2, size); |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 49 | |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 50 | 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 Landley | 03a8f74 | 2012-03-02 08:33:01 -0600 | [diff] [blame] | 76 | out: |
Rob Landley | 7aa651a | 2012-11-13 17:14:08 -0600 | [diff] [blame] | 77 | if (CFG_TOYBOX_FREE) close(TT.fd); |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | void cmp_main(void) |
| 81 | { |
Rob Landley | 784eb9c | 2014-10-14 14:16:34 -0500 | [diff] [blame] | 82 | loopfiles_rw(toys.optargs, O_CLOEXEC, 0, toys.optflags&FLAG_s, do_cmp); |
Timothy Elliott | ae079d2 | 2012-02-06 01:28:40 -0800 | [diff] [blame] | 83 | } |
| 84 | |