|
@@ -32,6 +32,13 @@
|
|
|
#include "../core/windows/SDL_windows.h"
|
|
|
#endif
|
|
|
|
|
|
+#ifdef HAVE_STDIO_H
|
|
|
+#include <stdio.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef HAVE_LIMITS_H
|
|
|
+#include <limits.h>
|
|
|
+#endif
|
|
|
|
|
|
/* This file provides a general interface for SDL to read and write
|
|
|
data sources. It can easily be extended to files, memory, etc.
|
|
@@ -306,6 +313,19 @@ windows_file_close(SDL_RWops * context)
|
|
|
#define fseek fseeko64
|
|
|
#define ftell ftello64
|
|
|
#elif defined(HAVE_FSEEKO)
|
|
|
+#if defined(OFF_MIN) && defined(OFF_MAX)
|
|
|
+#define FSEEK_OFF_MIN OFF_MIN
|
|
|
+#define FSEEK_OFF_MAX OFF_MAX
|
|
|
+#elif defined(HAVE_LIMITS_H)
|
|
|
+/* POSIX doesn't specify the minimum and maximum macros for off_t so
|
|
|
+ * we have to improvise and dance around implementation-defined
|
|
|
+ * behavior. This may fail if the off_t type has padding bits or
|
|
|
+ * is not a two's-complement representation. The compilers will detect
|
|
|
+ * and eliminate the dead code if off_t has 64 bits.
|
|
|
+ */
|
|
|
+#define FSEEK_OFF_MAX (((((off_t)1 << (sizeof(off_t) * CHAR_BIT - 2)) - 1) << 1) + 1)
|
|
|
+#define FSEEK_OFF_MIN (-(FSEEK_OFF_MAX) - 1)
|
|
|
+#endif
|
|
|
#define fseek_off_t off_t
|
|
|
#define fseek fseeko
|
|
|
#define ftell ftello
|
|
@@ -314,6 +334,10 @@ windows_file_close(SDL_RWops * context)
|
|
|
#define fseek _fseeki64
|
|
|
#define ftell _ftelli64
|
|
|
#else
|
|
|
+#ifdef HAVE_LIMITS_H
|
|
|
+#define FSEEK_OFF_MIN LONG_MIN
|
|
|
+#define FSEEK_OFF_MAX LONG_MAX
|
|
|
+#endif
|
|
|
#define fseek_off_t long
|
|
|
#endif
|
|
|
|
|
@@ -337,8 +361,18 @@ stdio_size(SDL_RWops * context)
|
|
|
static Sint64 SDLCALL
|
|
|
stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
|
|
|
{
|
|
|
+#if defined(FSEEK_OFF_MIN) && defined(FSEEK_OFF_MAX)
|
|
|
+ if (offset < (Sint64)(FSEEK_OFF_MIN) || offset > (Sint64)(FSEEK_OFF_MAX)) {
|
|
|
+ return SDL_SetError("Seek offset out of range");
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
if (fseek(context->hidden.stdio.fp, (fseek_off_t)offset, whence) == 0) {
|
|
|
- return ftell(context->hidden.stdio.fp);
|
|
|
+ Sint64 pos = ftell(context->hidden.stdio.fp);
|
|
|
+ if (pos < 0) {
|
|
|
+ return SDL_SetError("Couldn't get stream offset");
|
|
|
+ }
|
|
|
+ return pos;
|
|
|
}
|
|
|
return SDL_Error(SDL_EFSEEK);
|
|
|
}
|