10f66f451Sopenharmony_ci/* cmp.c - Compare two files. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Timothy Elliott <tle@holymonkey.com> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/cmp.html 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciUSE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2))) 80f66f451Sopenharmony_ci 90f66f451Sopenharmony_ciconfig CMP 100f66f451Sopenharmony_ci bool "cmp" 110f66f451Sopenharmony_ci default y 120f66f451Sopenharmony_ci help 130f66f451Sopenharmony_ci usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]] 140f66f451Sopenharmony_ci 150f66f451Sopenharmony_ci Compare the contents of two files. (Or stdin and file if only one given.) 160f66f451Sopenharmony_ci 170f66f451Sopenharmony_ci -l Show all differing bytes 180f66f451Sopenharmony_ci -s Silent 190f66f451Sopenharmony_ci*/ 200f66f451Sopenharmony_ci 210f66f451Sopenharmony_ci#define FOR_cmp 220f66f451Sopenharmony_ci#include "toys.h" 230f66f451Sopenharmony_ci 240f66f451Sopenharmony_ciGLOBALS( 250f66f451Sopenharmony_ci int fd; 260f66f451Sopenharmony_ci char *name; 270f66f451Sopenharmony_ci) 280f66f451Sopenharmony_ci 290f66f451Sopenharmony_cistatic void do_cmp(int fd, char *name) 300f66f451Sopenharmony_ci{ 310f66f451Sopenharmony_ci int i, len1, len2, min_len, size = sizeof(toybuf)/2; 320f66f451Sopenharmony_ci long byte_no = 1, line_no = 1; 330f66f451Sopenharmony_ci char *buf2 = toybuf+size; 340f66f451Sopenharmony_ci 350f66f451Sopenharmony_ci // First time through, cache the data and return. 360f66f451Sopenharmony_ci if (!TT.fd) { 370f66f451Sopenharmony_ci TT.name = name; 380f66f451Sopenharmony_ci // On return the old filehandle is closed, and this assures that even 390f66f451Sopenharmony_ci // if we were called with stdin closed, the new filehandle != 0. 400f66f451Sopenharmony_ci TT.fd = dup(fd); 410f66f451Sopenharmony_ci return; 420f66f451Sopenharmony_ci } 430f66f451Sopenharmony_ci 440f66f451Sopenharmony_ci toys.exitval = 0; 450f66f451Sopenharmony_ci 460f66f451Sopenharmony_ci for (;;) { 470f66f451Sopenharmony_ci len1 = readall(TT.fd, toybuf, size); 480f66f451Sopenharmony_ci len2 = readall(fd, buf2, size); 490f66f451Sopenharmony_ci 500f66f451Sopenharmony_ci min_len = len1 < len2 ? len1 : len2; 510f66f451Sopenharmony_ci for (i=0; i<min_len; i++) { 520f66f451Sopenharmony_ci if (toybuf[i] != buf2[i]) { 530f66f451Sopenharmony_ci toys.exitval = 1; 540f66f451Sopenharmony_ci if (toys.optflags & FLAG_l) 550f66f451Sopenharmony_ci printf("%ld %o %o\n", byte_no, toybuf[i], buf2[i]); 560f66f451Sopenharmony_ci else { 570f66f451Sopenharmony_ci if (!(toys.optflags & FLAG_s)) 580f66f451Sopenharmony_ci printf("%s %s differ: char %ld, line %ld\n", 590f66f451Sopenharmony_ci TT.name, name, byte_no, line_no); 600f66f451Sopenharmony_ci goto out; 610f66f451Sopenharmony_ci } 620f66f451Sopenharmony_ci } 630f66f451Sopenharmony_ci byte_no++; 640f66f451Sopenharmony_ci if (toybuf[i] == '\n') line_no++; 650f66f451Sopenharmony_ci } 660f66f451Sopenharmony_ci if (len1 != len2) { 670f66f451Sopenharmony_ci if (!(toys.optflags & FLAG_s)) 680f66f451Sopenharmony_ci fprintf(stderr, "cmp: EOF on %s\n", len1 < len2 ? TT.name : name); 690f66f451Sopenharmony_ci toys.exitval = 1; 700f66f451Sopenharmony_ci break; 710f66f451Sopenharmony_ci } 720f66f451Sopenharmony_ci if (len1 < 1) break; 730f66f451Sopenharmony_ci } 740f66f451Sopenharmony_ciout: 750f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) close(TT.fd); 760f66f451Sopenharmony_ci} 770f66f451Sopenharmony_ci 780f66f451Sopenharmony_civoid cmp_main(void) 790f66f451Sopenharmony_ci{ 800f66f451Sopenharmony_ci toys.exitval = 2; 810f66f451Sopenharmony_ci loopfiles_rw(toys.optargs, O_CLOEXEC|(WARN_ONLY*!(toys.optflags&FLAG_s)), 0, 820f66f451Sopenharmony_ci do_cmp); 830f66f451Sopenharmony_ci if (toys.optc == 1) do_cmp(0, "-"); 840f66f451Sopenharmony_ci} 85