authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-05 21:06:33-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-06 12:27:28-07:00
log793db278050973e00d71d6789b8d439a7bbbcaa9
tree505e19c453babe2e9f0b3a10b80d7dd9cb27757a
parent98338358ede66020458e83b1ec7cda79eac2698b

wasi: add support for windows paths


1 files changed, 27 insertions(+), 8 deletions(-)

stage1/wasi.c+27-8
...@@ -237,7 +237,7 @@ int main(int argc, char **argv) {...@@ -237,7 +237,7 @@ int main(int argc, char **argv) {
237237
238 des[3].filetype = wasi_filetype_directory;238 des[3].filetype = wasi_filetype_directory;
239 des[3].guest_path = dupe("/lib", sizeof("/lib"));239 des[3].guest_path = dupe("/lib", sizeof("/lib"));
240 des[3].host_path = dupe(argv[1], strlen(argv[1]));240 des[3].host_path = dupe(argv[1], strlen(argv[1]) + 1);
241241
242 fd_len = 6;242 fd_len = 6;
243 fds = calloc(sizeof(struct FileDescriptor), fd_len);243 fds = calloc(sizeof(struct FileDescriptor), fd_len);
...@@ -252,8 +252,27 @@ int main(int argc, char **argv) {...@@ -252,8 +252,27 @@ int main(int argc, char **argv) {
252 wasm__start();252 wasm__start();
253}253}
254254
255static bool isLetter(char c) {
256 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
257}
258static bool isPathSep(char c) {
259 return c == '/' || c == '\\';
260}
261static bool isAbsPath(const char *path, uint32_t path_len) {
262 if (path_len >= 1 && isPathSep(path[0])) return true;
263 if (path_len >= 3 && isLetter(path[0]) && path[1] == ':' && isPathSep(path[2])) return true;
264 return false;
265}
266static bool isSamePath(const char *a, const char *b, uint32_t len) {
267 for (uint32_t i = 0; i < len; i += 1) {
268 if (isPathSep(a[i]) && isPathSep(b[i])) continue;
269 if (a[i] != b[i]) return false;
270 }
271 return true;
272}
273
255static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32_t path_len, enum wasi_filetype filetype, time_t tim, uint32_t *res_de) {274static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32_t path_len, enum wasi_filetype filetype, time_t tim, uint32_t *res_de) {
256 if (path[0] != '/') {275 if (isAbsPath(path, path_len)) {
257 if (dir_fd >= fd_len || fds[dir_fd].de >= de_len) return wasi_errno_badf;276 if (dir_fd >= fd_len || fds[dir_fd].de >= de_len) return wasi_errno_badf;
258 if (des[fds[dir_fd].de].filetype != wasi_filetype_directory) return wasi_errno_notdir;277 if (des[fds[dir_fd].de].filetype != wasi_filetype_directory) return wasi_errno_notdir;
259 }278 }
...@@ -267,7 +286,7 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32...@@ -267,7 +286,7 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32
267 de->atim = tim;286 de->atim = tim;
268 de->mtim = tim;287 de->mtim = tim;
269 de->ctim = tim;288 de->ctim = tim;
270 if (path[0] == '/') {289 if (isAbsPath(path, path_len)) {
271 de->guest_path = malloc(path_len + 1);290 de->guest_path = malloc(path_len + 1);
272 if (de->guest_path == NULL) return wasi_errno_nomem;291 if (de->guest_path == NULL) return wasi_errno_nomem;
273 memcpy(&de->guest_path[0], path, path_len);292 memcpy(&de->guest_path[0], path, path_len);
...@@ -307,10 +326,10 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32...@@ -307,10 +326,10 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32
307326
308static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const char *path, uint32_t path_len, uint32_t *res_de) {327static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const char *path, uint32_t path_len, uint32_t *res_de) {
309 (void)flags;328 (void)flags;
310 if (path[0] == '/') {329 if (isAbsPath(path, path_len)) {
311 for (uint32_t de = 0; de < de_len; de += 1) {330 for (uint32_t de = 0; de < de_len; de += 1) {
312 if (des[de].guest_path == NULL) continue;331 if (des[de].guest_path == NULL) continue;
313 if (memcmp(&des[de].guest_path[0], path, path_len) != 0) continue;332 if (!isSamePath(&des[de].guest_path[0], path, path_len)) continue;
314 if (des[de].guest_path[path_len] != '\0') continue;333 if (des[de].guest_path[path_len] != '\0') continue;
315 if (res_de != NULL) *res_de = de;334 if (res_de != NULL) *res_de = de;
316 return wasi_errno_success;335 return wasi_errno_success;
...@@ -323,9 +342,9 @@ static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const ch...@@ -323,9 +342,9 @@ static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const ch
323 size_t dir_guest_path_len = strlen(dir_de->guest_path);342 size_t dir_guest_path_len = strlen(dir_de->guest_path);
324 for (uint32_t de = 0; de < de_len; de += 1) {343 for (uint32_t de = 0; de < de_len; de += 1) {
325 if (des[de].guest_path == NULL) continue;344 if (des[de].guest_path == NULL) continue;
326 if (memcmp(&des[de].guest_path[0], dir_de->guest_path, dir_guest_path_len) != 0) continue;345 if (!isSamePath(&des[de].guest_path[0], dir_de->guest_path, dir_guest_path_len)) continue;
327 if (des[de].guest_path[dir_guest_path_len] != '/') continue;346 if (!isPathSep(des[de].guest_path[dir_guest_path_len])) continue;
328 if (memcmp(&des[de].guest_path[dir_guest_path_len + 1], path, path_len) != 0) continue;347 if (!isSamePath(&des[de].guest_path[dir_guest_path_len + 1], path, path_len)) continue;
329 if (des[de].guest_path[dir_guest_path_len + 1 + path_len] != '\0') continue;348 if (des[de].guest_path[dir_guest_path_len + 1 + path_len] != '\0') continue;
330 if (res_de != NULL) *res_de = de;349 if (res_de != NULL) *res_de = de;
331 return wasi_errno_success;350 return wasi_errno_success;