Repository: libsdl-org/SDL

Issue #3121: [patch] Add SDL_RWflush()
Created: 2021-02-11T01:22:06Z
This bug report was migrated from our old Bugzilla tracker.
These attachments are available in the static archive:

An untested patch for all platforms. (add-rwflush.patch, text/plain, 2019-01-09 20:59:20 +0000, 5729 bytes)
An untested patch for all platforms. (add-rwflush.patch, text/plain, 2019-01-09 21:09:29 +0000, 5726 bytes)
Untested SDL_RWflush() (add-rwflush-2.patch, text/plain, 2019-01-11 13:16:48 +0000, 5959 bytes)

Reported in version: 2.0.9
Reported for operating system, platform: All, All
Comments on the original bug report:
On 2019-01-09 15:49:29 +0000, David Lönnhager wrote:

Useful when the stream is a FILE*, at least.

On 2019-01-09 20:59:20 +0000, David Lönnhager wrote:

Created attachment 3563
An untested patch for all platforms.

On 2019-01-09 21:07:12 +0000, David Lönnhager wrote:

Comment on attachment 3563
An untested patch for all platforms.
# HG changeset patch
# User David Lönnhager <dv.lnh.d@gmail.com>
# Date 1547065423 -3600
#      Wed Jan 09 21:23:43 2019 +0100
# Node ID a7379dd9f8cc02c5474517ac49232c05b497d909
# Parent  c70b2574d38d9e040f088032674e5e4870c30853
Add SDL_RWflush().

diff -r c70b2574d38d -r a7379dd9f8cc include/SDL_error.h
--- a/include/SDL_error.h	Wed Jan 09 15:37:21 2019 +0100
+++ b/include/SDL_error.h	Wed Jan 09 21:23:43 2019 +0100
@@ -58,6 +58,7 @@
     SDL_EFREAD,
     SDL_EFWRITE,
     SDL_EFSEEK,
+    SDL_EFFLUSH,
     SDL_UNSUPPORTED,
     SDL_LASTERROR
 } SDL_errorcode;
diff -r c70b2574d38d -r a7379dd9f8cc include/SDL_rwops.h
--- a/include/SDL_rwops.h	Wed Jan 09 15:37:21 2019 +0100
+++ b/include/SDL_rwops.h	Wed Jan 09 21:23:43 2019 +0100
@@ -84,6 +84,14 @@
                               size_t size, size_t num);
 
     /**
+     *  Flushes the buffers for the stream and causes all buffered
+     *  data to be written.
+     *
+     *  \return 0 if successful, or -1 on error.
+     */
+    int (SDLCALL * flush) (struct SDL_RWops * context);
+
+    /**
      *  Close and free an allocated SDL_RWops structure.
      *
      *  \return 0 if successful or -1 on write error when flushing data.
@@ -186,6 +194,7 @@
 #define SDL_RWtell(ctx)         (ctx)->seek(ctx, 0, RW_SEEK_CUR)
 #define SDL_RWread(ctx, ptr, size, n)   (ctx)->read(ctx, ptr, size, n)
 #define SDL_RWwrite(ctx, ptr, size, n)  (ctx)->write(ctx, ptr, size, n)
+#define SDL_RWflush(ctx)  (ctx)->flush(ctx)
 #define SDL_RWclose(ctx)        (ctx)->close(ctx)
 /* @} *//* Read/write macros */
 
diff -r c70b2574d38d -r a7379dd9f8cc src/SDL_error.c
--- a/src/SDL_error.c	Wed Jan 09 15:37:21 2019 +0100
+++ b/src/SDL_error.c	Wed Jan 09 21:23:43 2019 +0100
@@ -166,6 +166,8 @@
         return SDL_SetError("Error writing to datastream");
     case SDL_EFSEEK:
         return SDL_SetError("Error seeking in datastream");
+    case SDL_EFFLUSH:
+        return SDL_SetError("Error flushing datastream");
     case SDL_UNSUPPORTED:
         return SDL_SetError("That operation is not supported");
     default:
diff -r c70b2574d38d -r a7379dd9f8cc src/core/android/SDL_android.c
--- a/src/core/android/SDL_android.c	Wed Jan 09 15:37:21 2019 +0100
+++ b/src/core/android/SDL_android.c	Wed Jan 09 21:23:43 2019 +0100
@@ -1718,6 +1718,12 @@
     return 0;
 }
 
+int Android_JNI_FileFlush(SDL_RWops *ctx)
+{
+    SDL_SetError("Cannot write to Android package filesystem");
+    return 0;
+}
+
 static int Internal_Android_JNI_FileClose(SDL_RWops *ctx, SDL_bool release)
 {
     struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
diff -r c70b2574d38d -r a7379dd9f8cc src/core/android/SDL_android.h
--- a/src/core/android/SDL_android.h	Wed Jan 09 15:37:21 2019 +0100
+++ b/src/core/android/SDL_android.h	Wed Jan 09 21:23:43 2019 +0100
@@ -67,6 +67,7 @@
 Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence);
 size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t maxnum);
 size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num);
+int Android_JNI_FileFlush(SDL_RWops* ctx);
 int Android_JNI_FileClose(SDL_RWops* ctx);
 
 /* Environment support */
diff -r c70b2574d38d -r a7379dd9f8cc src/file/SDL_rwops.c
--- a/src/file/SDL_rwops.c	Wed Jan 09 15:37:21 2019 +0100
+++ b/src/file/SDL_rwops.c	Wed Jan 09 21:23:43 2019 +0100
@@ -287,6 +287,19 @@
 }
 
 static int SDLCALL
+windows_file_flush(SDL_RWops * context)
+{
+    if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE)
+        return 0;
+
+    if (!FlushFileBuffers(context->hidden.windowsio.h)) {
+        SDL_Error(SDL_EFFLUSH);
+        return -1;
+    }
+    return 0;
+}
+
+static int SDLCALL
 windows_file_close(SDL_RWops * context)
 {
 
@@ -402,6 +415,15 @@
 }
 
 static int SDLCALL
+stdio_flush(SDL_RWops * context)
+{
+    if (fflush(context->hidden.stdio.fp)) {
+        return SDL_Error(SDL_EFFLUSH);
+    }
+    return 0;
+}
+
+static int SDLCALL
 stdio_close(SDL_RWops * context)
 {
     int status = 0;
@@ -496,6 +518,13 @@
 }
 
 static int SDLCALL
+mem_flush(SDL_RWops * context)
+{
+    SDL_SetError("Can't write to read-only memory");
+    return 0;
+}
+
+static int SDLCALL
 mem_close(SDL_RWops * context)
 {
     if (context) {
@@ -555,6 +584,7 @@
     rwops->read = Android_JNI_FileRead;
     rwops->write = Android_JNI_FileWrite;
     rwops->close = Android_JNI_FileClose;
+    rwops->flush = Android_JNI_FileFlush;
     rwops->type = SDL_RWOPS_JNIFILE;
 
 #elif defined(__WIN32__)
@@ -570,6 +600,7 @@
     rwops->read = windows_file_read;
     rwops->write = windows_file_write;
     rwops->close = windows_file_close;
+    rwops->flush = windows_file_flush;
     rwops->type = SDL_RWOPS_WINFILE;
 
 #elif HAVE_STDIO_H
@@ -608,6 +639,7 @@
         rwops->read = stdio_read;
         rwops->write = stdio_write;
         rwops->close = stdio_close;
+        rwops->flush = stdio_flush;
         rwops->hidden.stdio.fp = fp;
         rwops->hidden.stdio.autoclose = autoclose;
         rwops->type = SDL_RWOPS_STDFILE;
@@ -643,6 +675,7 @@
         rwops->read = mem_read;
         rwops->write = mem_write;
         rwops->close = mem_close;
+        rwops->flush = mem_flush;
         rwops->hidden.mem.base = (Uint8 *) mem;
         rwops->hidden.mem.here = rwops->hidden.mem.base;
         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
@@ -671,6 +704,7 @@
         rwops->read = mem_read;
         rwops->write = mem_writeconst;
         rwops->close = mem_close;
+        rwops->flush = mem_flush;
         rwops->hidden.mem.base = (Uint8 *) mem;
         rwops->hidden.mem.here = rwops->hidden.mem.base;
         rwops->hidden.mem.stop = rwops->hidden.mem.base + size;

On 2019-01-09 21:09:29 +0000, David Lönnhager wrote:

Created attachment 3564
An untested patch for all platforms.
Oops.

On 2019-01-10 07:59:37 +0000, Ryan C. Gordon wrote:

We can't add anything to this struct without breaking binary compatibility. Going to leave this assigned to Sam to make a judgement call, but this probably has to be punted to 2.1.
--ryan.

On 2019-01-11 13:16:48 +0000, David Lönnhager wrote:

Created attachment 3567
Untested SDL_RWflush()

Duplicate issue #3581: Add flush to SDL_rwops
Created: 2021-02-11T01:51:47Z
This bug report was migrated from our old Bugzilla tracker.
Reported in version: HG 2.1
Reported for operating system, platform: Linux, All
Comments on the original bug report:
On 2020-03-11 15:32:58 +0000, Rainer Deyke wrote:

I am using SDL_RWops for a log file.  This works fine for most cases, but if my program crashes with the log file open, the resulting log file is truncated because the file hasn't been flushed to the disk.  Would it be possible to add a flush function to SDL_RWops so that I can manually flush my log file to disk?

Closing comment (2022-06-14T04:38:54Z): Duplicate of #3121.