From: d_m <d_m@plastic-idolatry.com>
Without this change there is no cross-platform way to create a
directory on Windows, since the previous code checked for the
path delimiter as the final character, which was OS-dependent.
Seems to work on Windows based on tbsp's testing.
This change also fixes realpath on Windows.
Suggested by tbsp, based on:
https://stackoverflow.com/questions/45124869/cross-platform-alternative-to-this-realpath-definition/72492046#72492046
---
src/devices/file.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/src/devices/file.c b/src/devices/file.c
index a7487d4..6683c35 100644
--- a/src/devices/file.c+++ b/src/devices/file.c
@@ -8,26 +8,29 @@
#include <sys/stat.h>
#include <unistd.h>
+#ifndef PATH_MAX+#define PATH_MAX 4096+#endif++/* Windows devices can handle relative paths like "abc/def.txt" and+ absolute paths like "/foo/bar/baz.txt" so cross-platform ROMs+ should just use forward slash unconditionally and let the emulator+ worry about how to find the files in the filesystem. */+#ifdef _WIN32
#include <direct.h>
#include <libiberty/libiberty.h>
-#define realpath(s, dummy) lrealpath(s)-#define DIR_SEP_CHAR '\\'-#define DIR_SEP_STR "\\"-#define pathcmp(path1, path2, length) strncasecmp(path1, path2, length) /* strncasecmp provided by libiberty */-#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR && ((strlen(file_name) > 2 && file_name[1] != ':') || strlen(file_name) <= 2))+#define realpath(s, dummy) _fullpath((dummy), (s), PATH_MAX)+#define pathcmp(path1, path2, length) strncasecmp(path1, path2, length)#define mkdir(file_name) (_mkdir(file_name) == 0)
#else
-#define DIR_SEP_CHAR '/'-#define DIR_SEP_STR "/"#define pathcmp(path1, path2, length) strncmp(path1, path2, length)
-#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR)#define mkdir(file_name) (mkdir(file_name, 0755) == 0)
#endif
-#ifndef PATH_MAX-#define PATH_MAX 4096-#endif+#define DIR_SEP_CHAR '/'+#define DIR_SEP_STR "/"+#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR)#include "../uxn.h"
#include "file.h"
@@ -140,20 +143,19 @@ retry_realpath(const char *file_name)
return NULL;
}
if(notdriveroot(file_name)) {
- /* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */ /* if a relative path, prepend cwd */
getcwd(p, sizeof(p));
if(strlen(p) + strlen(DIR_SEP_STR) + fnlen >= PATH_MAX) {
errno = ENAMETOOLONG;
return NULL;
}
- strcat(p, DIR_SEP_STR); /* TODO: use a macro instead of '/' for the path delimiter */+ strcat(p, DIR_SEP_STR); }
strcat(p, file_name);
while((r = realpath(p, NULL)) == NULL) {
if(errno != ENOENT)
return NULL;
- x = strrchr(p, DIR_SEP_CHAR); /* TODO: path delimiter macro */+ x = strrchr(p, DIR_SEP_CHAR); if(x)
*x = '\0';
else
@@ -217,19 +219,19 @@ is_dir_path(char *p)
{
char c;
int saw_slash = 0;
- while (c = *p++)+ while ((c = *p++)) saw_slash = c == DIR_SEP_CHAR;
return saw_slash;
}
-int+static intdir_exists(char *p)
{
struct stat st;
return stat(p, &st) == 0 && S_ISDIR(st.st_mode);
}
-int+static intensure_parent_dirs(char *p)
{
int ok = 1;
--
2.39.2