Re: [AD] bugfix for files > 2GB under unix |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On Mon, 2006-05-15 at 18:13 +0200, Elias Pschernig wrote:
> The attached patch allows the unix port to see files > 2GB - currently,
> all such files are silently ignored.
>
> The size is not returned correctly simply because 32-bit datatypes are
> used - I'd like to update those as well, but keeping in mind binary
> compatibility, maybe better to do so only for 4.3. For a video player,
> currently there would be no way to play e.g. any DVDs since the files
> are usually > 2GB. The patch fixes that.
>
Actually, providing wrong file sizes looks really broken, so here's now
a proper patch. To work around binary compatibility, I sneaked in an
extra size field into an internal struct, and provided an accessor
function. For file size, there's simply "uint64_t file_size_ex" now.
--
Elias Pschernig
Index: src/unix/ufile.c
===================================================================
--- src/unix/ufile.c (revision 5800)
+++ src/unix/ufile.c (working copy)
@@ -18,11 +18,16 @@
#include <stdio.h>
#include <string.h>
-#include <sys/stat.h>
#include "allegro.h"
#include "allegro/internal/aintern.h"
+#ifdef HAVE_SYS_STAT_H
+#ifdef HAVE_STAT64
+#define __USE_LARGEFILE64
+#endif
+#include <sys/stat.h>
+#endif
#ifdef HAVE_DIRENT_H
#include <sys/types.h>
@@ -53,6 +58,9 @@
#endif
#endif
+#ifdef HAVE_STAT64
+#define stat stat64
+#endif
/* _al_file_isok:
@@ -300,6 +308,7 @@
char dirname[FF_MAXPATHLEN];
char pattern[FF_MAXPATHLEN];
int attrib;
+ uint64_t size;
};
@@ -315,10 +324,18 @@
char tmp[1024];
char *p;
+ /* allocate ff_data structure */
+ ff_data = _AL_MALLOC(sizeof(struct FF_DATA));
+ if (!ff_data) {
+ *allegro_errno = ENOMEM;
+ return -1;
+ }
+
+ memset(ff_data, 0, sizeof *ff_data);
+ info->ff_data = (void *) ff_data;
+
/* if the pattern contains no wildcard, we use stat() */
if (!ustrpbrk(pattern, uconvert("?*", U_ASCII, tmp, U_CURRENT, sizeof(tmp)))) {
- info->ff_data = NULL;
-
/* start the search */
errno = *allegro_errno = 0;
@@ -330,28 +347,19 @@
if ((actual_attrib & ~attrib) == 0) {
info->attrib = actual_attrib;
info->time = s.st_mtime;
- info->size = s.st_size;
+ info->size = s.st_size; /* overflows at 2GB */
+ ff_data->size = s.st_size;
ustrzcpy(info->name, sizeof(info->name), get_filename(pattern));
return 0;
}
}
+ _AL_FREE(ff_data);
+ info->ff_data = NULL;
*allegro_errno = (errno ? errno : ENOENT);
return -1;
}
- /* allocate ff_data structure */
- ff_data = _AL_MALLOC(sizeof(struct FF_DATA));
-
- if (!ff_data) {
- *allegro_errno = ENOMEM;
- return -1;
- }
-
- /* attach it to the info structure */
- info->ff_data = (void *) ff_data;
-
- /* initialize it */
ff_data->attrib = attrib;
do_uconvert(pattern, U_CURRENT, ff_data->dirname, U_UTF8, sizeof(ff_data->dirname));
@@ -400,8 +408,10 @@
struct stat s;
struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
+ ASSERT(ff_data);
+
/* if the pattern contained no wildcard */
- if (!ff_data)
+ if (!ff_data->dir)
return -1;
while (TRUE) {
@@ -441,7 +451,8 @@
info->attrib = attrib;
info->time = s.st_mtime;
- info->size = s.st_size;
+ info->size = s.st_size; /* overflows at 2GB */
+ ff_data->size = s.st_size;
do_uconvert(tempname, U_UTF8, info->name, U_CURRENT, sizeof(info->name));
Index: include/allegro/file.h
===================================================================
--- include/allegro/file.h (revision 5800)
+++ include/allegro/file.h (working copy)
@@ -40,6 +40,7 @@
AL_FUNC(int, file_exists, (AL_CONST char *filename, int attrib, int *aret));
AL_FUNC(int, exists, (AL_CONST char *filename));
AL_FUNC(long, file_size, (AL_CONST char *filename));
+AL_FUNC(uint64_t, file_size_ex, (AL_CONST char *filename));
AL_FUNC(time_t, file_time, (AL_CONST char *filename));
AL_FUNC(int, delete_file, (AL_CONST char *filename));
AL_FUNC(int, for_each_file_ex, (AL_CONST char *name, int in_attrib, int out_attrib, AL_METHOD(int, callback, (AL_CONST char *filename, int attrib, void *param)), void *param));
@@ -55,6 +56,8 @@
void *ff_data; /* private hook */
};
+AL_FUNC(uint64_t, al_ffblk_get_size, (struct al_ffblk *info));
+
AL_FUNC(int, al_findfirst, (AL_CONST char *pattern, struct al_ffblk *info, int attrib));
AL_FUNC(int, al_findnext, (struct al_ffblk *info));
AL_FUNC(void, al_findclose, (struct al_ffblk *info));
Index: configure.in
===================================================================
--- configure.in (revision 5800)
+++ configure.in (working copy)
@@ -713,7 +713,7 @@
AC_STRUCT_TM
AC_TYPE_SIGNAL
-AC_CHECK_FUNCS(mmap mprotect memcmp mkstemp stricmp strlwr strupr vprintf)
+AC_CHECK_FUNCS(mmap mprotect memcmp mkstemp stricmp strlwr strupr vprintf stat64)
dnl Tweak header files for library build
CFLAGS="$CFLAGS -DALLEGRO_LIB_BUILD"