diff --git a/README.md b/README.md index 6b1817d35..2ede5150f 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ additional extensions: - pipe and event support (`pipe`, `event` ) - DNS resolution support (`resolve` ) +# NOTES +- Memory mapping is currently not compatible with threads + # WASI(X) Extensions Spec [WASIX](https://wasix.org) is maintained by wasix.org [here](https://github.com/wasix-org/wasix-witx) diff --git a/expected/wasm32-wasi-threads/defined-symbols.txt b/expected/wasm32-wasi-threads/defined-symbols.txt index f185eeb50..65169b4d3 100644 --- a/expected/wasm32-wasi-threads/defined-symbols.txt +++ b/expected/wasm32-wasi-threads/defined-symbols.txt @@ -1155,6 +1155,7 @@ modf modff modfl mrand48 +msync mtx_destroy mtx_init mtx_lock diff --git a/expected/wasm32-wasi/defined-symbols.txt b/expected/wasm32-wasi/defined-symbols.txt index 441eaf87c..7a59c64e5 100644 --- a/expected/wasm32-wasi/defined-symbols.txt +++ b/expected/wasm32-wasi/defined-symbols.txt @@ -1189,6 +1189,7 @@ modf modff modfl mrand48 +msync mtx_destroy mtx_init mtx_lock diff --git a/expected/wasm64-wasi/defined-symbols.txt b/expected/wasm64-wasi/defined-symbols.txt index 441eaf87c..7a59c64e5 100644 --- a/expected/wasm64-wasi/defined-symbols.txt +++ b/expected/wasm64-wasi/defined-symbols.txt @@ -1189,6 +1189,7 @@ modf modff modfl mrand48 +msync mtx_destroy mtx_init mtx_lock diff --git a/libc-bottom-half/mman/mman.c b/libc-bottom-half/mman/mman.c index 87f08ba7d..32bce0412 100644 --- a/libc-bottom-half/mman/mman.c +++ b/libc-bottom-half/mman/mman.c @@ -21,6 +21,7 @@ struct map { int flags; off_t offset; size_t length; + int fd; }; void *mmap(void *addr, size_t length, int prot, int flags, @@ -90,6 +91,17 @@ void *mmap(void *addr, size_t length, int prot, int flags, // or with zeros. addr = map + 1; if ((flags & MAP_ANON) == 0) { + int new_fd = dup(fd); + + if (new_fd < 0) { + errno = EINVAL; + free(map); + + return NULL; + } + + map->fd = new_fd; + char *body = (char *)addr; while (length > 0) { const ssize_t nread = pread(fd, body, length, offset); @@ -105,6 +117,7 @@ void *mmap(void *addr, size_t length, int prot, int flags, body += (size_t)nread; } } else { + map->fd = -1; memset(addr, 0, length); } @@ -123,6 +136,54 @@ int munmap(void *addr, size_t length) { // Release the memory. free(map); + // Write the data back to the backing file and close + // the file handle + if (map->fd > 0) { + if ((map->prot & PROT_WRITE) != 0) { + msync(addr, length, MS_SYNC); + } + + close(map->fd); + } + // Success! return 0; } + +int msync (void *addr, size_t length, int flags) { + struct map *map = (struct map *)addr - 1; + size_t map_flags = map->flags; + off_t map_offset = map->offset; + size_t map_length = map->length; + int fd = map->fd; + + if (length > map_length) { + errno = EINVAL; + return -1; + } + + if ((map->prot & PROT_WRITE) != 0) { + errno = EINVAL; + return -1; + } + + if ((map_flags & MAP_ANON) == 0) { + char *body = (char *)addr; + + while (length > 0) { + const ssize_t nwrite = pwrite(fd, body, length, map_offset); + + if (nwrite > 0) { + length -= (size_t)nwrite; + map_offset += (size_t)nwrite; + body += (size_t)nwrite; + } else if (errno == EINTR) { + continue; + } else { + return -1; + } + } + } + + return 0; +}