| diff --git a/CMakeLists.txt b/CMakeLists.txt |
| index 6f1a97e..664d3f4 100644 |
| --- a/CMakeLists.txt |
| +++ b/CMakeLists.txt |
| @@ -91,6 +91,10 @@ FUNCTION(TARGET_OS_LIBRARIES target) |
| TARGET_LINK_LIBRARIES(${target} rt) |
| SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} -lrt" PARENT_SCOPE) |
| ENDIF() |
| + IF("$ENV{NACL_LIBC}" STREQUAL "newlib") |
| + TARGET_LINK_LIBRARIES(${target} glibc-compat) |
| + SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} -lglibc-compat" PARENT_SCOPE) |
| + ENDIF() |
| |
| IF(THREADSAFE) |
| TARGET_LINK_LIBRARIES(${target} ${CMAKE_THREAD_LIBS_INIT}) |
| @@ -364,6 +368,8 @@ FILE(GLOB SRC_H include/git2.h include/git2/*.h include/git2/sys/*.h) |
| IF (WIN32 AND NOT CYGWIN) |
| ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501) |
| FILE(GLOB SRC_OS src/win32/*.c src/win32/*.h) |
| +ELSEIF (NACL) |
| + ADD_DEFINITIONS(-DNO_MMAP) |
| ELSEIF (AMIGA) |
| ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP) |
| ELSE() |
| diff --git a/src/pool.c b/src/pool.c |
| index a516ff9..b1c2bfe 100644 |
| --- a/src/pool.c |
| +++ b/src/pool.c |
| @@ -312,7 +312,7 @@ uint32_t git_pool__system_page_size(void) |
| #elif defined(__amigaos4__) |
| size = (uint32_t)4096; /* 4K as there is no global value we can query */ |
| #else |
| - size = (uint32_t)sysconf(_SC_PAGE_SIZE); |
| + size = (uint32_t)sysconf(_SC_PAGESIZE); |
| #endif |
| |
| size -= 2 * sizeof(void *); /* allow space for malloc overhead */ |
| diff --git a/src/posix.h b/src/posix.h |
| index 965cd98..eb93cde 100644 |
| --- a/src/posix.h |
| +++ b/src/posix.h |
| @@ -12,6 +12,10 @@ |
| #include <time.h> |
| #include "fnmatch.h" |
| |
| +#if defined(__native_client__) && defined(_NEWLIB_VERSION) |
| +mode_t umask(mode_t cmask); |
| +#endif |
| + |
| #ifndef S_IFGITLINK |
| #define S_IFGITLINK 0160000 |
| #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK) |
| diff --git a/tests/clar.c b/tests/clar.c |
| index 1546447..839f7f3 100644 |
| --- a/tests/clar.c |
| +++ b/tests/clar.c |
| @@ -222,7 +222,7 @@ static void |
| clar_run_suite(const struct clar_suite *suite, const char *filter) |
| { |
| const struct clar_func *test = suite->tests; |
| - size_t i, matchlen; |
| + size_t i, matchlen = 0; |
| |
| if (!suite->enabled) |
| return; |
| diff --git a/tests/clar/fs.h b/tests/clar/fs.h |
| index 7c7dde6..e37aec1 100644 |
| --- a/tests/clar/fs.h |
| +++ b/tests/clar/fs.h |
| @@ -250,6 +250,249 @@ cl_fs_cleanup(void) |
| fs_rm(fixture_path(_clar_path, "*")); |
| } |
| |
| +#elif defined(__native_client__) |
| + |
| +#include <dirent.h> |
| +#include <errno.h> |
| +#include <limits.h> |
| +#include <sys/stat.h> |
| + |
| +static int fs_copy_helper(const char* source, const char* dest); |
| + |
| +static int fs_copy_dir(const char* source, const char* dest) { |
| + DIR* src_dir = opendir(source); |
| + struct dirent* dirent_buf = malloc(sizeof(struct dirent)); |
| + struct dirent* dir_entry = NULL; |
| + int result = 1; |
| + |
| + if (src_dir == NULL) { |
| + fprintf(stderr, "Error opening directory %s: %s\n", |
| + source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + // Create the destination directory. |
| + if (mkdir(dest, 0700) != 0) { |
| + if (errno != EEXIST) { |
| + fprintf(stderr, "Error creating directory %s: %s\n", |
| + dest, strerror(errno)); |
| + goto error; |
| + } |
| + } |
| + |
| + while (1) { |
| + char src_entry_path[PATH_MAX]; |
| + char dst_entry_path[PATH_MAX]; |
| + const char* entry_name; |
| + |
| + if (readdir_r(src_dir, dirent_buf, &dir_entry) != 0) { |
| + fprintf(stderr, "Error reading directory %s: %s\n", |
| + source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + if (dir_entry == NULL) { |
| + break; |
| + } |
| + |
| + entry_name = dir_entry->d_name; |
| + |
| + if (strcmp(entry_name, ".") == 0 || strcmp(entry_name, "..") == 0) |
| + continue; |
| + |
| + snprintf(&src_entry_path[0], PATH_MAX, "%s/%s", source, entry_name); |
| + snprintf(&dst_entry_path[0], PATH_MAX, "%s/%s", dest, entry_name); |
| + |
| + if (!fs_copy_helper(src_entry_path, dst_entry_path)) { |
| + goto error; |
| + } |
| + } |
| + |
| + goto cleanup; |
| + |
| +error: |
| + result = 0; |
| + |
| +cleanup: |
| + closedir(src_dir); |
| + return result; |
| +} |
| + |
| +static int fs_copy_file(const char* source, const char* dest) { |
| + const size_t buffer_size = 8192; |
| + char buffer[buffer_size]; |
| + int result = 1; |
| + FILE* dst_file = NULL; |
| + |
| + FILE* src_file = fopen(source, "r"); |
| + if (src_file == NULL) { |
| + fprintf(stderr, "Error opening file %s for reading: %s\n", |
| + source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + dst_file = fopen(dest, "w"); |
| + if (dst_file == NULL) { |
| + fprintf(stderr, "Error opening file %s for writing: %s\n", |
| + dest, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + while (!feof(src_file)) { |
| + ssize_t bytes_read = fread(&buffer[0], 1, buffer_size, src_file); |
| + ssize_t bytes_written; |
| + if (bytes_read < 0) { |
| + fprintf(stderr, "Unable to read from %s: %s\n", source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + bytes_written = fwrite(&buffer[0], 1, bytes_read, dst_file); |
| + if (bytes_written != bytes_read) { |
| + fprintf(stderr, "Unable to write %d bytes of %s to %s: %s\n", |
| + bytes_read, source, dest, strerror(errno)); |
| + goto error; |
| + } |
| + } |
| + |
| + goto cleanup; |
| + |
| +error: |
| + result = 0; |
| + |
| +cleanup: |
| + if (src_file) |
| + fclose(src_file); |
| + |
| + if (dst_file) |
| + fclose(dst_file); |
| + |
| + return result; |
| +} |
| + |
| +static int fs_copy_helper(const char *source, const char *dest) { |
| + struct stat statbuf; |
| + if (stat(source, &statbuf) != 0) { |
| + fprintf(stderr, "Error stat'ing file %s: %s\n", source, strerror(errno)); |
| + return 0; |
| + } |
| + |
| + if (S_ISDIR(statbuf.st_mode)) { |
| + if (!fs_copy_dir(source, dest)) |
| + return 0; |
| + } else { |
| + if (!fs_copy_file(source, dest)) |
| + return 0; |
| + } |
| + |
| + return 1; |
| +} |
| + |
| + |
| +static void fs_copy(const char *source, const char *dest) { |
| + char real_dest[PATH_MAX]; |
| + char* last_slash = NULL; |
| + |
| + // Copy the base directory name of source to dest. |
| + // e.g. fs_copy("foo/bar/baz", "/tmp/blah") creates "/tmp/blah/baz". |
| + |
| + last_slash = strrchr(source, '/'); |
| + if (last_slash != NULL) { |
| + snprintf(real_dest, PATH_MAX, "%s/%s", dest, last_slash + 1); |
| + } else { |
| + strncpy(real_dest, dest, PATH_MAX); |
| + } |
| + |
| + cl_must_pass_(fs_copy_helper(source, real_dest), |
| + "Failed to copy test fixtures to sandbox"); |
| +} |
| + |
| +static int fs_rm_helper(const char* source); |
| + |
| +static int fs_rm_dir(const char* source) { |
| + DIR* src_dir = opendir(source); |
| + struct dirent* dir_entry = NULL; |
| + int result = 1; |
| + |
| + if (src_dir == NULL) { |
| + fprintf(stderr, "Error opening directory %s: %s\n", |
| + source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + for (dir_entry = readdir(src_dir); dir_entry; dir_entry = readdir(src_dir)) { |
| + char src_entry_path[PATH_MAX]; |
| + const char* entry_name = dir_entry->d_name; |
| + |
| + if (strcmp(entry_name, ".") == 0 || strcmp(entry_name, "..") == 0) |
| + continue; |
| + |
| + snprintf(&src_entry_path[0], PATH_MAX, "%s/%s", source, entry_name); |
| + |
| + if (!fs_rm_helper(src_entry_path)) { |
| + goto error; |
| + } |
| + } |
| + |
| + // Finally, remove source. |
| + if (rmdir(source) != 0) { |
| + fprintf(stderr, "Error removing directory %s: %s\n", |
| + source, strerror(errno)); |
| + goto error; |
| + } |
| + |
| + goto cleanup; |
| + |
| +error: |
| + result = 0; |
| + |
| +cleanup: |
| + closedir(src_dir); |
| + return result; |
| +} |
| + |
| +static int fs_rm_file(const char* source) { |
| + if (unlink(source) != 0) { |
| + fprintf(stderr, "Error removing file %s: %s\n", source, strerror(errno)); |
| + return 0; |
| + } |
| + |
| + return 1; |
| +} |
| + |
| +static int fs_rm_helper(const char* source) { |
| + struct stat statbuf; |
| + if (lstat(source, &statbuf) != 0) { |
| + fprintf(stderr, "Error stat'ing file %s: %s\n", source, strerror(errno)); |
| + return 0; |
| + } |
| + |
| + if (S_ISDIR(statbuf.st_mode)) { |
| + if (!fs_rm_dir(source)) |
| + return 0; |
| + } else { |
| + if (!fs_rm_file(source)) |
| + return 0; |
| + } |
| + |
| + return 1; |
| +} |
| + |
| +static void |
| +fs_rm(const char *source) |
| +{ |
| + cl_must_pass_( |
| + fs_rm_helper(source), |
| + "Failed to cleanup the sandbox" |
| + ); |
| +} |
| + |
| +void |
| +cl_fs_cleanup(void) |
| +{ |
| + clar_unsandbox(); |
| + clar_sandbox(); |
| +} |
| + |
| #else |
| |
| #include <errno.h> |
| diff --git a/tests/clar/sandbox.h b/tests/clar/sandbox.h |
| index a44e291..a6aea62 100644 |
| --- a/tests/clar/sandbox.h |
| +++ b/tests/clar/sandbox.h |
| @@ -110,8 +110,21 @@ static int build_sandbox_path(void) |
| return -1; |
| #else |
| if (mkdtemp(_clar_path) == NULL) |
| +#if defined(__native_client__) |
| + { |
| + // Under sel_ldr mkdtemp currently always fails. For now |
| + // fake it. |
| + struct stat buf; |
| + strcpy(_clar_path + strlen(_clar_path) - 6, "123456"); |
| + if (stat(_clar_path, &buf) == 0) |
| + fs_rm(_clar_path); |
| + if (mkdir(_clar_path, 0700) != 0) |
| + return -1; |
| + } |
| +#else |
| return -1; |
| #endif |
| +#endif |
| |
| return 0; |
| } |
| diff --git a/tests/commit/parse.c b/tests/commit/parse.c |
| index 41e1624..f27bada 100644 |
| --- a/tests/commit/parse.c |
| +++ b/tests/commit/parse.c |
| @@ -119,8 +119,8 @@ passing_signature_test_case passing_signature_cases[] = { |
| {"author Vicent Marti <tanoku@gmail.com> 1234567890 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 1234567890, 0}, |
| {"author Vicent Marti <tanoku@gmail.com> 2147483647 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 0x7fffffff, 0}, |
| {"author Vicent Marti <tanoku@gmail.com> 4294967295 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 0xffffffff, 0}, |
| - {"author Vicent Marti <tanoku@gmail.com> 4294967296 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 4294967296, 0}, |
| - {"author Vicent Marti <tanoku@gmail.com> 8589934592 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 8589934592, 0}, |
| + {"author Vicent Marti <tanoku@gmail.com> 4294967296 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 4294967296ll, 0}, |
| + {"author Vicent Marti <tanoku@gmail.com> 8589934592 \n", "author ", "Vicent Marti", "tanoku@gmail.com", 8589934592ll, 0}, |
| |
| {NULL,NULL,NULL,NULL,0,0} |
| }; |
| diff --git a/tests/config/read.c b/tests/config/read.c |
| index 2567272..2db4b3d 100644 |
| --- a/tests/config/read.c |
| +++ b/tests/config/read.c |
| @@ -477,7 +477,7 @@ void test_config_read__simple_read_from_specific_level(void) |
| { |
| git_config *cfg, *cfg_specific; |
| int i; |
| - int64_t l, expected = +9223372036854775803; |
| + int64_t l, expected = +9223372036854775803ll; |
| const char *s; |
| |
| cl_git_pass(git_config_new(&cfg)); |
| diff --git a/tests/config/write.c b/tests/config/write.c |
| index 0f11ae8..675f7f4 100644 |
| --- a/tests/config/write.c |
| +++ b/tests/config/write.c |
| @@ -18,7 +18,7 @@ void test_config_write__replace_value(void) |
| { |
| git_config *cfg; |
| int i; |
| - int64_t l, expected = +9223372036854775803; |
| + int64_t l, expected = +9223372036854775803ll; |
| |
| /* By freeing the config, we make sure we flush the values */ |
| cl_git_pass(git_config_open_ondisk(&cfg, "config9")); |
| @@ -179,7 +179,7 @@ void test_config_write__add_value_at_specific_level(void) |
| { |
| git_config *cfg, *cfg_specific; |
| int i; |
| - int64_t l, expected = +9223372036854775803; |
| + int64_t l, expected = +9223372036854775803ll; |
| const char *s; |
| |
| // open config15 as global level config file |