mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 22:08:56 +00:00
Fix p_ftruncate to handle big files for git_clone
This commit is contained in:
parent
fb2f3a76aa
commit
7e9b21aa2a
@ -41,7 +41,7 @@ extern int p_chdir(const char* path);
|
||||
extern int p_chmod(const char* path, mode_t mode);
|
||||
extern int p_rmdir(const char* path);
|
||||
extern int p_access(const char* path, mode_t mode);
|
||||
extern int p_ftruncate(int fd, long size);
|
||||
extern int p_ftruncate(int fd, git_off_t size);
|
||||
|
||||
/* p_lstat is almost but not quite POSIX correct. Specifically, the use of
|
||||
* ENOTDIR is wrong, in that it does not mean precisely that a non-directory
|
||||
|
@ -42,12 +42,30 @@
|
||||
/* GetFinalPathNameByHandleW signature */
|
||||
typedef DWORD(WINAPI *PFGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
|
||||
|
||||
int p_ftruncate(int fd, long size)
|
||||
/**
|
||||
* Truncate or extend file.
|
||||
*
|
||||
* We now take a "git_off_t" rather than "long" because
|
||||
* files may be longer than 2Gb.
|
||||
*/
|
||||
int p_ftruncate(int fd, git_off_t size)
|
||||
{
|
||||
if (size < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
return _chsize_s(fd, size);
|
||||
return ((_chsize_s(fd, size) == 0) ? 0 : -1);
|
||||
#else
|
||||
return _chsize(fd, size);
|
||||
/* TODO Find a replacement for _chsize() that handles big files.
|
||||
* This comment is probably __MINGW32__ specific.
|
||||
*/
|
||||
if (size > INT32_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
return _chsize(fd, (long)size);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
48
tests/core/ftruncate.c
Normal file
48
tests/core/ftruncate.c
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Some tests for p_ftruncate() to ensure that
|
||||
* properly handles large (2Gb+) files.
|
||||
*/
|
||||
|
||||
#include "clar_libgit2.h"
|
||||
|
||||
static const char *filename = "core_ftruncate.txt";
|
||||
static int fd = -1;
|
||||
|
||||
void test_core_ftruncate__initialize(void)
|
||||
{
|
||||
if (!cl_getenv("GITTEST_INVASIVE_FS_SIZE"))
|
||||
cl_skip();
|
||||
|
||||
cl_must_pass((fd = p_open(filename, O_CREAT | O_RDWR, 0644)));
|
||||
}
|
||||
|
||||
void test_core_ftruncate__cleanup(void)
|
||||
{
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
p_close(fd);
|
||||
fd = 0;
|
||||
|
||||
p_unlink(filename);
|
||||
}
|
||||
|
||||
static void _extend(git_off_t i64len)
|
||||
{
|
||||
struct stat st;
|
||||
int error;
|
||||
|
||||
cl_assert((error = p_ftruncate(fd, i64len)) == 0);
|
||||
cl_assert((error = p_fstat(fd, &st)) == 0);
|
||||
cl_assert(st.st_size == i64len);
|
||||
}
|
||||
|
||||
void test_core_ftruncate__2gb(void)
|
||||
{
|
||||
_extend(0x80000001);
|
||||
}
|
||||
|
||||
void test_core_ftruncate__4gb(void)
|
||||
{
|
||||
_extend(0x100000001);
|
||||
}
|
Loading…
Reference in New Issue
Block a user