Hello,
I have two files F1 and F2 (4.5Gb each) that i try to compare using cmp and
diff. They can be created with a Makefile as follows:

all: F1 F2
        -cmp -lb F1 F2
        -diff F1 F2
F1: l1 M100 G1
        #cat M100 l1 M100 M100 G1 G1 l1 G1 G1 > $@
        cat M100 M100 l1 M100 M100 M100 G1 G1 l1 G1 G1 > $@
F2: l2 M100 G1
        #cat M100 l2 M100 M100 G1 G1 l2 G1 G1 > $@
        cat M100 M100 l2 M100 M100 M100 G1 G1 l2 G1 G1 > $@
l1:
        echo "abc" > $@
l2:
        echo "xyz" > $@
G1: M100
        cat $+ $+ $+ $+ $+ $+ $+ $+ $+ $+ > $@
M100: M50
        cat $+ $+ > $@
M50: M5
        cat $+ $+ $+ $+ $+ $+ $+ $+ $+ $+ > $@
M5: k500
        cat $+ $+ $+ $+ $+ $+ $+ $+ $+ $+ > $@
k500: k50
        cat $+ $+ $+ $+ $+ $+ $+ $+ $+ $+ > $@
k50: k5
        cat $+ $+ $+ $+ $+ $+ $+ $+ $+ $+ > $@
k5:
        echo `seq 1001 2000` > $@
clean:
        -rm -f F1 F2 l1 l2
        -rm -f G1 M100 M50 M5 k500 k50 k5

Output is:

% make
cmp -lb F1 F2
 200000001 141 a    170 x
 200000002 142 b    171 y
 200000003 143 c    172 z
2500000005 141 a    170 x
2500000006 142 b    171 y
2500000007 143 c    172 z
diff F1 F2
40001c40001
< abc
---
> xyz
%

That is: cmp is correct but diff is missing the second set of differences.

After a look into the block_read() function in lib/cmpbuf.c in diffutils
source code (3.12), i come back with the simple.c program below:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  int fd;
  if ((fd = open(argv[1], O_RDONLY)) == -1) {
    perror("open failed");
    return(1);
  };
  struct stat s;
  if (fstat(fd, &s) == -1) {
    perror("stat failed");
    return(1);
  };
  size_t toread = s.st_size;
  size_t bufsize = toread;
  char *buf;
  if ((buf = malloc(bufsize)) == nullptr) {
    perror("malloc failed");
    return(1);
  };
  while (1) {
    size_t nread;
    if ((nread = read(fd, buf, toread)) > 0) {
      printf("read %zd bytes\n", nread);
      toread -= nread;
    } else {
      if (nread == -1) {
        perror("read failed");
      } else {
        printf("read() reached EOF\n");
      };
      break;
    };
  };
  close(fd);
  //sleep(1000);
  return(0);
};


When run on F1, the program displays:
% ./simple F1
read 205032712 bytes
read() reached EOF
%

and the last 2^32 bytes of the file have disappeared.

My analysis:
ssize_t read(int fildes, void *buf, size_t nbyte) seems to kill the
bits of nbyte that are over 32. Hence the premature EOF in this case.
Also malloc() seems strange because (with an appropriate sleep() near
the end) the Windows TaskManager shows 200Mb rather than 4Gb.

Any ideas?

I'm using cygwin1.dll from 3.7.0-0.579.g61b4866baf41.x86_64 as reported
by uname -a.

Regards,
Denis Excoffier.

















































































































-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to