Added c_compare_file function plus a test function.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Klaas Freitag 2013-03-22 10:23:17 +01:00 committed by Andreas Schneider
parent b8cf6f7f5c
commit 9f7de96a73
3 changed files with 148 additions and 0 deletions

View file

@ -28,6 +28,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include "c_file.h" #include "c_file.h"
#include "c_string.h" #include "c_string.h"
@ -195,3 +196,84 @@ int c_rename( const char *src, const char *dst ) {
return rc; return rc;
} }
int c_compare_file( const char *f1, const char *f2 ) {
mbchar_t *wf1, *wf2;
int fd1 = -1, fd2 = -1;
size_t size1, size2;
char buffer1[BUFFER_SIZE];
char buffer2[BUFFER_SIZE];
csync_stat_t stat1;
csync_stat_t stat2;
int rc = -1;
if(f1 == NULL || f2 == NULL) return -1;
wf1 = c_utf8_to_locale(f1);
if(wf1 == NULL) {
return -1;
}
wf2 = c_utf8_to_locale(f2);
if(wf2 == NULL) {
return -1;
}
/* compare size first. */
rc = _tstat(wf1, &stat1);
if(rc< 0) {
goto out;
}
rc = _tstat(wf2, &stat2);
if(rc < 0) {
goto out;
}
/* if sizes are different, the files can not be equal. */
if( stat1.st_size != stat2.st_size ) {
rc = 0;
goto out;
}
#ifdef _WIN32
_fmode = _O_BINARY;
#endif
fd1 = _topen(wf1, O_RDONLY);
if(fd1 < 0) {
rc = -1;
goto out;
}
fd2 = _topen(wf2, O_RDONLY);
if(fd2 < 0) {
rc = -1;
goto out;
}
while( (size1 = read(fd1, buffer1, BUFFER_SIZE)) > 0 ) {
size2 = read( fd2, buffer2, BUFFER_SIZE );
if( size1 != size2 ) {
rc = 0;
goto out;
}
if(memcmp(buffer1, buffer2, size1) != 0) {
/* buffers are different */
rc = 0;
goto out;
}
}
rc = 1;
out:
if(fd1 > -1) close(fd1);
if(fd2 > -1) close(fd2);
c_free_locale_string( wf1 );
c_free_locale_string( wf2 );
return rc;
}

View file

@ -64,6 +64,16 @@ int c_isfile(const char *path);
*/ */
int c_copy(const char *src, const char *dst, mode_t mode); int c_copy(const char *src, const char *dst, mode_t mode);
/**
* @brief Compare the content of two files byte by byte.
* @param f1 Path of file 1
* @param f2 Path of file 2
*
* @return 0 if the files differ, 1 if the files are equal or -1 on
* error with errno set.
*/
int c_compare_file( const char *f1, const char *f2 );
/** /**
* @brief move a file from source to destination. * @brief move a file from source to destination.
* *

View file

@ -86,12 +86,68 @@ static void check_c_copy_isdir(void **state)
assert_int_equal(errno, EISDIR); assert_int_equal(errno, EISDIR);
} }
static void check_c_compare_file(void **state)
{
int rc;
(void) state;
rc = c_copy(check_src_file, check_dst_file, 0644);
assert_int_equal(rc, 0);
rc = c_compare_file( check_src_file, check_dst_file );
assert_int_equal(rc, 1);
/* Check error conditions */
rc = c_compare_file( NULL, check_dst_file );
assert_int_equal(rc, -1);
rc = c_compare_file( check_dst_file, NULL );
assert_int_equal(rc, -1);
rc = c_compare_file( NULL, NULL );
assert_int_equal(rc, -1);
rc = c_compare_file( check_src_file, "/I_do_not_exist_in_the_filesystem.dummy");
assert_int_equal(rc, -1);
rc = c_compare_file( "/I_do_not_exist_in_the_filesystem.dummy", check_dst_file);
assert_int_equal(rc, -1);
rc = system("echo \"hallo42\" > /tmp/check/foo.txt");
assert_int_equal(rc, 0);
rc = system("echo \"hallo52\" > /tmp/check/bar.txt");
assert_int_equal(rc, 0);
rc = c_compare_file( check_src_file, check_dst_file );
assert_int_equal(rc, 0);
/* Create two 1MB random files */
rc = system("dd if=/dev/urandom of=/tmp/check/foo.txt bs=1024 count=1024");
assert_int_equal(rc, 0);
rc = system("dd if=/dev/urandom of=/tmp/check/bar.txt bs=1024 count=1024");
assert_int_equal(rc, 0);
rc = c_compare_file( check_src_file, check_dst_file );
assert_int_equal(rc, 0);
/* Create two 1MB random files with different size */
rc = system("dd if=/dev/urandom of=/tmp/check/foo.txt bs=1024 count=1024");
assert_int_equal(rc, 0);
rc = system("dd if=/dev/urandom of=/tmp/check/bar.txt bs=1024 count=1020");
assert_int_equal(rc, 0);
rc = c_compare_file( check_src_file, check_dst_file );
assert_int_equal(rc, 0);
/* compare two big files which are equal */
rc = c_copy(check_src_file, check_dst_file, 0644);
assert_int_equal(rc, 0);
rc = c_compare_file( check_src_file, check_dst_file );
assert_int_equal(rc, 1);
}
int torture_run_tests(void) int torture_run_tests(void)
{ {
const UnitTest tests[] = { const UnitTest tests[] = {
unit_test_setup_teardown(check_c_copy, setup, teardown), unit_test_setup_teardown(check_c_copy, setup, teardown),
unit_test(check_c_copy_same_file), unit_test(check_c_copy_same_file),
unit_test_setup_teardown(check_c_copy_isdir, setup, teardown), unit_test_setup_teardown(check_c_copy_isdir, setup, teardown),
unit_test_setup_teardown(check_c_compare_file, setup, teardown),
}; };
return run_tests(tests); return run_tests(tests);