ref: f79d846640485ee5b07fb2d9ec1275a1f76bbc5d
parent: 0f6f4d82ebd96a0e88efa9492a2038f23a2dcbf6
author: Andreas Gnau <[email protected]>
date: Sat Sep 23 19:21:32 EDT 2017
Make API large-file-aware #51 Enable large-file support, but change the API to accept file offsets larger than 2GB (unlikely for module files). Check the return-code of ftell to fail early when a file larger than 2GB is supplied.
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,9 @@
option(BUILD_ALLEGRO4 "Build Allegro4 support" ON)
option(USE_SSE "Use SSE instructions" ON)
-set(CMAKE_C_FLAGS "-Wall -DDUMB_DECLARE_DEPRECATED -Wno-unused-variable -Wno-unused-but-set-variable")
+set(CMAKE_C_FLAGS "-Wall -Wno-unused-variable -Wno-unused-but-set-variable")
+add_definitions(-D_FILE_OFFSET_BITS=64)
+add_definitions(-DDUMB_DECLARE_DEPRECATED)
set(CMAKE_C_FLAGS_DEBUG "-ggdb -DDEBUGMODE=1 -D_DEBUG")
set(CMAKE_C_FLAGS_RELEASE "-ffast-math -O2 -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-ffast-math -g -O2 -DNDEBUG")
--- a/include/dumb.h
+++ b/include/dumb.h
@@ -129,16 +129,47 @@
/* File Input Functions */
+#ifdef DUMB_OFF_T_CUSTOM
+ typedef dumb_off_t DUMB_OFF_T_CUSTOM;
+#elif defined _MSC_VER || defined __WATCOMC__
+ typedef __int64 dumb_off_t;
+#elif defined __DJGPP__
+ typedef off64_t dumb_off_t;
+#elif _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 500 || defined __MINGW32__
+ typedef off_t dumb_off_t;
+#else
+ typedef long long dumb_off_t;
+#endif
+/*
+ * If the build fails here, it does so, because we need a 64-bit-type for
+ * defining offsets. To fix this do either of the following:
+ *
+ * 1. Compile your code with -D_FILE_OFFSET_BITS=64, so that off_t is 64-bit
+ * (recommended, but make sure the rest of your code can handle it)
+ * 2. Supply your own definition of a signed 64-bit integer
+ * such as off64_t or int64_t before including dumb.h as follows:
+ * #define DUMB_OFF_T_CUSTOM int64_t
+ */
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined __cplusplus
+ _Static_assert(sizeof(dumb_off_t) >= 8, "fuse: off_t must be 64bit");
+#else
+ struct dumb_off_t_needs_to_be_at_least_8_bytes { \
+ unsigned int dumb_off_t_needs_to_be_at_least_8_bytes: \
+ ((sizeof(dumb_off_t) >= 8) ? 1 : -42); \
+ };
+#endif
+
+
typedef struct DUMBFILE_SYSTEM
{
void *(*open)(const char *filename);
- int (*skip)(void *f, long n);
+ int (*skip)(void *f, dumb_off_t n);
int (*getc)(void *f);
- long (*getnc)(char *ptr, long n, void *f);
+ size_t (*getnc)(char *ptr, size_t n, void *f);
void (*close)(void *f);
- int (*seek)(void *f, long n);
- long (*get_size)(void *f);
+ int (*seek)(void *f, dumb_off_t offset);
+ dumb_off_t (*get_size)(void *f);
}
DUMBFILE_SYSTEM;
@@ -149,16 +180,16 @@
DUMBFILE *dumbfile_open(const char *filename);
DUMBFILE *dumbfile_open_ex(void *file, const DUMBFILE_SYSTEM *dfs);
-long dumbfile_pos(DUMBFILE *f);
-int dumbfile_skip(DUMBFILE *f, long n);
+dumb_off_t dumbfile_pos(DUMBFILE *f);
+int dumbfile_skip(DUMBFILE *f, dumb_off_t n);
#define DFS_SEEK_SET 0
#define DFS_SEEK_CUR 1
#define DFS_SEEK_END 2
-int dumbfile_seek(DUMBFILE *f, long n, int origin);
+int dumbfile_seek(DUMBFILE *f, dumb_off_t n, int origin);
-long dumbfile_get_size(DUMBFILE *f);
+dumb_off_t dumbfile_get_size(DUMBFILE *f);
int dumbfile_getc(DUMBFILE *f);
@@ -171,7 +202,7 @@
unsigned long dumbfile_cgetul(DUMBFILE *f);
signed long dumbfile_cgetsl(DUMBFILE *f);
-long dumbfile_getnc(char *ptr, long n, DUMBFILE *f);
+size_t dumbfile_getnc(char *ptr, size_t n, DUMBFILE *f);
int dumbfile_error(DUMBFILE *f);
int dumbfile_close(DUMBFILE *f);
@@ -186,7 +217,7 @@
/* Memory File Input Module */
-DUMBFILE *dumbfile_open_memory(const char *data, long size);
+DUMBFILE *dumbfile_open_memory(const char *data, size_t size);
/* DUH Management */
@@ -200,7 +231,7 @@
DUH *load_duh(const char *filename);
DUH *read_duh(DUMBFILE *f);
-long duh_get_length(DUH *duh);
+dumb_off_t duh_get_length(DUH *duh);
const char *duh_get_tag(DUH *duh, const char *key);
int duh_get_tag_iterator_size(DUH *duh);
@@ -785,7 +816,7 @@
/* DUH Construction */
DUH *make_duh(
- long length,
+ dumb_off_t length,
int n_tags,
const char *const tag[][2],
int n_signals,
@@ -793,7 +824,7 @@
sigdata_t *sigdata[]
);
-void duh_set_length(DUH *duh, long length);
+void duh_set_length(DUH *duh, dumb_off_t length);
#ifdef __cplusplus
--- a/include/internal/dumb.h
+++ b/include/internal/dumb.h
@@ -67,7 +67,7 @@
struct DUH
{
- long length;
+ dumb_off_t length;
int n_tags;
char *(*tag)[2];
--- a/src/allegro/packfile.c
+++ b/src/allegro/packfile.c
@@ -48,7 +48,7 @@
}
-static int dumb_packfile_skip(void *f, long n)
+static int dumb_packfile_skip(void *f, dumb_off_t n)
{
dumb_packfile * file = ( dumb_packfile * ) f;
file->pos += n;
@@ -67,7 +67,7 @@
-static long dumb_packfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_packfile_getnc(char *ptr, size_t n, void *f)
{
dumb_packfile * file = ( dumb_packfile * ) f;
int nr = pack_fread(ptr, n, file->p);
@@ -89,7 +89,7 @@
free(f);
}
-static int dumb_packfile_seek(void *f, long n)
+static int dumb_packfile_seek(void *f, dumb_off_t n)
{
dumb_packfile * file = ( dumb_packfile * ) f;
file->pos = n;
@@ -96,7 +96,7 @@
return pack_fseek(file->p, n);
}
-static long dumb_packfile_get_size(void *f)
+static dumb_off_t dumb_packfile_get_size(void *f)
{
dumb_packfile * file = ( dumb_packfile * ) f;
return file->size;
--- a/src/core/duhlen.c
+++ b/src/core/duhlen.c
@@ -28,7 +28,7 @@
-long duh_get_length(DUH *duh)
+dumb_off_t duh_get_length(DUH *duh)
{
return duh ? duh->length : 0;
}
@@ -35,7 +35,7 @@
-void duh_set_length(DUH *duh, long length)
+void duh_set_length(DUH *duh, dumb_off_t length)
{
if (duh)
duh->length = length;
--- a/src/core/dumbfile.c
+++ b/src/core/dumbfile.c
@@ -98,7 +98,7 @@
-long dumbfile_pos(DUMBFILE *f)
+dumb_off_t dumbfile_pos(DUMBFILE *f)
{
ASSERT(f);
@@ -108,7 +108,7 @@
/* Move forward in the file from the current position by n bytes. */
-int dumbfile_skip(DUMBFILE *f, long n)
+int dumbfile_skip(DUMBFILE *f, dumb_off_t n)
{
int rv;
@@ -340,7 +340,7 @@
-long dumbfile_getnc(char *ptr, long n, DUMBFILE *f)
+size_t dumbfile_getnc(char *ptr, size_t n, DUMBFILE *f)
{
long rv;
@@ -377,7 +377,7 @@
/* Move to an arbitrary position n in the file, specified relative to origin,
* where origin shall be one of the DFS_SEEK_* constants.
*/
-int dumbfile_seek(DUMBFILE *f, long n, int origin)
+int dumbfile_seek(DUMBFILE *f, dumb_off_t n, int origin)
{
switch ( origin )
{
@@ -391,7 +391,7 @@
-long dumbfile_get_size(DUMBFILE *f)
+dumb_off_t dumbfile_get_size(DUMBFILE *f)
{
return (*f->dfs->get_size)(f->file);
}
--- a/src/core/makeduh.c
+++ b/src/core/makeduh.c
@@ -50,7 +50,7 @@
DUH *make_duh(
- long length,
+ dumb_off_t length,
int n_tags,
const char *const tags[][2],
int n_signals,
--- a/src/helpers/memfile.c
+++ b/src/helpers/memfile.c
@@ -29,12 +29,12 @@
struct MEMFILE
{
const char *ptr, *ptr_begin;
- long left, size;
+ size_t left, size;
};
-static int dumb_memfile_skip(void *f, long n)
+static int dumb_memfile_skip(void *f, dumb_off_t n)
{
MEMFILE *m = f;
if (n > m->left) return -1;
@@ -55,7 +55,7 @@
-static long dumb_memfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_memfile_getnc(char *ptr, size_t n, void *f)
{
MEMFILE *m = f;
if (n > m->left) n = m->left;
@@ -73,7 +73,7 @@
}
-static int dumb_memfile_seek(void *f, long n)
+static int dumb_memfile_seek(void *f, dumb_off_t n)
{
MEMFILE *m = f;
@@ -84,7 +84,7 @@
}
-static long dumb_memfile_get_size(void *f)
+static dumb_off_t dumb_memfile_get_size(void *f)
{
MEMFILE *m = f;
return m->size;
@@ -103,7 +103,7 @@
-DUMBFILE *dumbfile_open_memory(const char *data, long size)
+DUMBFILE *dumbfile_open_memory(const char *data, size_t size)
{
MEMFILE *m = malloc(sizeof(*m));
if (!m) return NULL;
--- a/src/helpers/stdfile.c
+++ b/src/helpers/stdfile.c
@@ -26,7 +26,7 @@
typedef struct dumb_stdfile
{
FILE * file;
- long size;
+ dumb_off_t size;
} dumb_stdfile;
@@ -43,6 +43,11 @@
}
fseek(file->file, 0, SEEK_END);
file->size = ftell(file->file);
+ if (file->size < 0) {
+ fclose(file->file);
+ free(file);
+ return 0;
+ }
fseek(file->file, 0, SEEK_SET);
return file;
}
@@ -49,7 +54,7 @@
-static int dumb_stdfile_skip(void *f, long n)
+static int dumb_stdfile_skip(void *f, dumb_off_t n)
{
dumb_stdfile * file = ( dumb_stdfile * ) f;
return fseek(file->file, n, SEEK_CUR);
@@ -65,7 +70,7 @@
-static long dumb_stdfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_stdfile_getnc(char *ptr, size_t n, void *f)
{
dumb_stdfile * file = ( dumb_stdfile * ) f;
return fread(ptr, 1, n, file->file);
@@ -89,7 +94,7 @@
-static int dumb_stdfile_seek(void *f, long n)
+static int dumb_stdfile_seek(void *f, dumb_off_t n)
{
dumb_stdfile * file = ( dumb_stdfile * ) f;
return fseek(file->file, n, SEEK_SET);
@@ -97,7 +102,7 @@
-static long dumb_stdfile_get_size(void *f)
+static dumb_off_t dumb_stdfile_get_size(void *f)
{
dumb_stdfile * file = ( dumb_stdfile * ) f;
return file->size;
@@ -144,6 +149,10 @@
file->file = p;
fseek(p, 0, SEEK_END);
file->size = ftell(p);
+ if (file->size < 0) {
+ free(file);
+ return 0;
+ }
fseek(p, 0, SEEK_SET);
d = dumbfile_open_ex(file, &stdfile_dfs_leave_open);
--- a/src/it/readxm.c
+++ b/src/it/readxm.c
@@ -399,7 +399,7 @@
return dumbfile_skip( lx->remaining, n );
}
-static int limit_xm_skip(void *f, long n)
+static int limit_xm_skip(void *f, dumb_off_t n)
{
LIMITED_XM *lx = f;
lx->ptr += n;
@@ -419,7 +419,7 @@
-static long limit_xm_getnc(char *ptr, long n, void *f)
+static size_t limit_xm_getnc(char *ptr, size_t n, void *f)
{
LIMITED_XM *lx = f;
int left;
@@ -450,7 +450,7 @@
/* These two can be stubs since this implementation doesn't use seeking */
-static int limit_xm_seek(void *f, long n)
+static int limit_xm_seek(void *f, dumb_off_t n)
{
(void)f;
(void)n;
@@ -459,7 +459,7 @@
-static long limit_xm_get_size(void *f)
+static dumb_off_t limit_xm_get_size(void *f)
{
(void)f;
return 0;