VirtualBox

Changeset 1309 in kBuild for trunk/src/kmk


Ignore:
Timestamp:
Dec 2, 2007 4:53:40 AM (17 years ago)
Author:
bird
Message:

combined the bulk of the cmp stuff into cmp_util.c. implemented cp --changed.

Location:
trunk/src/kmk
Files:
3 deleted
9 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r1274 r1309  
    5656                kmkbuiltin/cat.c \
    5757                kmkbuiltin/cmp.c \
     58                kmkbuiltin/cmp_util.c \
    5859                kmkbuiltin/cp.c \
    5960                kmkbuiltin/cp_utils.c \
     
    7576                kmkbuiltin/version.c
    7677
     78## TODO kmk_redirect.
    7779
    7880EXTRA_kmk_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
  • trunk/src/kmk/Makefile.kmk

    r1302 r1309  
    163163        kmkbuiltin/cat.c \
    164164        kmkbuiltin/cmp.c \
     165        kmkbuiltin/cmp_util.c \
    165166        kmkbuiltin/cp.c \
    166167        kmkbuiltin/cp_utils.c \
     
    220221kmk_cmp_DEFS = kmk_builtin_cmp=main
    221222kmk_cmp_SOURCES = \
    222         kmkbuiltin/cmp.c
     223        kmkbuiltin/cmp.c \
     224        kmkbuiltin/cmp_util.c
    223225
    224226kmk_cp_TEMPLATE = BIN-KMK
     
    226228kmk_cp_SOURCES = \
    227229        kmkbuiltin/cp.c \
    228         kmkbuiltin/cp_utils.c
     230        kmkbuiltin/cp_utils.c \
     231        kmkbuiltin/cmp_util.c
    229232
    230233kmk_echo_TEMPLATE = BIN-KMK
  • trunk/src/kmk/kmkbuiltin/cmp.c

    r1246 r1309  
    3030 */
    3131
    32 /*#include <sys/cdefs.h>*/
    33 #ifndef lint
    3432/*__COPYRIGHT("@(#) Copyright (c) 1987, 1990, 1993, 1994\n\
    35         The Regents of the University of California.  All rights reserved.\n");*/
    36 #endif /* not lint */
    37 
    38 #ifndef lint
    39 /*#if 0
     33        The Regents of the University of California.  All rights reserved.\n");
    4034static char sccsid[] = "@(#)cmp.c       8.3 (Berkeley) 4/2/94";
    41 #else
    42 __RCSID("$NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $");
    43 #endif*/
    44 #endif /* not lint */
     35__RCSID("$NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $"); */
    4536
    4637#include <sys/types.h>
    47 #include <sys/stat.h>
    48 
    4938#include "err.h"
    5039#include <errno.h>
    51 #include <fcntl.h>
    5240#include <stdio.h>
    5341#include <stdlib.h>
    5442#include <string.h>
     43#include <locale.h>
    5544#ifndef _MSC_VER
    5645# include <unistd.h>
    5746#else
     47# define MSC_DO_64_BIT_IO /* for correct off_t */
    5848# include "mscfakes.h"
    59 # if _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */
    60 #  define off_t __int64
    61 #  define stat  _stat64
    62 #  define fstat _fstat64
    63 #  define lseek _lseeki64
    64 # endif
    6549#endif
    66 #include <locale.h>
    6750#include "getopt.h"
    6851
    69 #ifndef O_BINARY
    70 # define O_BINARY 0
    71 #endif
    72 
    73 /*#include "extern.h"*/
    74 
    7552#include "kmkbuiltin.h"
     53#include "cmp_extern.h"
    7654
    7755
    78 static int      lflag, sflag;
    79 
    80 static struct option long_options[] =
     56static const struct option long_options[] =
    8157{
    8258    { "help",                                           no_argument, 0, 261 },
     
    8662
    8763
    88 /* this is kind of ugly but its the simplest way to avoid namespace mess. */
    89 #include "cmp_misc.c"
    90 #include "cmp_special.c"
    91 #if defined(__FreeBSD__) || defined(__NetBSD__) /** @todo more mmap capable OSes. */
    92 #include "cmp_regular.c"
    93 #else
    94 #include "cmp_regular_std.c"
    95 #endif
    96 
    9764static int usage(FILE *);
    9865
     
    10067kmk_builtin_cmp(int argc, char *argv[], char **envp)
    10168{
    102         struct stat sb1, sb2;
    103         off_t skip1 = 0, skip2 = 0;
    104         int ch, fd1, fd2, special;
    105         char *file1, *file2;
    106         int rc;
     69    off_t skip1 = 0, skip2 = 0;
     70    int lflag = 0, sflag = 0;
     71    int ch;
     72    char *file1, *file2;
    10773
    10874#ifdef kmk_builtin_cmp
    109         setlocale(LC_ALL, "");
     75    setlocale(LC_ALL, "");
    11076#endif
    111         /* init globals */
    112         lflag = sflag = 0;
    11377
    114         /* reset getopt and set progname. */
    115         g_progname = argv[0];
    116         opterr = 1;
    117         optarg = NULL;
    118         optopt = 0;
    119         optind = 0; /* init */
     78    /* reset getopt and set progname. */
     79    g_progname = argv[0];
     80    opterr = 1;
     81    optarg = NULL;
     82    optopt = 0;
     83    optind = 0; /* init */
    12084
    121         while ((ch = getopt_long(argc, argv, "ls", long_options, NULL)) != -1)
    122                 switch (ch) {
    123                 case 'l':               /* print all differences */
    124                         lflag = 1;
    125                         break;
    126                 case 's':               /* silent run */
    127                         sflag = 1;
    128                         break;
    129                 case 261:
    130                         usage(stdout);
    131                         return 0;
    132                 case 262:
    133                         return kbuild_version(argv[0]);
    134                 case '?':
    135                 default:
    136                         return usage(stderr);
    137                 }
    138         argv += optind;
    139         argc -= optind;
     85    while ((ch = getopt_long(argc, argv, "ls", long_options, NULL)) != -1)
     86    {
     87        switch (ch)
     88        {
     89            case 'l':           /* print all differences */
     90                lflag = 1;
     91                break;
     92            case 's':           /* silent run */
     93                sflag = 1;
     94                break;
     95            case 261:
     96                usage(stdout);
     97                return 0;
     98            case 262:
     99                return kbuild_version(argv[0]);
     100            case '?':
     101            default:
     102                return usage(stderr);
     103        }
     104    }
     105    argv += optind;
     106    argc -= optind;
    140107
    141         if (lflag && sflag)
    142                 return errx(ERR_EXIT, "only one of -l and -s may be specified");
     108    if (argc < 2 || argc > 4)
     109        return usage(stderr);
    143110
    144         if (argc < 2 || argc > 4)
    145                 return usage(stderr);
     111    file1 = argv[0];
     112    file2 = argv[1];
    146113
    147         /* Backward compatibility -- handle "-" meaning stdin. */
    148         special = 0;
    149         if (strcmp(file1 = argv[0], "-") == 0) {
    150                 special = 1;
    151                 fd1 = 0;
    152                 file1 = "stdin";
     114    if (argc > 2)
     115    {
     116        char *ep;
     117
     118        errno = 0;
     119        skip1 = strtoll(argv[2], &ep, 0);
     120        if (errno || ep == argv[2])
     121            return errx(ERR_EXIT, "strtoll(%s,,) failed", argv[2]);
     122
     123        if (argc == 4)
     124        {
     125            skip2 = strtoll(argv[3], &ep, 0);
     126            if (errno || ep == argv[3])
     127                return errx(ERR_EXIT, "strtoll(%s,,) failed", argv[3]);
    153128        }
    154         else if ((fd1 = open(file1, O_RDONLY | O_BINARY, 0)) < 0) {
    155                 if (!sflag)
    156                         warn("%s", file1);
    157                 return(ERR_EXIT);
    158         }
    159         if (strcmp(file2 = argv[1], "-") == 0) {
    160                 if (special)
    161                         return errx(ERR_EXIT,
    162                                 "standard input may only be specified once");
    163                 special = 1;
    164                 fd2 = 0;
    165                 file2 = "stdin";
    166         }
    167         else if ((fd2 = open(file2, O_RDONLY | O_BINARY, 0)) < 0) {
    168                 if (!sflag)
    169                         warn("%s", file2);
    170                 if (fd1 != 0) close(fd1);
    171                 return(ERR_EXIT);
    172         }
     129    }
    173130
    174         if (argc > 2) {
    175                 char *ep;
    176 
    177                 errno = 0;
    178                 skip1 = strtoll(argv[2], &ep, 0);
    179                 if (errno || ep == argv[2]) {
    180                         rc = usage(stderr);
    181                         goto l_exit;
    182                 }
    183 
    184                 if (argc == 4) {
    185                         skip2 = strtoll(argv[3], &ep, 0);
    186                         if (errno || ep == argv[3]) {
    187                                 rc = usage(stderr);
    188                                 goto l_exit;
    189                         }
    190                 }
    191         }
    192 
    193         if (!special) {
    194                 if (fstat(fd1, &sb1)) {
    195                         rc = err(ERR_EXIT, "%s", file1);
    196                         goto l_exit;
    197                 }
    198                 if (!S_ISREG(sb1.st_mode))
    199                         special = 1;
    200                 else {
    201                         if (fstat(fd2, &sb2)) {
    202                                 rc = err(ERR_EXIT, "%s", file2);
    203                                 goto l_exit;
    204                         }
    205                         if (!S_ISREG(sb2.st_mode))
    206                                 special = 1;
    207                 }
    208         }
    209 
    210         if (special)
    211                 rc = c_special(fd1, file1, skip1, fd2, file2, skip2);
    212         else
    213                 rc = c_regular(fd1, file1, skip1, sb1.st_size,
    214                     fd2, file2, skip2, sb2.st_size);
    215 l_exit:
    216         if (fd1 != 0) close(fd1);
    217         if (fd2 != 0) close(fd2);
    218         return rc;
     131    return cmp_file_and_file_ex(file1, skip1, file2, skip2, sflag, lflag, 0);
    219132}
    220133
     
    223136{
    224137    fprintf(fp, "usage: %s [-l | -s] file1 file2 [skip1 [skip2]]\n"
    225                                 "   or: %s --help\n"
    226                                 "   or: %s --version\n",
    227                         g_progname, g_progname, g_progname);
    228         return(ERR_EXIT);
     138                "   or: %s --help\n"
     139                "   or: %s --version\n",
     140            g_progname, g_progname, g_progname);
     141    return ERR_EXIT;
    229142}
  • trunk/src/kmk/kmkbuiltin/cmp_extern.h

    r1117 r1309  
    3636#define ERR_EXIT        2       /* error exit code */
    3737
    38 static int      c_regular(int, char *, off_t, off_t, int, char *, off_t, off_t);
    39 static int      c_special(int, char *, off_t, int, char *, off_t);
    40 static int      diffmsg(char *, char *, off_t, off_t);
    41 static int      eofmsg(char *, off_t, off_t);
    42 static int      errmsg(char *, off_t, off_t);
     38int cmp_file_and_file(const char *file1, const char *file2, int sflag, int lflag, int special);
     39int cmp_file_and_file_ex(const char *file1, off_t skip1,
     40                         const char *file2, off_t skip2, int sflag, int lflag, int special);
     41int cmp_fd_and_file(int fd1, const char *file1,
     42                    const char *file2, int sflag, int lflag, int special);
     43int cmp_fd_and_file_ex(int fd1, const char *file1, off_t skip1,
     44                       const char *file2, off_t skip2, int sflag, int lflag, int special);
     45int cmp_fd_and_fd(int fd1, const char *file1,
     46                  int fd2, const char *file2, int sflag, int lflag, int special);
     47int cmp_fd_and_fd_ex(int fd1, const char *file1, off_t skip1,
     48                     int fd2, const char *file2, off_t skip2,  int sflag, int lflag, int special);
    4349
    44 /*extern int lflag, sflag;*/
  • trunk/src/kmk/kmkbuiltin/cmp_util.c

    r1301 r1309  
    11/*      $NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $ */
     2/*      $NetBSD: misc.c,v 1.11 2007/08/22 16:59:19 christos Exp $       */
     3/*      $NetBSD: regular.c,v 1.20 2006/06/03 21:47:55 christos Exp $    */
     4/*      $NetBSD: special.c,v 1.12 2007/08/21 14:09:54 christos Exp $    */
    25
    36/*
     
    3033 */
    3134
    32 /*#include <sys/cdefs.h>*/
    33 #ifndef lint
    3435/*__COPYRIGHT("@(#) Copyright (c) 1987, 1990, 1993, 1994\n\
    3536        The Regents of the University of California.  All rights reserved.\n");*/
    36 #endif /* not lint */
    37 
    38 #ifndef lint
    39 /*#if 0
    40 static char sccsid[] = "@(#)cmp.c       8.3 (Berkeley) 4/2/94";
    41 #else
    42 __RCSID("$NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $");
    43 #endif*/
    44 #endif /* not lint */
    4537
    4638#include <sys/types.h>
    4739#include <sys/stat.h>
    48 
    49 #include "err.h"
     40#if defined(__FreeBSD__) || defined(__NetBSD__) /** @todo more mmap capable OSes. */
     41# define CMP_USE_MMAP
     42# include <sys/param.h>
     43# include <sys/mman.h>
     44#endif
    5045#include <errno.h>
    5146#include <fcntl.h>
     
    5550#ifndef _MSC_VER
    5651# include <unistd.h>
    57 #else
     52# ifndef O_BINARY
     53#  define O_BINARY 0
     54# endif
     55#else
     56# define MSC_DO_64_BIT_IO
    5857# include "mscfakes.h"
    59 # if _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */
    60 #  define off_t __int64
    61 #  define stat  _stat64
    62 #  define fstat _fstat64
    63 #  define lseek _lseeki64
    64 # endif
    65 #endif
    66 #include <locale.h>
    67 #include "getopt.h"
    68 
    69 #ifndef O_BINARY
    70 # define O_BINARY 0
    71 #endif
    72 
    73 /*#include "extern.h"*/
    74 
    75 #include "kmkbuiltin.h"
    76 
    77 
    78 static int      lflag, sflag;
    79 
    80 static struct option long_options[] =
    81 {
    82     { "help",                                           no_argument, 0, 261 },
    83     { "version",                                        no_argument, 0, 262 },
    84     { 0, 0,     0, 0 },
    85 };
    86 
    87 
    88 /* this is kind of ugly but its the simplest way to avoid namespace mess. */
    89 #include "cmp_misc.c"
    90 #include "cmp_special.c"
    91 #if defined(__FreeBSD__) || defined(__NetBSD__) /** @todo more mmap capable OSes. */
    92 #include "cmp_regular.c"
    93 #else
    94 #include "cmp_regular_std.c"
    95 #endif
    96 
    97 static int usage(FILE *);
    98 
     58#endif
     59#include "err.h"
     60
     61#include "cmp_extern.h"
     62
     63
     64static int
     65errmsg(const char *file, off_t byte, off_t line, int lflag)
     66{
     67    if (lflag)
     68#ifdef _MSC_VER
     69        return err(ERR_EXIT, "%s: char %I64d, line %lld", file, (__int64)byte, (long long)line);
     70#else
     71        return err(ERR_EXIT, "%s: char %lld, line %lld", file, (long long)byte, (long long)line);
     72#endif
     73    return err(ERR_EXIT, "%s", file);
     74}
     75
     76
     77static int
     78eofmsg(const char *file, off_t byte, off_t line, int sflag, int lflag)
     79{
     80    if (!sflag)
     81    {
     82        if (!lflag)
     83            warnx("EOF on %s", file);
     84        else
     85        {
     86#ifdef _MSC_VER
     87            if (line > 0)
     88                warnx("EOF on %s: char %I64d, line %I64d", file, (__int64)byte, (__int64)line);
     89            else
     90                warnx("EOF on %s: char %I64d", file, (__int64)byte);
     91#else
     92            if (line > 0)
     93                warnx("EOF on %s: char %lld, line %lld", file, (long long)byte, (long long)line);
     94            else
     95                warnx("EOF on %s: char %lld", file, (long long)byte);
     96#endif
     97        }
     98    }
     99    return DIFF_EXIT;
     100}
     101
     102
     103static int
     104diffmsg(const char *file1, const char *file2, off_t byte, off_t line, int sflag)
     105{
     106    if (!sflag)
     107#ifdef _MSC_VER
     108        printf("%s %s differ: char %I64d, line %I64d\n",
     109               file1, file2, (__int64)byte, (__int64)line);
     110#else
     111        printf("%s %s differ: char %lld, line %lld\n",
     112               file1, file2, (long long)byte, (long long)line);
     113#endif
     114    return DIFF_EXIT;
     115}
     116
     117
     118/**
     119 * Compares two files, where one or both are non-regular ones.
     120 */
     121static int
     122c_special(int fd1, const char *file1, off_t skip1,
     123          int fd2, const char *file2, off_t skip2,
     124          int lflag, int sflag)
     125{
     126    int fd1dup, fd2dup;
     127    FILE *fp1;
     128    int rc;
     129
     130    /* duplicate because fdopen+fclose will otherwise close the handle. */
     131    fd1dup = dup(fd1);
     132    if (fd1 < 0)
     133        return err(ERR_EXIT, "%s", file1);
     134    fp1 = fdopen(fd1dup, "rb");
     135    if (!fp1)
     136        fp1 = fdopen(fd1dup, "r");
     137    if (!fp1)
     138    {
     139        err(ERR_EXIT, "%s", file1);
     140        close(fd1dup);
     141        return ERR_EXIT;
     142    }
     143
     144    fd2dup = dup(fd2);
     145    if (fd2dup >= 0)
     146    {
     147        FILE *fp2 = fdopen(fd2dup, "rb");
     148        if (!fp2)
     149            fp2 = fdopen(fd2dup, "r");
     150        if (fp2)
     151        {
     152            off_t byte;
     153            off_t line;
     154            int ch1 = 0;
     155            int ch2 = 0;
     156
     157            /* skipping ahead */
     158            rc = OK_EXIT;
     159            for (byte = line = 1; skip1--; byte++)
     160            {
     161                ch1 = getc(fp1);
     162                if (ch1 == EOF)
     163                    break;
     164                if (ch1 == '\n')
     165                    line++;
     166            }
     167            for (byte = line = 1; skip2--; byte++)
     168            {
     169                ch2 = getc(fp2);
     170                if (ch2 == EOF)
     171                    break;
     172                if (ch2 == '\n')
     173                    line++;
     174            }
     175            if (ch2 != EOF && ch1 != EOF)
     176            {
     177                /* compare byte by byte */
     178                for (byte = line = 1;; ++byte)
     179                {
     180                    ch1 = getc(fp1);
     181                    ch2 = getc(fp2);
     182                    if (ch1 == EOF || ch2 == EOF)
     183                        break;
     184                    if (ch1 != ch2)
     185                    {
     186                        if (!lflag)
     187                        {
     188                            rc = diffmsg(file1, file2, byte, line, sflag);
     189                            break;
     190                        }
     191                        rc = DIFF_EXIT;
     192#ifdef _MSC_VER
     193                        printf("%6i64d %3o %3o\n", (__int64)byte, ch1, ch2);
     194#else
     195                        printf("%6lld %3o %3o\n", (long long)byte, ch1, ch2);
     196#endif
     197                    }
     198                    if (ch1 == '\n')
     199                        ++line;
     200                }
     201            }
     202
     203            /* Check for errors and length differences (EOF). */
     204            if (ferror(fp1) && rc != ERR_EXIT)
     205                rc = errmsg(file1, byte, line, lflag);
     206            if (ferror(fp2) && rc != ERR_EXIT)
     207                rc = errmsg(file2, byte, line, lflag);
     208            if (rc == OK_EXIT)
     209            {
     210                if (feof(fp1))
     211                {
     212                    if (!feof(fp2))
     213                        rc = eofmsg(file1, byte, line, sflag, lflag);
     214                }
     215                else if (feof(fp2))
     216                    rc = eofmsg(file2, byte, line, sflag, lflag);
     217            }
     218
     219            fclose(fp2);
     220        }
     221        else
     222        {
     223            rc = err(ERR_EXIT, "%s", file2);
     224            close(fd2dup);
     225        }
     226    }
     227    else
     228        rc = err(ERR_EXIT, "%s", file2);
     229
     230    fclose(fp1);
     231    return rc;
     232}
     233
     234
     235#ifdef CMP_USE_MMAP
     236/**
     237 * Compare two files using mmap.
     238 */
     239static int
     240c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
     241          int fd2, const char *file2, off_t skip2, off_t len2, int sflag, int lflag)
     242{
     243    unsigned char ch, *p1, *p2, *b1, *b2;
     244    off_t byte, length, line;
     245    int dfound;
     246    size_t blk_sz, blk_cnt;
     247
     248    if (sflag && len1 != len2)
     249        return DIFF_EXIT;
     250
     251    if (skip1 > len1)
     252        return eofmsg(file1, len1 + 1, 0, sflag, lflag);
     253    len1 -= skip1;
     254    if (skip2 > len2)
     255        return eofmsg(file2, len2 + 1, 0, sflag, lflag);
     256    len2 -= skip2;
     257
     258    byte = line = 1;
     259    dfound = 0;
     260    length = len1 <= len2 ? len1 : len2;
     261    for (blk_sz = 1024 * 1024; length != 0; length -= blk_sz)
     262    {
     263        if (blk_sz > length)
     264            blk_sz = length;
     265        b1 = p1 = mmap(NULL, blk_sz, PROT_READ, MAP_FILE | MAP_SHARED, fd1, skip1);
     266        if (p1 == MAP_FAILED)
     267            goto l_mmap_failed;
     268
     269        b2 = p2 = mmap(NULL, blk_sz, PROT_READ, MAP_FILE | MAP_SHARED, fd2, skip2);
     270        if (p2 == MAP_FAILED)
     271        {
     272            munmap(p1, blk_sz);
     273            goto l_mmap_failed;
     274        }
     275
     276        blk_cnt = blk_sz;
     277        for (; blk_cnt--; ++p1, ++p2, ++byte)
     278        {
     279            if ((ch = *p1) != *p2)
     280            {
     281                if (!lflag)
     282                {
     283                    munmap(b1, blk_sz);
     284                    munmap(b2, blk_sz);
     285                    return diffmsg(file1, file2, byte, line, sflag);
     286                }
     287                dfound = 1;
     288#ifdef _MSC_VER
     289                printf("%6I64d %3o %3o\n", (__int64)byte, ch, *p2);
     290#else
     291                printf("%6lld %3o %3o\n", (long long)byte, ch, *p2);
     292#endif
     293            }
     294            if (ch == '\n')
     295                ++line;
     296        }
     297        munmap(p1 - blk_sz, blk_sz);
     298        munmap(p2 - blk_sz, blk_sz);
     299        skip1 += blk_sz;
     300        skip2 += blk_sz;
     301    }
     302
     303    if (len1 != len2)
     304        return eofmsg(len1 > len2 ? file2 : file1, byte, line, sflag, lflag);
     305    if (dfound)
     306        return DIFF_EXIT;
     307    return OK_EXIT;
     308
     309l_mmap_failed:
     310    return c_special(fd1, file1, skip1, fd2, file2, skip2, lflag, sflag);
     311}
     312
     313#else /* non-mmap c_regular: */
     314
     315/**
     316 * Compare two files without mmaping them.
     317 */
     318static int
     319c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
     320          int fd2, const char *file2, off_t skip2, off_t len2, int sflag, int lflag)
     321{
     322    unsigned char ch, *p1, *p2, *b1 = 0, *b2 = 0;
     323    off_t byte, length, line, bytes_read;
     324    int dfound;
     325    size_t blk_sz, blk_cnt;
     326
     327    if (sflag && len1 != len2)
     328        return DIFF_EXIT;
     329
     330    if (skip1 > len1)
     331        return eofmsg(file1, len1 + 1, 0, sflag, lflag);
     332    len1 -= skip1;
     333    if (skip2 > len2)
     334        return eofmsg(file2, len2 + 1, 0, sflag, lflag);
     335    len2 -= skip2;
     336
     337    if (skip1 && lseek(fd1, skip1, SEEK_SET) < 0)
     338        goto l_special;
     339    if (skip2 && lseek(fd2, skip2, SEEK_SET) < 0)
     340    {
     341        if (skip1 && lseek(fd1, 0, SEEK_SET) < 0)
     342            return err(1, "seek failed");
     343        goto l_special;
     344    }
     345
     346#define CMP_BUF_SIZE (128*1024)
     347
     348    b1 = malloc(CMP_BUF_SIZE);
     349    b2 = malloc(CMP_BUF_SIZE);
     350    if (!b1 || !b2)
     351        goto l_malloc_failed;
     352
     353    byte = line = 1;
     354    dfound = 0;
     355    length = len1;
     356    if (length > len2)
     357        length = len2;
     358    for (blk_sz = CMP_BUF_SIZE; length != 0; length -= blk_sz)
     359    {
     360        if ((off_t)blk_sz > length)
     361            blk_sz = length;
     362
     363        bytes_read = read(fd1, b1, blk_sz);
     364        if (bytes_read != blk_sz)
     365            goto l_read_error;
     366
     367        bytes_read = read(fd2, b2, blk_sz);
     368        if (bytes_read != blk_sz)
     369            goto l_read_error;
     370
     371        blk_cnt = blk_sz;
     372        p1 = b1;
     373        p2 = b2;
     374        for (; blk_cnt--; ++p1, ++p2, ++byte)
     375        {
     376            if ((ch = *p1) != *p2)
     377            {
     378                if (!lflag)
     379                {
     380                    free(b1);
     381                    free(b2);
     382                    return diffmsg(file1, file2, byte, line, sflag);
     383                }
     384                dfound = 1;
     385#ifdef _MSC_VER
     386                printf("%6I64d %3o %3o\n", (__int64)byte, ch, *p2);
     387#else
     388                printf("%6lld %3o %3o\n", (long long)byte, ch, *p2);
     389#endif
     390            }
     391            if (ch == '\n')
     392                ++line;
     393        }
     394        skip1 += blk_sz;
     395        skip2 += blk_sz;
     396    }
     397
     398    if (len1 != len2)
     399        return eofmsg(len1 > len2 ? file2 : file1, byte, line, sflag, lflag);
     400    if (dfound)
     401        return DIFF_EXIT;
     402    return OK_EXIT;
     403
     404l_read_error:
     405    if (    lseek(fd1, 0, SEEK_SET) < 0
     406        ||  lseek(fd2, 0, SEEK_SET) < 0)
     407    {
     408        err(1, "seek failed");
     409        free(b1);
     410        free(b2);
     411        return 1;
     412    }
     413l_malloc_failed:
     414    free(b1);
     415    free(b2);
     416l_special:
     417    return c_special(fd1, file1, skip1, fd2, file2, skip2, lflag, sflag);
     418}
     419#endif  /* non-mmap c_regular */
     420
     421
     422/**
     423 * Compares two open files.
     424 */
    99425int
    100 kmk_builtin_cmp(int argc, char *argv[], char **envp)
    101 {
    102         struct stat sb1, sb2;
    103         off_t skip1 = 0, skip2 = 0;
    104         int ch, fd1, fd2, special;
    105         char *file1, *file2;
    106         int rc;
    107 
    108 #ifdef kmk_builtin_cmp
    109         setlocale(LC_ALL, "");
    110 #endif
    111         /* init globals */
    112         lflag = sflag = 0;
    113 
    114         /* reset getopt and set progname. */
    115         g_progname = argv[0];
    116         opterr = 1;
    117         optarg = NULL;
    118         optopt = 0;
    119         optind = 0; /* init */
    120 
    121         while ((ch = getopt_long(argc, argv, "ls", long_options, NULL)) != -1)
    122                 switch (ch) {
    123                 case 'l':               /* print all differences */
    124                         lflag = 1;
    125                         break;
    126                 case 's':               /* silent run */
    127                         sflag = 1;
    128                         break;
    129                 case 261:
    130                         usage(stdout);
    131                         return 0;
    132                 case 262:
    133                         return kbuild_version(argv[0]);
    134                 case '?':
    135                 default:
    136                         return usage(stderr);
    137                 }
    138         argv += optind;
    139         argc -= optind;
    140 
    141         if (lflag && sflag)
    142                 return errx(ERR_EXIT, "only one of -l and -s may be specified");
    143 
    144         if (argc < 2 || argc > 4)
    145                 return usage(stderr);
    146 
    147         /* Backward compatibility -- handle "-" meaning stdin. */
    148         special = 0;
    149         if (strcmp(file1 = argv[0], "-") == 0) {
    150                 special = 1;
    151                 fd1 = 0;
    152                 file1 = "stdin";
    153         }
    154         else if ((fd1 = open(file1, O_RDONLY | O_BINARY, 0)) < 0) {
    155                 if (!sflag)
    156                         warn("%s", file1);
    157                 return(ERR_EXIT);
    158         }
    159         if (strcmp(file2 = argv[1], "-") == 0) {
    160                 if (special)
    161                         return errx(ERR_EXIT,
    162                                 "standard input may only be specified once");
    163                 special = 1;
    164                 fd2 = 0;
    165                 file2 = "stdin";
    166         }
    167         else if ((fd2 = open(file2, O_RDONLY | O_BINARY, 0)) < 0) {
    168                 if (!sflag)
    169                         warn("%s", file2);
    170                 if (fd1 != 0) close(fd1);
    171                 return(ERR_EXIT);
    172         }
    173 
    174         if (argc > 2) {
    175                 char *ep;
    176 
    177                 errno = 0;
    178                 skip1 = strtoll(argv[2], &ep, 0);
    179                 if (errno || ep == argv[2]) {
    180                         rc = usage(stderr);
    181                         goto l_exit;
    182                 }
    183 
    184                 if (argc == 4) {
    185                         skip2 = strtoll(argv[3], &ep, 0);
    186                         if (errno || ep == argv[3]) {
    187                                 rc = usage(stderr);
    188                                 goto l_exit;
    189                         }
    190                 }
    191         }
    192 
    193         if (!special) {
    194                 if (fstat(fd1, &sb1)) {
    195                         rc = err(ERR_EXIT, "%s", file1);
    196                         goto l_exit;
    197                 }
    198                 if (!S_ISREG(sb1.st_mode))
    199                         special = 1;
    200                 else {
    201                         if (fstat(fd2, &sb2)) {
    202                                 rc = err(ERR_EXIT, "%s", file2);
    203                                 goto l_exit;
    204                         }
    205                         if (!S_ISREG(sb2.st_mode))
    206                                 special = 1;
    207                 }
    208         }
    209 
    210         if (special)
    211                 rc = c_special(fd1, file1, skip1, fd2, file2, skip2);
    212         else
    213                 rc = c_regular(fd1, file1, skip1, sb1.st_size,
    214                     fd2, file2, skip2, sb2.st_size);
    215 l_exit:
    216         if (fd1 != 0) close(fd1);
    217         if (fd2 != 0) close(fd2);
    218         return rc;
    219 }
    220 
    221 static int
    222 usage(FILE *fp)
    223 {
    224     fprintf(fp, "usage: %s [-l | -s] file1 file2 [skip1 [skip2]]\n"
    225                                 "   or: %s --help\n"
    226                                 "   or: %s --version\n",
    227                         g_progname, g_progname, g_progname);
    228         return(ERR_EXIT);
    229 }
     426cmp_fd_and_fd_ex(int fd1, const char *file1, off_t skip1,
     427                 int fd2, const char *file2, off_t skip2,
     428                 int sflag, int lflag, int special)
     429{
     430    struct stat st1, st2;
     431    int rc;
     432
     433    if (fstat(fd1, &st1))
     434        return err(ERR_EXIT, "%s", file1);
     435    if (fstat(fd2, &st2))
     436        return err(ERR_EXIT, "%s", file2);
     437
     438    if (    !S_ISREG(st1.st_mode)
     439        ||  !S_ISREG(st2.st_mode)
     440        ||  special)
     441        rc = c_special(fd1, file1, skip1,
     442                       fd2, file2, skip2, sflag, lflag);
     443    else
     444        rc = c_regular(fd1, file1, skip1, st1.st_size,
     445                       fd2, file2, skip2, st2.st_size, sflag, lflag);
     446    return rc;
     447}
     448
     449
     450/**
     451 * Compares two open files.
     452 */
     453int
     454cmp_fd_and_fd(int fd1, const char *file1,
     455              int fd2, const char *file2,
     456              int sflag, int lflag, int special)
     457{
     458    return cmp_fd_and_fd_ex(fd1, file1, 0, fd2, file2, 0, sflag, lflag, special);
     459}
     460
     461
     462/**
     463 * Compares an open file with another that isn't open yet.
     464 */
     465int
     466cmp_fd_and_file_ex(int fd1, const char *file1, off_t skip1,
     467                   const char *file2, off_t skip2,
     468                   int sflag, int lflag, int special)
     469{
     470    int rc;
     471    int fd2;
     472
     473    if (!strcmp(file2, "-"))
     474    {
     475        fd2 = 0 /* stdin */;
     476        special = 1;
     477        file2 = "stdin";
     478    }
     479    else
     480        fd2 = open(file2, O_RDONLY | O_BINARY, 0);
     481    if (fd2 >= 0)
     482    {
     483        rc = cmp_fd_and_fd_ex(fd1, file1, skip1,
     484                              fd2, file2, skip2, sflag, lflag, special);
     485        close(fd2);
     486    }
     487    else
     488    {
     489        if (!sflag)
     490            warn("%s", file2);
     491        rc = ERR_EXIT;
     492    }
     493    return rc;
     494}
     495
     496
     497/**
     498 * Compares an open file with another that isn't open yet.
     499 */
     500int
     501cmp_fd_and_file(int fd1, const char *file1,
     502                const char *file2,
     503                int sflag, int lflag, int special)
     504{
     505    return cmp_fd_and_file_ex(fd1, file1, 0,
     506                                   file2, 0, sflag, lflag, special);
     507}
     508
     509
     510/**
     511 * Opens and compare two files.
     512 */
     513int
     514cmp_file_and_file_ex(const char *file1, off_t skip1,
     515                     const char *file2, off_t skip2,
     516                     int sflag, int lflag, int special)
     517{
     518    int fd1;
     519    int rc;
     520
     521    if (lflag && sflag)
     522        return errx(ERR_EXIT, "only one of -l and -s may be specified");
     523
     524    if (!strcmp(file1, "-"))
     525    {
     526        if (!strcmp(file2, "-"))
     527            return errx(ERR_EXIT, "standard input may only be specified once");
     528        file1 = "stdin";
     529        fd1 = 1;
     530        special = 1;
     531    }
     532    else
     533        fd1 = open(file1, O_RDONLY | O_BINARY, 0);
     534    if (fd1 >= 0)
     535    {
     536        rc = cmp_fd_and_file_ex(fd1, file1, skip1,
     537                                     file2, skip2, sflag, lflag, special);
     538        close(fd1);
     539    }
     540    else
     541    {
     542        if (!sflag)
     543            warn("%s", file1);
     544        rc = ERR_EXIT;
     545    }
     546
     547    return rc;
     548}
     549
     550
     551/**
     552 * Opens and compare two files.
     553 */
     554int
     555cmp_file_and_file(const char *file1, const char *file2, int sflag, int lflag, int special)
     556{
     557    return cmp_file_and_file_ex(file1, 0, file2, 0, sflag, lflag, special);
     558}
     559
  • trunk/src/kmk/kmkbuiltin/cp.c

    r1287 r1309  
    363363                return err(1, "fts_open");
    364364        for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) {
     365                int copied = 0;
     366
    365367                switch (curr->fts_info) {
    366368                case FTS_NS:
     
    511513                            ((fts_options & FTS_COMFOLLOW) &&
    512514                            curr->fts_level == 0)) {
    513                                 if (copy_file(curr, dne))
     515                                if (copy_file(curr, dne, cp_changed_only, &copied))
    514516                                        badcp = rval = 1;
    515517                        } else {
     
    558560                                        badcp = rval = 1;
    559561                        } else {
    560                                 if (copy_file(curr, dne))
     562                                if (copy_file(curr, dne, cp_changed_only, &copied))
    561563                                        badcp = rval = 1;
    562564                        }
     
    569571                                        badcp = rval = 1;
    570572                        } else {
    571                                 if (copy_file(curr, dne))
     573                                if (copy_file(curr, dne, cp_changed_only, &copied))
    572574                                        badcp = rval = 1;
    573575                        }
    574576                        break;
    575577                default:
    576                         if (copy_file(curr, dne))
     578                        if (copy_file(curr, dne, cp_changed_only, &copied))
    577579                                badcp = rval = 1;
    578580                        break;
    579581                }
    580582                if (vflag && !badcp)
    581                         (void)printf("%s -> %s\n", curr->fts_path, to.p_path);
     583                        (void)printf(copied ? "%s -> %s\n" : "%s matches %s - not copied\n",
     584                                     curr->fts_path, to.p_path);
    582585        }
    583586        if (errno)
  • trunk/src/kmk/kmkbuiltin/cp_extern.h

    r1183 r1309  
    5454
    5555int     copy_fifo(struct stat *, int);
    56 int     copy_file(const FTSENT *, int);
     56int     copy_file(const FTSENT *, int, int, int *);
    5757int     copy_link(const FTSENT *, int);
    5858int     copy_special(struct stat *, int);
  • trunk/src/kmk/kmkbuiltin/cp_utils.c

    r1192 r1309  
    5454#include <sysexits.h>
    5555#include <unistd.h>
    56 
    5756#ifdef __sun__
    5857# include "solfakes.h"
    5958#endif
    6059#ifdef _MSC_VER
     60# define MSC_DO_64_BIT_IO
    6161# include "mscfakes.h"
    6262#endif
    63 
    6463#include "cp_extern.h"
     64#include "cmp_extern.h"
     65
    6566#define cp_pct(x,y)     (int)(100.0 * (double)(x) / (double)(y))
    6667
     
    7677#endif
    7778
    78 int
    79 copy_file(const FTSENT *entp, int dne)
     79
     80int
     81copy_file(const FTSENT *entp, int dne, int changed_only, int *pcopied)
    8082{
    8183        static char buf[MAXBSIZE];
     
    9092#endif
    9193
     94        *pcopied = 0;
     95
    9296        if ((from_fd = open(entp->fts_path, O_RDONLY | O_BINARY, 0)) == -1) {
    9397                warn("%s", entp->fts_path);
     
    106110         */
    107111        if (!dne) {
     112                /* compare the files first if requested */
     113                if (    changed_only
     114                    &&  cmp_fd_and_file(from_fd, entp->fts_path, to.p_path,
     115                                        1 /* silent */, 0 /* lflag */,
     116                                        0 /* special */)
     117                        == OK_EXIT) {
     118                        return (0);
     119                }
     120
    108121#define YESNO "(y/n [n]) "
    109122                if (nflag) {
     
    144157
    145158        rval = 0;
     159        *pcopied = 1;
    146160
    147161        /*
  • trunk/src/kmk/kmkbuiltin/err.h

    r785 r1309  
    2323 */
    2424
    25 #ifndef __err_h__
    26 #define __err_h__
     25#ifndef ___err_h
     26#define ___err_h
    2727
    2828extern const char *g_progname;
  • trunk/src/kmk/kmkbuiltin/mscfakes.h

    r1292 r1309  
    3535#undef setmode
    3636#include "getopt.h"
     37
     38#if defined(MSC_DO_64_BIT_IO) && _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */
     39# define off_t __int64
     40# define stat  _stat64
     41# define fstat _fstat64
     42# define lseek _lseeki64
     43#endif
     44
    3745
    3846#define S_ISDIR(m)  (((m) & _S_IFMT) == _S_IFDIR)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette