Fix T40157: Loading movies larger than 4GB in size fails

Issue was caused by _wstat returning EOVERFLOW error because
of file size didn't fit into stat structure which was using
long datatype.

The idea of this patch is to use _wstat64 and _stat64 structure
which is capable storing 64bit file sizes.

Made it a typedef for stat structure used by BLI_stat function
in order to make code easier to follow and avoid ifdefs all
over the place.

Additionally solved issue with BLI_exists which was wrongly
returning False in cases destination file is larger then 4GB.
This commit is contained in:
Sergey Sharybin 2014-05-28 22:50:40 +06:00
parent 74cc3974fe
commit 973f95fa9d
9 changed files with 27 additions and 16 deletions

@ -210,7 +210,7 @@ static int findFileRecursive(char *filename_new,
/* file searching stuff */ /* file searching stuff */
DIR *dir; DIR *dir;
struct dirent *de; struct dirent *de;
struct stat status; BLI_stat_t status;
char path[FILE_MAX]; char path[FILE_MAX];
int size; int size;
bool found = false; bool found = false;

@ -368,7 +368,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
int checkPackedFile(const char *filename, PackedFile *pf) int checkPackedFile(const char *filename, PackedFile *pf)
{ {
struct stat st; BLI_stat_t st;
int ret_val, i, len, file; int ret_val, i, len, file;
char buf[4096]; char buf[4096];
char name[FILE_MAX]; char name[FILE_MAX];

@ -667,7 +667,7 @@ void BKE_text_write(Text *text, const char *str) /* called directly from rna */
int BKE_text_file_modified_check(Text *text) int BKE_text_file_modified_check(Text *text)
{ {
struct stat st; BLI_stat_t st;
int result; int result;
char file[FILE_MAX]; char file[FILE_MAX];
@ -696,7 +696,7 @@ int BKE_text_file_modified_check(Text *text)
void BKE_text_file_modified_ignore(Text *text) void BKE_text_file_modified_ignore(Text *text)
{ {
struct stat st; BLI_stat_t st;
int result; int result;
char file[FILE_MAX]; char file[FILE_MAX];

@ -59,7 +59,18 @@ int BLI_rename(const char *from, const char *to);
int BLI_delete(const char *path, bool dir, bool recursive); int BLI_delete(const char *path, bool dir, bool recursive);
int BLI_move(const char *path, const char *to); int BLI_move(const char *path, const char *to);
int BLI_create_symlink(const char *path, const char *to); int BLI_create_symlink(const char *path, const char *to);
int BLI_stat(const char *path, struct stat *buffer);
#ifdef WIN32
# ifndef __MINGW64__
typedef struct _stat64 BLI_stat_t;
# else
typedef struct stat BLI_stat_t;
#endif
#else
typedef struct stat BLI_stat_t;
#endif
int BLI_stat(const char *path, BLI_stat_t *buffer);
/* Directories */ /* Directories */

@ -460,7 +460,7 @@ size_t BLI_file_descriptor_size(int file)
*/ */
size_t BLI_file_size(const char *path) size_t BLI_file_size(const char *path)
{ {
struct stat stats; BLI_stat_t stats;
if (BLI_stat(path, &stats) == -1) if (BLI_stat(path, &stats) == -1)
return -1; return -1;
return stats.st_size; return stats.st_size;
@ -474,7 +474,7 @@ int BLI_exists(const char *name)
{ {
#if defined(WIN32) #if defined(WIN32)
#ifndef __MINGW32__ #ifndef __MINGW32__
struct _stat64i32 st; struct _stat64 st;
#else #else
struct _stati64 st; struct _stati64 st;
#endif #endif
@ -507,7 +507,7 @@ int BLI_exists(const char *name)
old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#ifndef __MINGW32__ #ifndef __MINGW32__
res = _wstat(tmp_16, &st); res = _wstat64(tmp_16, &st);
#else #else
res = _wstati64(tmp_16, &st); res = _wstati64(tmp_16, &st);
#endif #endif
@ -525,14 +525,14 @@ int BLI_exists(const char *name)
#ifdef WIN32 #ifdef WIN32
int BLI_stat(const char *path, struct stat *buffer) int BLI_stat(const char *path, BLI_stat_t *buffer)
{ {
int r; int r;
UTF16_ENCODE(path); UTF16_ENCODE(path);
/* workaround error in MinGW64 headers, normally, a wstat should work */ /* workaround error in MinGW64 headers, normally, a wstat should work */
#ifndef __MINGW64__ #ifndef __MINGW64__
r = _wstat(path_16, buffer); r = _wstat64(path_16, buffer);
#else #else
r = _wstati64(path_16, buffer); r = _wstati64(path_16, buffer);
#endif #endif

@ -656,7 +656,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
} }
else { else {
char path[FILE_MAX]; char path[FILE_MAX];
struct stat status; BLI_stat_t status;
BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);

@ -458,7 +458,7 @@ static void txt_write_file(Text *text, ReportList *reports)
{ {
FILE *fp; FILE *fp;
TextLine *tmp; TextLine *tmp;
struct stat st; BLI_stat_t st;
char filepath[FILE_MAX]; char filepath[FILE_MAX];
BLI_strncpy(filepath, text->name, FILE_MAX); BLI_strncpy(filepath, text->name, FILE_MAX);

@ -305,7 +305,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
short tsize = 128; short tsize = 128;
short ex, ey; short ex, ey;
float scaledx, scaledy; float scaledx, scaledy;
struct stat info; BLI_stat_t info;
switch (size) { switch (size) {
case THB_NORMAL: case THB_NORMAL:
@ -472,7 +472,7 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
{ {
char thumb[FILE_MAX]; char thumb[FILE_MAX];
char uri[URI_MAX]; char uri[URI_MAX];
struct stat st; BLI_stat_t st;
ImBuf *img = NULL; ImBuf *img = NULL;
if (BLI_stat(path, &st)) { if (BLI_stat(path, &st)) {

@ -187,7 +187,7 @@ int IMB_ispic_type(const char *name)
unsigned char buf[HEADER_SIZE]; unsigned char buf[HEADER_SIZE];
ImFileType *type; ImFileType *type;
struct stat st; BLI_stat_t st;
int fp; int fp;
if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name); if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
@ -391,7 +391,7 @@ static int isredcode(const char *filename)
int imb_get_anim_type(const char *name) int imb_get_anim_type(const char *name)
{ {
int type; int type;
struct stat st; BLI_stat_t st;
if (UTIL_DEBUG) printf("in getanimtype: %s\n", name); if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);