SDL_RWFromFile, stdio: allow named pipes along with regular files.

Fixes https://github.com/libsdl-org/SDL/issues/9174
This commit is contained in:
Ozkan Sezer 2024-03-06 18:50:00 +03:00
parent bdc7ad8f56
commit 177a836653

View file

@ -38,7 +38,6 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
@ -525,16 +524,17 @@ static int SDLCALL mem_close(SDL_RWops *context)
/* Functions to create SDL_RWops structures from various data sources */ /* Functions to create SDL_RWops structures from various data sources */
#if defined(HAVE_STDIO_H) && !(defined(__WIN32__) || defined(__GDK__)) #if defined(HAVE_STDIO_H) && !(defined(__WIN32__) || defined(__GDK__))
static SDL_bool SDL_IsRegularFile(FILE *f) static SDL_bool IsRegularFileOrPipe(FILE *f)
{ {
#ifdef __WINRT__ #ifdef __WINRT__
struct __stat64 st; struct __stat64 st;
if (_fstat64(_fileno(f), &st) < 0 || (st.st_mode & _S_IFMT) != _S_IFREG) { if (_fstat64(_fileno(f), &st) < 0 ||
!((st.st_mode & _S_IFMT) == _S_IFREG || (st.st_mode & _S_IFMT) == _S_IFIFO)) {
return SDL_FALSE; return SDL_FALSE;
} }
#else #else
struct stat st; struct stat st;
if (fstat(fileno(f), &st) < 0 || !S_ISREG(st.st_mode)) { if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) {
return SDL_FALSE; return SDL_FALSE;
} }
#endif #endif
@ -555,9 +555,9 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
if (*file == '/') { if (*file == '/') {
FILE *fp = fopen(file, mode); FILE *fp = fopen(file, mode);
if (fp) { if (fp) {
if (!SDL_IsRegularFile(fp)) { if (!IsRegularFileOrPipe(fp)) {
fclose(fp); fclose(fp);
SDL_SetError("%s is not a regular file", file); SDL_SetError("%s is not a regular file or pipe", file);
return NULL; return NULL;
} }
return SDL_RWFromFP(fp, 1); return SDL_RWFromFP(fp, 1);
@ -575,9 +575,9 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
fp = fopen(path, mode); fp = fopen(path, mode);
SDL_stack_free(path); SDL_stack_free(path);
if (fp) { if (fp) {
if (!SDL_IsRegularFile(fp)) { if (!IsRegularFileOrPipe(fp)) {
fclose(fp); fclose(fp);
SDL_SetError("%s is not a regular file", path); SDL_SetError("%s is not a regular file or pipe", path);
return NULL; return NULL;
} }
return SDL_RWFromFP(fp, 1); return SDL_RWFromFP(fp, 1);
@ -633,10 +633,10 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
#endif #endif
if (!fp) { if (!fp) {
SDL_SetError("Couldn't open %s", file); SDL_SetError("Couldn't open %s", file);
} else if (!SDL_IsRegularFile(fp)) { } else if (!IsRegularFileOrPipe(fp)) {
fclose(fp); fclose(fp);
fp = NULL; fp = NULL;
SDL_SetError("%s is not a regular file", file); SDL_SetError("%s is not a regular file or pipe", file);
} else { } else {
rwops = SDL_RWFromFP(fp, SDL_TRUE); rwops = SDL_RWFromFP(fp, SDL_TRUE);
} }