summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deps/uvwasi/include/fd_table.h15
-rw-r--r--deps/uvwasi/include/uvwasi.h16
-rw-r--r--deps/uvwasi/src/fd_table.c125
-rw-r--r--deps/uvwasi/src/uvwasi.c508
-rw-r--r--deps/uvwasi/src/uvwasi_alloc.h11
5 files changed, 497 insertions, 178 deletions
diff --git a/deps/uvwasi/include/fd_table.h b/deps/uvwasi/include/fd_table.h
index ef87a3ff8f..42a5f0d920 100644
--- a/deps/uvwasi/include/fd_table.h
+++ b/deps/uvwasi/include/fd_table.h
@@ -16,6 +16,7 @@
# define PATH_MAX_BYTES (PATH_MAX)
#endif
+struct uvwasi_s;
struct uvwasi_fd_wrap_t {
uvwasi_fd_t id;
@@ -27,22 +28,28 @@ struct uvwasi_fd_wrap_t {
uvwasi_rights_t rights_inheriting;
int preopen;
int valid;
+ uv_mutex_t mutex;
};
struct uvwasi_fd_table_t {
struct uvwasi_fd_wrap_t* fds;
uint32_t size;
uint32_t used;
+ uv_rwlock_t rwlock;
};
-uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
+uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
uint32_t init_size);
-void uvwasi_fd_table_free(struct uvwasi_fd_table_t* table);
-uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
+void uvwasi_fd_table_free(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table);
+uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
const uv_file fd,
const char* path,
const char* real_path);
-uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
+uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_s* uvwasi,
+ struct uvwasi_fd_table_t* table,
const uv_file fd,
const int flags,
const char* path,
diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h
index a7695734ac..2a4e389164 100644
--- a/deps/uvwasi/include/uvwasi.h
+++ b/deps/uvwasi/include/uvwasi.h
@@ -20,7 +20,20 @@ extern "C" {
#define UVWASI_VERSION_STRING UVWASI_STRINGIFY(UVWASI_VERSION_MAJOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_MINOR) "." \
UVWASI_STRINGIFY(UVWASI_VERSION_PATCH)
+#define UVWASI_VERSION_WASI "snapshot_0"
+typedef void* (*uvwasi_malloc)(size_t size, void* mem_user_data);
+typedef void (*uvwasi_free)(void* ptr, void* mem_user_data);
+typedef void* (*uvwasi_calloc)(size_t nmemb, size_t size, void* mem_user_data);
+typedef void* (*uvwasi_realloc)(void* ptr, size_t size, void* mem_user_data);
+
+typedef struct uvwasi_mem_s {
+ void* mem_user_data;
+ uvwasi_malloc malloc;
+ uvwasi_free free;
+ uvwasi_calloc calloc;
+ uvwasi_realloc realloc;
+} uvwasi_mem_t;
typedef struct uvwasi_s {
struct uvwasi_fd_table_t fds;
@@ -32,6 +45,7 @@ typedef struct uvwasi_s {
char** env;
char* env_buf;
size_t env_buf_size;
+ const uvwasi_mem_t* allocator;
} uvwasi_t;
typedef struct uvwasi_preopen_s {
@@ -46,9 +60,9 @@ typedef struct uvwasi_options_s {
size_t argc;
char** argv;
char** envp;
+ const uvwasi_mem_t* allocator;
} uvwasi_options_t;
-
// Embedder API.
uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options);
void uvwasi_destroy(uvwasi_t* uvwasi);
diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c
index 9343868074..f716495e9a 100644
--- a/deps/uvwasi/src/fd_table.c
+++ b/deps/uvwasi/src/fd_table.c
@@ -10,6 +10,7 @@
#include "fd_table.h"
#include "wasi_types.h"
#include "uv_mapping.h"
+#include "uvwasi_alloc.h"
#define UVWASI__RIGHTS_ALL (UVWASI_RIGHT_FD_DATASYNC | \
@@ -175,7 +176,8 @@ static uvwasi_errno_t uvwasi__get_type_and_rights(uv_file fd,
}
-static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
+static uvwasi_errno_t uvwasi__fd_table_insert(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
uv_file fd,
const char* mapped_path,
const char* real_path,
@@ -186,16 +188,22 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
struct uvwasi_fd_wrap_t** wrap) {
struct uvwasi_fd_wrap_t* entry;
struct uvwasi_fd_wrap_t* new_fds;
+ uvwasi_errno_t err;
uint32_t new_size;
int index;
uint32_t i;
+ int r;
+
+ uv_rwlock_wrlock(&table->rwlock);
/* Check that there is room for a new item. If there isn't, grow the table. */
if (table->used >= table->size) {
new_size = table->size * 2;
- new_fds = realloc(table->fds, new_size * sizeof(*new_fds));
- if (new_fds == NULL)
- return UVWASI_ENOMEM;
+ new_fds = uvwasi__realloc(uvwasi, table->fds, new_size * sizeof(*new_fds));
+ if (new_fds == NULL) {
+ err = UVWASI_ENOMEM;
+ goto exit;
+ }
for (i = table->size; i < new_size; ++i)
new_fds[i].valid = 0;
@@ -214,11 +222,20 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
}
/* index should never be -1. */
- if (index == -1)
- return UVWASI_ENOSPC;
+ if (index == -1) {
+ err = UVWASI_ENOSPC;
+ goto exit;
+ }
}
entry = &table->fds[index];
+
+ r = uv_mutex_init(&entry->mutex);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
+
entry->id = index;
entry->fd = fd;
strcpy(entry->path, mapped_path);
@@ -233,11 +250,15 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
if (wrap != NULL)
*wrap = entry;
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_wrunlock(&table->rwlock);
+ return err;
}
-uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
+uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
uint32_t init_size) {
struct uvwasi_fd_wrap_t* wrap;
uvwasi_filetype_t type;
@@ -245,17 +266,27 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
uvwasi_rights_t inheriting;
uvwasi_errno_t err;
uvwasi_fd_t i;
+ int r;
/* Require an initial size of at least three to store the stdio FDs. */
if (table == NULL || init_size < 3)
return UVWASI_EINVAL;
+ table->fds = NULL;
+ r = uv_rwlock_init(&table->rwlock);
+ if (r != 0)
+ return uvwasi__translate_uv_error(r);
+
table->used = 0;
table->size = init_size;
- table->fds = calloc(init_size, sizeof(struct uvwasi_fd_wrap_t));
+ table->fds = uvwasi__calloc(uvwasi,
+ init_size,
+ sizeof(struct uvwasi_fd_wrap_t));
- if (table->fds == NULL)
- return UVWASI_ENOMEM;
+ if (table->fds == NULL) {
+ err = UVWASI_ENOMEM;
+ goto error_exit;
+ }
/* Create the stdio FDs. */
for (i = 0; i < 3; ++i) {
@@ -267,7 +298,8 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
if (err != UVWASI_ESUCCESS)
goto error_exit;
- err = uvwasi__fd_table_insert(table,
+ err = uvwasi__fd_table_insert(uvwasi,
+ table,
i,
"",
"",
@@ -287,23 +319,25 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
return UVWASI_ESUCCESS;
error_exit:
- uvwasi_fd_table_free(table);
+ uvwasi_fd_table_free(uvwasi, table);
return err;
}
-void uvwasi_fd_table_free(struct uvwasi_fd_table_t* table) {
+void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) {
if (table == NULL)
return;
- free(table->fds);
+ uvwasi__free(uvwasi, table->fds);
table->fds = NULL;
table->size = 0;
table->used = 0;
+ uv_rwlock_destroy(&table->rwlock);
}
-uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
+uvwasi_errno_t uvwasi_fd_table_insert_preopen(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
const uv_file fd,
const char* path,
const char* real_path) {
@@ -322,7 +356,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
if (type != UVWASI_FILETYPE_DIRECTORY)
return UVWASI_ENOTDIR;
- err = uvwasi__fd_table_insert(table,
+ err = uvwasi__fd_table_insert(uvwasi,
+ table,
fd,
path,
real_path,
@@ -338,7 +373,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_fd_table_t* table,
}
-uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
+uvwasi_errno_t uvwasi_fd_table_insert_fd(uvwasi_t* uvwasi,
+ struct uvwasi_fd_table_t* table,
const uv_file fd,
const int flags,
const char* path,
@@ -358,7 +394,8 @@ uvwasi_errno_t uvwasi_fd_table_insert_fd(struct uvwasi_fd_table_t* table,
if (r != UVWASI_ESUCCESS)
return r;
- r = uvwasi__fd_table_insert(table,
+ r = uvwasi__fd_table_insert(uvwasi,
+ table,
fd,
path,
path,
@@ -381,42 +418,68 @@ uvwasi_errno_t uvwasi_fd_table_get(const struct uvwasi_fd_table_t* table,
uvwasi_rights_t rights_base,
uvwasi_rights_t rights_inheriting) {
struct uvwasi_fd_wrap_t* entry;
+ uvwasi_errno_t err;
if (table == NULL || wrap == NULL)
return UVWASI_EINVAL;
- if (id >= table->size)
- return UVWASI_EBADF;
+
+ uv_rwlock_rdlock((uv_rwlock_t *)&table->rwlock);
+
+ if (id >= table->size) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
entry = &table->fds[id];
- if (entry->valid != 1 || entry->id != id)
- return UVWASI_EBADF;
+ if (entry->valid != 1 || entry->id != id) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
/* Validate that the fd has the necessary rights. */
if ((~entry->rights_base & rights_base) != 0 ||
- (~entry->rights_inheriting & rights_inheriting) != 0)
- return UVWASI_ENOTCAPABLE;
+ (~entry->rights_inheriting & rights_inheriting) != 0) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+ uv_mutex_lock(&entry->mutex);
*wrap = entry;
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_rdunlock((uv_rwlock_t *)&table->rwlock);
+ return err;
}
uvwasi_errno_t uvwasi_fd_table_remove(struct uvwasi_fd_table_t* table,
const uvwasi_fd_t id) {
struct uvwasi_fd_wrap_t* entry;
+ uvwasi_errno_t err;
if (table == NULL)
return UVWASI_EINVAL;
- if (id >= table->size)
- return UVWASI_EBADF;
+
+ uv_rwlock_wrlock(&table->rwlock);
+
+ if (id >= table->size) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
entry = &table->fds[id];
- if (entry->valid != 1 || entry->id != id)
- return UVWASI_EBADF;
+ if (entry->valid != 1 || entry->id != id) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
+ uv_mutex_destroy(&entry->mutex);
entry->valid = 0;
table->used--;
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_rwlock_wrunlock(&table->rwlock);
+ return err;
}
diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c
index 39a94b6d21..0f7c4c5d3a 100644
--- a/deps/uvwasi/src/uvwasi.c
+++ b/deps/uvwasi/src/uvwasi.c
@@ -19,26 +19,69 @@
#define UVWASI__READDIR_NUM_ENTRIES 1
#include "uvwasi.h"
+#include "uvwasi_alloc.h"
#include "uv.h"
#include "uv_mapping.h"
#include "fd_table.h"
#include "clocks.h"
+static void* default_malloc(size_t size, void* mem_user_data) {
+ return malloc(size);
+}
+
+static void default_free(void* ptr, void* mem_user_data) {
+ free(ptr);
+}
+
+static void* default_calloc(size_t nmemb, size_t size, void* mem_user_data) {
+ return calloc(nmemb, size);
+}
+
+static void* default_realloc(void* ptr, size_t size, void* mem_user_data) {
+ return realloc(ptr, size);
+}
+
+void* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size) {
+ return uvwasi->allocator->malloc(size, uvwasi->allocator->mem_user_data);
+}
+
+void uvwasi__free(const uvwasi_t* uvwasi, void* ptr) {
+ uvwasi->allocator->free(ptr, uvwasi->allocator->mem_user_data);
+}
+
+void* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size) {
+ return uvwasi->allocator->calloc(nmemb,
+ size,
+ uvwasi->allocator->mem_user_data);
+}
+
+void* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size) {
+ return uvwasi->allocator->realloc(ptr,
+ size,
+ uvwasi->allocator->mem_user_data);
+}
+
+static const uvwasi_mem_t default_allocator = {
+ NULL,
+ default_malloc,
+ default_free,
+ default_calloc,
+ default_realloc,
+};
+
static int uvwasi__is_absolute_path(const char* path, size_t path_len) {
- /* TODO(cjihrig): Add a Windows implementation. */
- return path != NULL && path_len > 0 && path[0] == SLASH;
+ /* It's expected that only Unix style paths will be generated by WASI. */
+ return path != NULL && path_len > 0 && path[0] == '/';
}
-static uvwasi_errno_t uvwasi__resolve_path(const struct uvwasi_fd_wrap_t* fd,
+static uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
+ const struct uvwasi_fd_wrap_t* fd,
const char* path,
size_t path_len,
char* resolved_path,
uvwasi_lookupflags_t flags) {
- /* TODO(cjihrig): path_len is treated as a size. Need to verify if path_len is
- really a string length or a size. Also need to verify if it is null
- terminated. */
uv_fs_t realpath_req;
uvwasi_errno_t err;
char* abs_path;
@@ -58,7 +101,7 @@ static uvwasi_errno_t uvwasi__resolve_path(const struct uvwasi_fd_wrap_t* fd,
if (1 == input_is_absolute) {
/* TODO(cjihrig): Revisit this. Copying is probably not necessary here. */
abs_size = path_len;
- abs_path = malloc(abs_size);
+ abs_path = uvwasi__malloc(uvwasi, abs_size);
if (abs_path == NULL) {
err = UVWASI_ENOMEM;
goto exit;
@@ -68,7 +111,7 @@ static uvwasi_errno_t uvwasi__resolve_path(const struct uvwasi_fd_wrap_t* fd,
} else {
/* Resolve the relative path to fd's real path. */
abs_size = path_len + strlen(fd->real_path) + 2;
- abs_path = malloc(abs_size);
+ abs_path = uvwasi__malloc(uvwasi, abs_size);
if (abs_path == NULL) {
err = UVWASI_ENOMEM;
goto exit;
@@ -146,7 +189,7 @@ static uvwasi_errno_t uvwasi__resolve_path(const struct uvwasi_fd_wrap_t* fd,
}
exit:
- free(abs_path);
+ uvwasi__free(uvwasi, abs_path);
return err;
}
@@ -185,13 +228,17 @@ static uvwasi_errno_t uvwasi__lseek(uv_file fd,
}
-static uvwasi_errno_t uvwasi__setup_iovs(uv_buf_t** buffers,
+static uvwasi_errno_t uvwasi__setup_iovs(const uvwasi_t* uvwasi,
+ uv_buf_t** buffers,
const uvwasi_iovec_t* iovs,
size_t iovs_len) {
uv_buf_t* bufs;
size_t i;
- bufs = malloc(iovs_len * sizeof(*bufs));
+ if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
+ return UVWASI_ENOMEM;
+
+ bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs));
if (bufs == NULL)
return UVWASI_ENOMEM;
@@ -203,13 +250,17 @@ static uvwasi_errno_t uvwasi__setup_iovs(uv_buf_t** buffers,
}
-static uvwasi_errno_t uvwasi__setup_ciovs(uv_buf_t** buffers,
+static uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi,
+ uv_buf_t** buffers,
const uvwasi_ciovec_t* iovs,
size_t iovs_len) {
uv_buf_t* bufs;
size_t i;
- bufs = malloc(iovs_len * sizeof(*bufs));
+ if ((iovs_len * sizeof(*bufs)) / (sizeof(*bufs)) != iovs_len)
+ return UVWASI_ENOMEM;
+
+ bufs = uvwasi__malloc(uvwasi, iovs_len * sizeof(*bufs));
if (bufs == NULL)
return UVWASI_ENOMEM;
@@ -236,6 +287,10 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
if (uvwasi == NULL || options == NULL || options->fd_table_size == 0)
return UVWASI_EINVAL;
+ uvwasi->allocator = options->allocator;
+ if (uvwasi->allocator == NULL)
+ uvwasi->allocator = &default_allocator;
+
uvwasi->argv_buf = NULL;
uvwasi->argv = NULL;
uvwasi->env_buf = NULL;
@@ -250,13 +305,13 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
uvwasi->argv_buf_size = args_size;
if (args_size > 0) {
- uvwasi->argv_buf = malloc(args_size);
+ uvwasi->argv_buf = uvwasi__malloc(uvwasi, args_size);
if (uvwasi->argv_buf == NULL) {
err = UVWASI_ENOMEM;
goto exit;
}
- uvwasi->argv = calloc(options->argc, sizeof(char*));
+ uvwasi->argv = uvwasi__calloc(uvwasi, options->argc, sizeof(char*));
if (uvwasi->argv == NULL) {
err = UVWASI_ENOMEM;
goto exit;
@@ -284,13 +339,13 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
uvwasi->env_buf_size = env_buf_size;
if (env_buf_size > 0) {
- uvwasi->env_buf = malloc(env_buf_size);
+ uvwasi->env_buf = uvwasi__malloc(uvwasi, env_buf_size);
if (uvwasi->env_buf == NULL) {
err = UVWASI_ENOMEM;
goto exit;
}
- uvwasi->env = calloc(env_count, sizeof(char*));
+ uvwasi->env = uvwasi__calloc(uvwasi, env_count, sizeof(char*));
if (uvwasi->env == NULL) {
err = UVWASI_ENOMEM;
goto exit;
@@ -313,7 +368,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
}
}
- err = uvwasi_fd_table_init(&uvwasi->fds, options->fd_table_size);
+ err = uvwasi_fd_table_init(uvwasi, &uvwasi->fds, options->fd_table_size);
if (err != UVWASI_ESUCCESS)
goto exit;
@@ -336,7 +391,8 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) {
goto exit;
}
- err = uvwasi_fd_table_insert_preopen(&uvwasi->fds,
+ err = uvwasi_fd_table_insert_preopen(uvwasi,
+ &uvwasi->fds,
open_req.result,
options->preopens[i].mapped_path,
realpath_req.ptr);
@@ -359,11 +415,11 @@ void uvwasi_destroy(uvwasi_t* uvwasi) {
if (uvwasi == NULL)
return;
- uvwasi_fd_table_free(&uvwasi->fds);
- free(uvwasi->argv_buf);
- free(uvwasi->argv);
- free(uvwasi->env_buf);
- free(uvwasi->env);
+ uvwasi_fd_table_free(uvwasi, &uvwasi->fds);
+ uvwasi__free(uvwasi, uvwasi->argv_buf);
+ uvwasi__free(uvwasi, uvwasi->argv);
+ uvwasi__free(uvwasi, uvwasi->env_buf);
+ uvwasi__free(uvwasi, uvwasi->env);
uvwasi->argv_buf = NULL;
uvwasi->argv = NULL;
uvwasi->env_buf = NULL;
@@ -385,6 +441,7 @@ uvwasi_errno_t uvwasi_embedder_remap_fd(uvwasi_t* uvwasi,
return err;
wrap->fd = new_host_fd;
+ uv_mutex_unlock(&wrap->mutex);
return UVWASI_ESUCCESS;
}
@@ -543,12 +600,15 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
+ err = UVWASI_ESUCCESS;
+
#ifdef POSIX_FADV_NORMAL
r = posix_fadvise(wrap->fd, offset, len, mapped_advice);
if (r != 0)
- return uvwasi__translate_uv_error(uv_translate_sys_error(r));
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(r));
#endif /* POSIX_FADV_NORMAL */
- return UVWASI_ESUCCESS;
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -579,23 +639,32 @@ uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi,
race condition prone combination of fstat() + ftruncate(). */
#if defined(__POSIX__)
r = posix_fallocate(wrap->fd, offset, len);
- if (r != 0)
- return uvwasi__translate_uv_error(uv_translate_sys_error(r));
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(r));
+ goto exit;
+ }
#else
r = uv_fs_fstat(NULL, &req, wrap->fd, NULL);
st_size = req.statbuf.st_size;
uv_fs_req_cleanup(&req);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
if (st_size < offset + len) {
r = uv_fs_ftruncate(NULL, &req, wrap->fd, offset + len, NULL);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
}
#endif /* __POSIX__ */
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -613,6 +682,7 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
return err;
r = uv_fs_close(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -640,6 +710,7 @@ uvwasi_errno_t uvwasi_fd_datasync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
return err;
r = uv_fs_fdatasync(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -672,11 +743,15 @@ uvwasi_errno_t uvwasi_fd_fdstat_get(uvwasi_t* uvwasi,
buf->fs_flags = 0; /* TODO(cjihrig): Missing Windows support. */
#else
r = fcntl(wrap->fd, F_GETFL);
- if (r < 0)
- return uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ if (r < 0) {
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
+ }
buf->fs_flags = r;
#endif /* _WIN32 */
+ uv_mutex_unlock(&wrap->mutex);
return UVWASI_ESUCCESS;
}
@@ -731,9 +806,12 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_flags(uvwasi_t* uvwasi,
r = fcntl(wrap->fd, F_SETFL, mapped_flags);
if (r < 0)
- return uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
+ else
+ err = UVWASI_ESUCCESS;
- return UVWASI_ESUCCESS;
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
#endif /* _WIN32 */
}
@@ -754,16 +832,23 @@ uvwasi_errno_t uvwasi_fd_fdstat_set_rights(uvwasi_t* uvwasi,
return err;
/* Check for attempts to add new permissions. */
- if ((fs_rights_base | wrap->rights_base) > wrap->rights_base)
- return UVWASI_ENOTCAPABLE;
+ if ((fs_rights_base | wrap->rights_base) > wrap->rights_base) {
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
+ }
+
if ((fs_rights_inheriting | wrap->rights_inheriting) >
wrap->rights_inheriting) {
- return UVWASI_ENOTCAPABLE;
+ err = UVWASI_ENOTCAPABLE;
+ goto exit;
}
wrap->rights_base = fs_rights_base;
wrap->rights_inheriting = fs_rights_inheriting;
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -788,14 +873,16 @@ uvwasi_errno_t uvwasi_fd_filestat_get(uvwasi_t* uvwasi,
r = uv_fs_fstat(NULL, &req, wrap->fd, NULL);
if (r != 0) {
- uv_fs_req_cleanup(&req);
- return uvwasi__translate_uv_error(r);
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
}
uvwasi__stat_to_filestat(&req.statbuf, buf);
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
-
- return UVWASI_ESUCCESS;
+ return err;
}
@@ -820,6 +907,7 @@ uvwasi_errno_t uvwasi_fd_filestat_set_size(uvwasi_t* uvwasi,
return err;
r = uv_fs_ftruncate(NULL, &req, wrap->fd, st_size, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -858,6 +946,7 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
/* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
r = uv_fs_futime(NULL, &req, wrap->fd, st_atim, st_mtim, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -891,14 +980,17 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__setup_iovs(&bufs, iovs, iovs_len);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uvread = req.result;
uv_fs_req_cleanup(&req);
- free(bufs);
+ uvwasi__free(uvwasi, bufs);
if (r < 0)
return uvwasi__translate_uv_error(r);
@@ -920,12 +1012,17 @@ uvwasi_errno_t uvwasi_fd_prestat_get(uvwasi_t* uvwasi,
err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
- if (wrap->preopen != 1)
- return UVWASI_EINVAL;
+ if (wrap->preopen != 1) {
+ err = UVWASI_EINVAL;
+ goto exit;
+ }
buf->pr_type = UVWASI_PREOPENTYPE_DIR;
buf->u.dir.pr_name_len = strlen(wrap->path) + 1;
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -943,15 +1040,22 @@ uvwasi_errno_t uvwasi_fd_prestat_dir_name(uvwasi_t* uvwasi,
err = uvwasi_fd_table_get(&uvwasi->fds, fd, &wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
- if (wrap->preopen != 1)
- return UVWASI_EBADF;
+ if (wrap->preopen != 1) {
+ err = UVWASI_EBADF;
+ goto exit;
+ }
size = strlen(wrap->path) + 1;
- if (size > path_len)
- return UVWASI_ENOBUFS;
+ if (size > path_len) {
+ err = UVWASI_ENOBUFS;
+ goto exit;
+ }
memcpy(path, wrap->path, size);
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -979,14 +1083,17 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__setup_ciovs(&bufs, iovs, iovs_len);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, offset, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uvwritten = req.result;
uv_fs_req_cleanup(&req);
- free(bufs);
+ uvwasi__free(uvwasi, bufs);
if (r < 0)
return uvwasi__translate_uv_error(r);
@@ -1015,14 +1122,17 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__setup_iovs(&bufs, iovs, iovs_len);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_read(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uvread = req.result;
uv_fs_req_cleanup(&req);
- free(bufs);
+ uvwasi__free(uvwasi, bufs);
if (r < 0)
return uvwasi__translate_uv_error(r);
@@ -1066,8 +1176,10 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
/* Open the directory. */
r = uv_fs_opendir(NULL, &req, wrap->real_path, NULL);
- if (r != 0)
+ if (r != 0) {
+ uv_mutex_unlock(&wrap->mutex);
return uvwasi__translate_uv_error(r);
+ }
/* Setup for reading the directory. */
dir = req.ptr;
@@ -1161,6 +1273,7 @@ uvwasi_errno_t uvwasi_fd_readdir(uvwasi_t* uvwasi,
exit:
/* Close the directory. */
r = uv_fs_closedir(NULL, &req, dir, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
return uvwasi__translate_uv_error(r);
@@ -1181,22 +1294,31 @@ uvwasi_errno_t uvwasi_fd_renumber(uvwasi_t* uvwasi,
if (uvwasi == NULL)
return UVWASI_EINVAL;
+ if (from == to)
+ return UVWASI_ESUCCESS;
+
err = uvwasi_fd_table_get(&uvwasi->fds, from, &from_wrap, 0, 0);
if (err != UVWASI_ESUCCESS)
return err;
err = uvwasi_fd_table_get(&uvwasi->fds, to, &to_wrap, 0, 0);
- if (err != UVWASI_ESUCCESS)
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&from_wrap->mutex);
return err;
+ }
r = uv_fs_close(NULL, &req, to_wrap->fd, NULL);
uv_fs_req_cleanup(&req);
- if (r != 0)
+ if (r != 0) {
+ uv_mutex_unlock(&from_wrap->mutex);
+ uv_mutex_unlock(&to_wrap->mutex);
return uvwasi__translate_uv_error(r);
+ }
memcpy(to_wrap, from_wrap, sizeof(*to_wrap));
to_wrap->id = to;
-
+ uv_mutex_unlock(&from_wrap->mutex);
+ uv_mutex_unlock(&to_wrap->mutex);
return uvwasi_fd_table_remove(&uvwasi->fds, from);
}
@@ -1216,7 +1338,9 @@ uvwasi_errno_t uvwasi_fd_seek(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- return uvwasi__lseek(wrap->fd, offset, whence, newoffset);
+ err = uvwasi__lseek(wrap->fd, offset, whence, newoffset);
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -1238,6 +1362,7 @@ uvwasi_errno_t uvwasi_fd_sync(uvwasi_t* uvwasi, uvwasi_fd_t fd) {
return err;
r = uv_fs_fsync(NULL, &req, wrap->fd, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -1260,7 +1385,9 @@ uvwasi_errno_t uvwasi_fd_tell(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- return uvwasi__lseek(wrap->fd, 0, UVWASI_WHENCE_CUR, offset);
+ err = uvwasi__lseek(wrap->fd, 0, UVWASI_WHENCE_CUR, offset);
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -1283,14 +1410,17 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__setup_ciovs(&bufs, iovs, iovs_len);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uvwritten = req.result;
uv_fs_req_cleanup(&req);
- free(bufs);
+ uvwasi__free(uvwasi, bufs);
if (r < 0)
return uvwasi__translate_uv_error(r);
@@ -1321,17 +1451,22 @@ uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, 0);
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
r = uv_fs_mkdir(NULL, &req, resolved_path, 0777, NULL);
uv_fs_req_cleanup(&req);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -1358,20 +1493,28 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, flags);
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
+ path,
+ path_len,
+ resolved_path,
+ flags);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
r = uv_fs_stat(NULL, &req, resolved_path, NULL);
if (r != 0) {
uv_fs_req_cleanup(&req);
- return uvwasi__translate_uv_error(r);
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
}
uvwasi__stat_to_filestat(&req.statbuf, buf);
uv_fs_req_cleanup(&req);
-
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -1406,18 +1549,28 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, flags);
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
+ path,
+ path_len,
+ resolved_path,
+ flags);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
/* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
r = uv_fs_utime(NULL, &req, resolved_path, st_atim, st_mtim, NULL);
uv_fs_req_cleanup(&req);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&wrap->mutex);
+ return err;
}
@@ -1440,44 +1593,68 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
if (uvwasi == NULL || old_path == NULL || new_path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
- old_fd,
- &old_wrap,
- UVWASI_RIGHT_PATH_LINK_SOURCE,
- 0);
- if (err != UVWASI_ESUCCESS)
- return err;
+ if (old_fd == new_fd) {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_LINK_SOURCE |
+ UVWASI_RIGHT_PATH_LINK_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
- err = uvwasi_fd_table_get(&uvwasi->fds,
- new_fd,
- &new_wrap,
- UVWASI_RIGHT_PATH_LINK_TARGET,
- 0);
- if (err != UVWASI_ESUCCESS)
- return err;
+ new_wrap = old_wrap;
+ } else {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_LINK_SOURCE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ new_fd,
+ &new_wrap,
+ UVWASI_RIGHT_PATH_LINK_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&old_wrap->mutex);
+ return err;
+ }
+ }
- err = uvwasi__resolve_path(old_wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ old_wrap,
old_path,
old_path_len,
resolved_old_path,
old_flags);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
- err = uvwasi__resolve_path(new_wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ new_wrap,
new_path,
new_path_len,
resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
r = uv_fs_link(NULL, &req, resolved_old_path, resolved_new_path, NULL);
uv_fs_req_cleanup(&req);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&old_wrap->mutex);
+ if (old_fd != new_fd)
+ uv_mutex_unlock(&new_wrap->mutex);
+ return err;
}
@@ -1560,39 +1737,49 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(dirfd_wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ dirfd_wrap,
path,
path_len,
resolved_path,
dirflags);
- if (err != UVWASI_ESUCCESS)
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
return err;
+ }
r = uv_fs_open(NULL, &req, resolved_path, flags, 0666, NULL);
uv_fs_req_cleanup(&req);
- if (r < 0)
+ if (r < 0) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
return uvwasi__translate_uv_error(r);
+ }
- err = uvwasi_fd_table_insert_fd(&uvwasi->fds,
+ err = uvwasi_fd_table_insert_fd(uvwasi,
+ &uvwasi->fds,
r,
flags,
resolved_path,
fs_rights_base,
fs_rights_inheriting,
&wrap);
- if (err != UVWASI_ESUCCESS)
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
goto close_file_and_error_exit;
+ }
/* Not all platforms support UV_FS_O_DIRECTORY, so enforce it here as well. */
if ((o_flags & UVWASI_O_DIRECTORY) != 0 &&
wrap.type != UVWASI_FILETYPE_DIRECTORY) {
+ uv_mutex_unlock(&dirfd_wrap->mutex);
uvwasi_fd_table_remove(&uvwasi->fds, wrap.id);
err = UVWASI_ENOTDIR;
goto close_file_and_error_exit;
}
*fd = wrap.id;
+ uv_mutex_unlock(&dirfd_wrap->mutex);
return UVWASI_ESUCCESS;
close_file_and_error_exit:
@@ -1627,11 +1814,14 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, 0);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_readlink(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
if (r != 0) {
uv_fs_req_cleanup(&req);
return uvwasi__translate_uv_error(r);
@@ -1672,11 +1862,14 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, 0);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_rmdir(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
@@ -1704,44 +1897,68 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
if (uvwasi == NULL || old_path == NULL || new_path == NULL)
return UVWASI_EINVAL;
- err = uvwasi_fd_table_get(&uvwasi->fds,
- old_fd,
- &old_wrap,
- UVWASI_RIGHT_PATH_RENAME_SOURCE,
- 0);
- if (err != UVWASI_ESUCCESS)
- return err;
-
- err = uvwasi_fd_table_get(&uvwasi->fds,
- new_fd,
- &new_wrap,
- UVWASI_RIGHT_PATH_RENAME_TARGET,
- 0);
- if (err != UVWASI_ESUCCESS)
- return err;
+ if (old_fd == new_fd) {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_RENAME_SOURCE |
+ UVWASI_RIGHT_PATH_RENAME_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+ new_wrap = old_wrap;
+ } else {
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ old_fd,
+ &old_wrap,
+ UVWASI_RIGHT_PATH_RENAME_SOURCE,
+ 0);
+ if (err != UVWASI_ESUCCESS)
+ return err;
+
+ err = uvwasi_fd_table_get(&uvwasi->fds,
+ new_fd,
+ &new_wrap,
+ UVWASI_RIGHT_PATH_RENAME_TARGET,
+ 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&old_wrap->mutex);
+ return err;
+ }
+ }
- err = uvwasi__resolve_path(old_wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ old_wrap,
old_path,
old_path_len,
resolved_old_path,
0);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
- err = uvwasi__resolve_path(new_wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ new_wrap,
new_path,
new_path_len,
resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
- return err;
+ goto exit;
r = uv_fs_rename(NULL, &req, resolved_old_path, resolved_new_path, NULL);
uv_fs_req_cleanup(&req);
- if (r != 0)
- return uvwasi__translate_uv_error(r);
+ if (r != 0) {
+ err = uvwasi__translate_uv_error(r);
+ goto exit;
+ }
- return UVWASI_ESUCCESS;
+ err = UVWASI_ESUCCESS;
+exit:
+ uv_mutex_unlock(&old_wrap->mutex);
+ if (old_fd != new_fd)
+ uv_mutex_unlock(&new_wrap->mutex);
+
+ return err;
}
@@ -1768,16 +1985,20 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap,
+ err = uvwasi__resolve_path(uvwasi,
+ wrap,
new_path,
new_path_len,
resolved_new_path,
0);
- if (err != UVWASI_ESUCCESS)
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
/* Windows support may require setting the flags option. */
r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
return uvwasi__translate_uv_error(r);
@@ -1807,11 +2028,14 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;
- err = uvwasi__resolve_path(wrap, path, path_len, resolved_path, 0);
- if (err != UVWASI_ESUCCESS)
+ err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
+ if (err != UVWASI_ESUCCESS) {
+ uv_mutex_unlock(&wrap->mutex);
return err;
+ }
r = uv_fs_unlink(NULL, &req, resolved_path, NULL);
+ uv_mutex_unlock(&wrap->mutex);
uv_fs_req_cleanup(&req);
if (r != 0)
diff --git a/deps/uvwasi/src/uvwasi_alloc.h b/deps/uvwasi/src/uvwasi_alloc.h
new file mode 100644
index 0000000000..1486f31391
--- /dev/null
+++ b/deps/uvwasi/src/uvwasi_alloc.h
@@ -0,0 +1,11 @@
+#ifndef __UVWASI_ALLOC_H__
+#define __UVWASI_ALLOC_H__
+
+#include "uvwasi.h"
+
+void* uvwasi__malloc(const uvwasi_t* uvwasi, size_t size);
+void uvwasi__free(const uvwasi_t* uvwasi, void* ptr);
+void* uvwasi__calloc(const uvwasi_t* uvwasi, size_t nmemb, size_t size);
+void* uvwasi__realloc(const uvwasi_t* uvwasi, void* ptr, size_t size);
+
+#endif