regular.c revision 180426
1251877Speter/*- 2251877Speter * Copyright (c) 1991, 1993, 1994 3251877Speter * The Regents of the University of California. All rights reserved. 4251877Speter * 5251877Speter * Redistribution and use in source and binary forms, with or without 6251877Speter * modification, are permitted provided that the following conditions 7251877Speter * are met: 8251877Speter * 1. Redistributions of source code must retain the above copyright 9251877Speter * notice, this list of conditions and the following disclaimer. 10251877Speter * 2. Redistributions in binary form must reproduce the above copyright 11251877Speter * notice, this list of conditions and the following disclaimer in the 12251877Speter * documentation and/or other materials provided with the distribution. 13251877Speter * 3. All advertising materials mentioning features or use of this software 14251877Speter * must display the following acknowledgement: 15251877Speter * This product includes software developed by the University of 16251877Speter * California, Berkeley and its contributors. 17251877Speter * 4. Neither the name of the University nor the names of its contributors 18251877Speter * may be used to endorse or promote products derived from this software 19251877Speter * without specific prior written permission. 20251877Speter * 21251877Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22251877Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23251877Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24251877Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25251877Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26253895Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27253895Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28251877Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29251877Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30251877Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31251877Speter * SUCH DAMAGE. 32251877Speter */ 33251877Speter 34251877Speter#if 0 35251877Speter#ifndef lint 36251877Speterstatic char sccsid[] = "@(#)regular.c 8.3 (Berkeley) 4/2/94"; 37251877Speter#endif 38251877Speter#endif 39251877Speter 40251877Speter#include <sys/cdefs.h> 41251877Speter__FBSDID("$FreeBSD: head/usr.bin/cmp/regular.c 180426 2008-07-10 13:26:46Z charnier $"); 42251877Speter 43251877Speter#include <sys/param.h> 44251877Speter#include <sys/mman.h> 45251877Speter#include <sys/stat.h> 46253895Speter 47253895Speter#include <err.h> 48251877Speter#include <errno.h> 49251877Speter#include <limits.h> 50253895Speter#include <signal.h> 51262339Speter#include <stdlib.h> 52251877Speter#include <stdio.h> 53251877Speter#include <string.h> 54251877Speter#include <unistd.h> 55251877Speter 56251877Speter#include "extern.h" 57251877Speter 58251877Speterstatic u_char *remmap(u_char *, int, off_t); 59253895Speterstatic void segv_handler(int); 60253895Speter#define MMAP_CHUNK (8*1024*1024) 61253895Speter 62253895Speter#define ROUNDPAGE(i) ((i) & ~pagemask) 63253895Speter 64253895Spetervoid 65251877Speterc_regular(int fd1, const char *file1, off_t skip1, off_t len1, 66253895Speter int fd2, const char *file2, off_t skip2, off_t len2) 67253895Speter{ 68251877Speter u_char ch, *p1, *p2, *m1, *m2, *e1, *e2; 69253895Speter off_t byte, length, line; 70253895Speter int dfound; 71253895Speter off_t pagemask, off1, off2; 72253895Speter size_t pagesize; 73253895Speter struct sigaction act, oact; 74253895Speter 75253895Speter if (skip1 > len1) 76253895Speter eofmsg(file1); 77253895Speter len1 -= skip1; 78251877Speter if (skip2 > len2) 79251877Speter eofmsg(file2); 80251877Speter len2 -= skip2; 81251877Speter 82251877Speter if (sflag && len1 != len2) 83251877Speter exit(DIFF_EXIT); 84251877Speter 85253895Speter sigemptyset(&act.sa_mask); 86253895Speter act.sa_flags = SA_NODEFER; 87253895Speter act.sa_handler = segv_handler; 88251877Speter if (sigaction(SIGSEGV, &act, &oact)) 89251877Speter err(ERR_EXIT, "sigaction()"); 90251877Speter 91251877Speter pagesize = getpagesize(); 92253895Speter pagemask = (off_t)pagesize - 1; 93253895Speter off1 = ROUNDPAGE(skip1); 94253895Speter off2 = ROUNDPAGE(skip2); 95253895Speter 96253895Speter length = MIN(len1, len2); 97251877Speter 98251877Speter if ((m1 = remmap(NULL, fd1, off1)) == NULL) { 99251877Speter c_special(fd1, file1, skip1, fd2, file2, skip2); 100251877Speter return; 101251877Speter } 102251877Speter 103251877Speter if ((m2 = remmap(NULL, fd2, off2)) == NULL) { 104251877Speter munmap(m1, MMAP_CHUNK); 105251877Speter c_special(fd1, file1, skip1, fd2, file2, skip2); 106251877Speter return; 107251877Speter } 108251877Speter 109251877Speter dfound = 0; 110251877Speter e1 = m1 + MMAP_CHUNK; 111251877Speter e2 = m2 + MMAP_CHUNK; 112251877Speter p1 = m1 + (skip1 - off1); 113251877Speter p2 = m2 + (skip2 - off2); 114251877Speter 115251877Speter for (byte = line = 1; length--; ++byte) { 116251877Speter if ((ch = *p1) != *p2) { 117251877Speter if (xflag) { 118251877Speter dfound = 1; 119251877Speter (void)printf("%08llx %02x %02x\n", 120251877Speter (long long)byte - 1, ch, *p2); 121251877Speter } else if (lflag) { 122253895Speter dfound = 1; 123253895Speter (void)printf("%6lld %3o %3o\n", 124253895Speter (long long)byte, ch, *p2); 125253895Speter } else 126253895Speter diffmsg(file1, file2, byte, line); 127253895Speter /* NOTREACHED */ 128251877Speter } 129253895Speter if (ch == '\n') 130253895Speter ++line; 131251877Speter if (++p1 == e1) { 132251877Speter off1 += MMAP_CHUNK; 133251877Speter if ((p1 = m1 = remmap(m1, fd1, off1)) == NULL) { 134253895Speter munmap(m2, MMAP_CHUNK); 135253895Speter err(ERR_EXIT, "remmap %s", file1); 136253895Speter } 137253895Speter e1 = m1 + MMAP_CHUNK; 138253895Speter } 139253895Speter if (++p2 == e2) { 140253895Speter off2 += MMAP_CHUNK; 141253895Speter if ((p2 = m2 = remmap(m2, fd2, off2)) == NULL) { 142253895Speter munmap(m1, MMAP_CHUNK); 143253895Speter err(ERR_EXIT, "remmap %s", file2); 144253895Speter } 145253895Speter e2 = m2 + MMAP_CHUNK; 146253895Speter } 147251877Speter } 148251877Speter munmap(m1, MMAP_CHUNK); 149251877Speter munmap(m2, MMAP_CHUNK); 150251877Speter 151251877Speter if (sigaction(SIGSEGV, &oact, NULL)) 152251877Speter err(ERR_EXIT, "sigaction()"); 153251877Speter 154251877Speter if (len1 != len2) 155251877Speter eofmsg (len1 > len2 ? file2 : file1); 156251877Speter if (dfound) 157251877Speter exit(DIFF_EXIT); 158251877Speter} 159251877Speter 160253895Speterstatic u_char * 161253895Speterremmap(u_char *mem, int fd, off_t offset) 162251877Speter{ 163251877Speter if (mem != NULL) 164253895Speter munmap(mem, MMAP_CHUNK); 165251877Speter mem = mmap(NULL, MMAP_CHUNK, PROT_READ, MAP_SHARED, fd, offset); 166253895Speter if (mem == MAP_FAILED) 167251877Speter return (NULL); 168253895Speter madvise(mem, MMAP_CHUNK, MADV_SEQUENTIAL); 169251877Speter return (mem); 170253895Speter} 171253895Speter 172253895Speterstatic void 173251877Spetersegv_handler(int sig __unused) { 174251877Speter static const char msg[] = "cmp: Input/output error (caught SIGSEGV)\n"; 175251877Speter 176251877Speter write(STDERR_FILENO, msg, sizeof(msg)); 177251877Speter _exit(EXIT_FAILURE); 178} 179