iostream: Properly support the "x" mode for SDL_IOFromFile()

The "x" mode for `fopen()` (open file only if it doesn't exist) used to
be a glibc-exclusive extension, but was later standardized in C11, and
is now also implemented as part of every other widely-used libc:

	* musl: https://git.musl-libc.org/cgit/musl/tree/src/stdio/__fmodeflags.c?id=0ccaf0572e9cccda2cced0f7ee659af4c1c6679a
	* Android Bionic / OpenBSD: 731631f300/libc/upstream-openbsd/lib/libc/stdio/flags.c (86)
	* Apple / FreeBSD: 63976b830a/stdio/FreeBSD/flags.c (L91-L92)

As a result, "x" has already been working on all our automatically
tested platforms that implement `SDL_IOFromFile()` via `fopen()`. So
all we'd be missing for proper support is a Windows implementation
using `CREATE_NEW`, and the documentation that this mode exists and is
intended to work.
This commit is contained in:
nmlgc
2025-10-05 23:15:03 +02:00
committed by Sam Lantinga
parent 87e3250518
commit 8df057fafc
3 changed files with 18 additions and 3 deletions

View File

@@ -94,10 +94,12 @@ static HANDLE SDLCALL windows_file_open(const char *filename, const char *mode)
// "r" = reading, file must exist
// "w" = writing, truncate existing, file may not exist
// "wx"= writing, file must not exist
// "r+"= reading or writing, file must exist
// "a" = writing, append file may not exist
// "a+"= append + read, file may not exist
// "w+" = read, write, truncate. file may not exist
// "w+x"= read, write, file must not exist
must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
@@ -105,6 +107,10 @@ static HANDLE SDLCALL windows_file_open(const char *filename, const char *mode)
a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
w_right = (a_mode || SDL_strchr(mode, '+') || truncate) ? GENERIC_WRITE : 0;
if (truncate && (SDL_strchr(mode, 'x') != NULL)) {
truncate = CREATE_NEW;
}
if (!r_right && !w_right) {
return INVALID_HANDLE_VALUE; // inconsistent mode
}