From 3bd3369fdc8b133d2a6a537160cb438749af3349 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 21:56:01 -0700 Subject: [PATCH] Add fopenfile, alternative to fopen that does not ever open directories --- src/doomdef.h | 2 ++ src/filesrch.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/doomdef.h b/src/doomdef.h index 2b62bcd6e..62afcc6c7 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -104,6 +104,8 @@ #include #endif +FILE *fopenfile(const char*, const char*); + //#define NOMD5 // Uncheck this to compile debugging code diff --git a/src/filesrch.c b/src/filesrch.c index 3f901b695..33d5bc65f 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -39,6 +39,7 @@ #define SUFFIX "*" #define SLASH "\\" +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #ifndef INVALID_FILE_ATTRIBUTES @@ -307,6 +308,39 @@ closedir (DIR * dirp) } #endif +// fopen but it REALLY only works on regular files +// Turns out, on linux, anyway, you can fopen directories +// in read mode. (It's supposed to fail in write mode +// though!!) +FILE *fopenfile(const char *path, const char *mode) +{ + FILE *h = fopen(path, mode); + + if (h != NULL) + { + struct stat st; + int eno; + + if (fstat(fileno(h), &st) == -1) + { + eno = errno; + } + else if (!S_ISREG(st.st_mode)) + { + eno = EACCES; // set some kinda error + } + else + { + return h; // ok + } + + fclose(h); + errno = eno; + } + + return NULL; +} + static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"}, #if 1 {1, "HOME"}, {2, "SRB2"},