Browse code

A more elegant solution to the Windows bugs in filepaths and MinGW compilation

Deadly Headshot authored on 19/03/2023 21:04:58 • Devine Lu Linvega committed on 19/03/2023 21:11:42
Showing 2 changed files
... ...
@@ -11,6 +11,15 @@
11 11
 #ifdef _WIN32
12 12
 #include <libiberty/libiberty.h>
13 13
 #define realpath(s, dummy) lrealpath(s)
14
+#define DIR_SEP_CHAR '\\'
15
+#define DIR_SEP_STR "\\"
16
+#define pathcmp(path1,path2,length) strncasecmp(path1,path2,length) /* strncasecmp provided by libiberty */
17
+#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR && ((strlen(file_name)>2 && file_name[1] != ':') || strlen(file_name)<=2))
18
+#else
19
+#define DIR_SEP_CHAR '/'
20
+#define DIR_SEP_STR "/"
21
+#define pathcmp(path1,path2,length) strncmp(path1,path2,length)
22
+#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR)
14 23
 #endif
15 24
 
16 25
 #ifndef PATH_MAX
... ...
@@ -124,17 +133,17 @@ retry_realpath(const char *file_name)
124 133
 		errno = ENAMETOOLONG;
125 134
 		return NULL;
126 135
 	}
127
-	if(file_name[0] != '/') {
136
+	if(notdriveroot(file_name)) {
128 137
 		/* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */
129 138
 		/* if a relative path, prepend cwd */
130 139
 		getcwd(p, sizeof(p));
131
-		strcat(p, "/"); /* TODO: use a macro instead of '/' for the path delimiter */
140
+		strcat(p, DIR_SEP_STR); /* TODO: use a macro instead of '/' for the path delimiter */
132 141
 	}
133 142
 	strcat(p, file_name);
134 143
 	while((r = realpath(p, NULL)) == NULL) {
135 144
 		if(errno != ENOENT)
136 145
 			return NULL;
137
-		x = strrchr(p, '/'); /* TODO: path delimiter macro */
146
+		x = strrchr(p, DIR_SEP_CHAR); /* TODO: path delimiter macro */
138 147
 		if(x)
139 148
 			*x = '\0';
140 149
 		else
... ...
@@ -149,7 +158,7 @@ file_check_sandbox(UxnFile *c)
149 158
 	char *x, *rp, cwd[PATH_MAX] = {'\0'};
150 159
 	x = getcwd(cwd, sizeof(cwd));
151 160
 	rp = retry_realpath(c->current_filename);
152
-	if(rp == NULL || (x && strncmp(cwd, rp, strlen(cwd)) != 0)) {
161
+	if(rp == NULL || (x && pathcmp(cwd, rp, strlen(cwd)) != 0)) {
153 162
 		c->outside_sandbox = 1;
154 163
 		fprintf(stderr, "file warning: blocked attempt to access %s outside of sandbox\n", c->current_filename);
155 164
 	}
... ...
@@ -213,7 +222,7 @@ file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
213 222
 static Uint16
214 223
 file_stat(UxnFile *c, void *dest, Uint16 len)
215 224
 {
216
-	char *basename = strrchr(c->current_filename, '/');
225
+	char *basename = strrchr(c->current_filename, DIR_SEP_CHAR);
217 226
 	if(c->outside_sandbox) return 0;
218 227
 	if(basename != NULL)
219 228
 		basename++;
... ...
@@ -16,8 +16,11 @@
16 16
 #include "devices/controller.h"
17 17
 #include "devices/mouse.h"
18 18
 #include "devices/datetime.h"
19
-#ifdef _WIN32
19
+#if defined(_WIN32) && defined(_WIN32_WINNT) && _WIN32_WINNT > 0x0602
20 20
 #include <processthreadsapi.h>
21
+#elif defined(_WIN32)
22
+#include <windows.h>
23
+#include <string.h>
21 24
 #endif
22 25
 #pragma GCC diagnostic pop
23 26
 #pragma clang diagnostic pop