Skip to content

Commit

Permalink
add --wasi-mapdir option
Browse files Browse the repository at this point in the history
intended to be similar to wasmtime --mapdir
  • Loading branch information
yamt committed Feb 1, 2023
1 parent 9f4350f commit dc896e9
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 12 deletions.
14 changes: 14 additions & 0 deletions cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum longopt {
opt_version,
opt_wasi,
opt_wasi_dir,
opt_wasi_mapdir,
opt_wasi_env,
};

Expand Down Expand Up @@ -110,6 +111,12 @@ const struct option longopts[] = {
NULL,
opt_wasi_dir,
},
{
"wasi-mapdir",
required_argument,
NULL,
opt_wasi_mapdir,
},
{
"wasi-env",
required_argument,
Expand Down Expand Up @@ -203,6 +210,13 @@ main(int argc, char *const *argv)
goto fail;
}
break;
case opt_wasi_mapdir:
ret = toywasm_repl_set_wasi_prestat_mapdir(state,
optarg);
if (ret != 0) {
goto fail;
}
break;
case opt_wasi_env:
nenvs++;
envs = realloc(envs, nenvs * sizeof(*envs));
Expand Down
10 changes: 10 additions & 0 deletions cli/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ toywasm_repl_set_wasi_prestat(struct repl_state *state, const char *path)
return wasi_instance_prestat_add(state->wasi, path);
}

int
toywasm_repl_set_wasi_prestat_mapdir(struct repl_state *state,
const char *path)
{
if (state->wasi == NULL) {
return EPROTO;
}
return wasi_instance_prestat_add_mapdir(state->wasi, path);
}

int
find_mod(struct repl_state *state, const char *modname,
struct repl_module_state **modp)
Expand Down
2 changes: 2 additions & 0 deletions cli/repl.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ int toywasm_repl_set_wasi_args(struct repl_state *state, int argc,
int toywasm_repl_set_wasi_environ(struct repl_state *state, int nenvs,
char *const *envs);
int toywasm_repl_set_wasi_prestat(struct repl_state *state, const char *path);
int toywasm_repl_set_wasi_prestat_mapdir(struct repl_state *state,
const char *path);
76 changes: 64 additions & 12 deletions lib/wasi.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct wasi_fdinfo {
* hostfd == -1
*/
char *prestat_path;
char *wasm_path; /* NULL means same as prestat_path */
int hostfd;
DIR *dir;
uint32_t refcount;
Expand Down Expand Up @@ -307,6 +308,7 @@ wasi_fdinfo_alloc(void)
fdinfo->hostfd = -1;
fdinfo->dir = NULL;
fdinfo->prestat_path = NULL;
fdinfo->wasm_path = NULL;
fdinfo->refcount = 0;
fdinfo->blocking = 1;
assert(wasi_fdinfo_unused(fdinfo));
Expand Down Expand Up @@ -378,6 +380,7 @@ wasi_fdinfo_release(struct wasi_instance *wasi, struct wasi_fdinfo *fdinfo)
if (fdinfo->refcount == 0) {
assert(fdinfo->hostfd == -1);
free(fdinfo->prestat_path);
free(fdinfo->wasm_path);
free(fdinfo);
}
toywasm_mutex_unlock(&wasi->lock);
Expand Down Expand Up @@ -421,7 +424,9 @@ wasi_fdinfo_close(struct wasi_fdinfo *fdinfo)
}
fdinfo->dir = NULL;
free(fdinfo->prestat_path);
free(fdinfo->wasm_path);
fdinfo->prestat_path = NULL;
fdinfo->wasm_path = NULL;
return ret;
}

Expand Down Expand Up @@ -526,6 +531,7 @@ wasi_fd_add(struct wasi_instance *wasi, int hostfd, char *path,
fdinfo->hostfd = hostfd;
fdinfo->dir = NULL;
fdinfo->prestat_path = path;
fdinfo->wasm_path = NULL;
fdinfo->blocking = (fdflags & WASI_FDFLAG_NONBLOCK) == 0;
toywasm_mutex_lock(&wasi->lock);
ret = wasi_fd_alloc(wasi, &wasifd);
Expand Down Expand Up @@ -1940,7 +1946,11 @@ wasi_fd_prestat_get(struct exec_context *ctx, struct host_instance *hi,
struct wasi_fd_prestat st;
memset(&st, 0, sizeof(st));
st.type = WASI_PREOPEN_TYPE_DIR;
st.dir_name_len = host_to_le32(strlen(fdinfo->prestat_path));
const char *prestat_path = fdinfo->prestat_path;
if (fdinfo->wasm_path != NULL) {
prestat_path = fdinfo->wasm_path;
}
st.dir_name_len = host_to_le32(strlen(prestat_path));
host_ret = wasi_copyout(ctx, &st, retp, sizeof(st));
fail:
wasi_fdinfo_release(wasi, fdinfo);
Expand Down Expand Up @@ -1977,13 +1987,17 @@ wasi_fd_prestat_dir_name(struct exec_context *ctx, struct host_instance *hi,
xlog_trace("wasm fd %" PRIu32 " is prestat %s", wasifd,
fdinfo->prestat_path);

size_t len = strlen(fdinfo->prestat_path);
const char *prestat_path = fdinfo->prestat_path;
if (fdinfo->wasm_path != NULL) {
prestat_path = fdinfo->wasm_path;
}
size_t len = strlen(prestat_path);
if (len != pathlen) {
xlog_trace("pathlen mismatch %zu != %" PRIu32, len, pathlen);
ret = EINVAL;
goto fail;
}
host_ret = wasi_copyout(ctx, fdinfo->prestat_path, path, len);
host_ret = wasi_copyout(ctx, prestat_path, path, len);
fail:
wasi_fdinfo_release(wasi, fdinfo);
if (host_ret == 0) {
Expand Down Expand Up @@ -3504,31 +3518,69 @@ wasi_instance_set_environ(struct wasi_instance *inst, int nenvs,
#endif
}

int
wasi_instance_prestat_add(struct wasi_instance *wasi, const char *path)
static int
wasi_instance_prestat_add_common(struct wasi_instance *wasi, const char *path,
bool is_mapdir)
{
struct wasi_fdinfo *fdinfo = NULL;
char *host_path = NULL;
char *wasm_path = NULL;
uint32_t wasifd;
int ret;
xlog_trace("prestat adding %s", path);
xlog_trace("prestat adding mapdir %s", path);

if (is_mapdir) {
/*
* <wasm dir>::<host dir>
*
* intended to be compatible with wasmtime's --mapdir
*/

const char *colon = strchr(path, ':');
if (colon == NULL || colon[1] != ':') {
ret = EINVAL;
goto fail;
}
wasm_path = strndup(path, colon - path);
host_path = strdup(colon + 2);
} else {
host_path = strdup(path);
}
fdinfo = wasi_fdinfo_alloc();
if (fdinfo == NULL) {
return ENOMEM;
if (host_path == NULL || (is_mapdir && wasm_path == NULL) ||
fdinfo == NULL) {
ret = ENOMEM;
goto fail;
}
fdinfo->prestat_path = strdup(path);
fdinfo->prestat_path = host_path;
fdinfo->wasm_path = wasm_path;
toywasm_mutex_lock(&wasi->lock);
ret = wasi_fd_alloc(wasi, &wasifd);
if (ret != 0) {
toywasm_mutex_unlock(&wasi->lock);
free(fdinfo->prestat_path);
free(fdinfo);
return ret;
goto fail;
}
wasi_fd_affix(wasi, wasifd, fdinfo);
toywasm_mutex_unlock(&wasi->lock);
xlog_trace("prestat added %s (%s)", path, fdinfo->prestat_path);
return 0;
fail:
free(host_path);
free(wasm_path);
free(fdinfo);
return ret;
}

int
wasi_instance_prestat_add(struct wasi_instance *wasi, const char *path)
{
return wasi_instance_prestat_add_common(wasi, path, false);
}

int
wasi_instance_prestat_add_mapdir(struct wasi_instance *wasi, const char *path)
{
return wasi_instance_prestat_add_common(wasi, path, true);
}

void
Expand Down
2 changes: 2 additions & 0 deletions lib/wasi.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ void wasi_instance_set_environ(struct wasi_instance *inst, int nenvs,
char *const *envs);
void wasi_instance_destroy(struct wasi_instance *inst);
int wasi_instance_prestat_add(struct wasi_instance *inst, const char *path);
int wasi_instance_prestat_add_mapdir(struct wasi_instance *inst,
const char *path);
int import_object_create_for_wasi(struct wasi_instance *wasi,
struct import_object **impp);

Expand Down

0 comments on commit dc896e9

Please sign in to comment.