Skip to content

Commit 6387beb

Browse files
authored
WasmFS JS API: Implement readlink (#19587)
1 parent 4113a59 commit 6387beb

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

emcc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,7 @@ def phase_linker_setup(options, state, newargs):
23482348
'_wasmfs_lchmod',
23492349
'_wasmfs_llseek',
23502350
'_wasmfs_identify',
2351+
'_wasmfs_readlink',
23512352
'_wasmfs_readdir_start',
23522353
'_wasmfs_readdir_get',
23532354
'_wasmfs_readdir_finish',

src/library_wasmfs.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,13 @@ FS.createPreloadedFile = FS_createPreloadedFile;
228228
_free(dataBuffer);
229229
return ret;
230230
}),
231-
symlink: (target, linkpath) => withStackSave(() => {
232-
var targetBuffer = stringToUTF8OnStack(target);
233-
var linkpathBuffer = stringToUTF8OnStack(linkpath);
234-
return __wasmfs_symlink(targetBuffer, linkpathBuffer);
235-
}),
236-
// TODO: readlink
231+
symlink: (target, linkpath) => withStackSave(() => (
232+
__wasmfs_symlink(stringToUTF8OnStack(target), stringToUTF8OnStack(linkpath))
233+
)),
234+
readlink: (path) => {
235+
var readBuffer = FS.handleError(withStackSave(() => __wasmfs_readlink(stringToUTF8OnStack(path))));
236+
return UTF8ToString(readBuffer);
237+
},
237238
statBufToObject : (statBuf) => {
238239
// i53/u53 are enough for times and ino in practice.
239240
return {

system/lib/wasmfs/js_api.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ int _wasmfs_symlink(char* old_path, char* new_path) {
147147
return __syscall_symlink((intptr_t)old_path, (intptr_t)new_path);
148148
}
149149

150+
intptr_t _wasmfs_readlink(char* path) {
151+
static thread_local void* readBuf = nullptr;
152+
readBuf = realloc(readBuf, PATH_MAX);
153+
int err = __syscall_readlinkat(AT_FDCWD, (intptr_t)path, (intptr_t)readBuf, PATH_MAX);
154+
if (err < 0) {
155+
return err;
156+
}
157+
return (intptr_t)readBuf;
158+
}
159+
150160
int _wasmfs_write(int fd, void *buf, size_t count) {
151161
__wasi_ciovec_t iovs[1];
152162
iovs[0].buf = (uint8_t*)buf;

test/fs/test_fs_js_api.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
#include <emscripten/emscripten.h>
22
#include <stdio.h>
3+
#include <unistd.h>
34
#include <sys/stat.h>
45
#include <assert.h>
56
#include <fcntl.h>
67

8+
EM_JS(void, test_fs_readlink,(), {
9+
FS.writeFile('/readlinktestfile', "");
10+
FS.symlink('/readlinktestfile', '/readlinksymlink');
11+
12+
var symlinkString = FS.readlink('readlinksymlink');
13+
assert(symlinkString === '/readlinktestfile');
14+
15+
var ex;
16+
try {
17+
FS.readlink('nonexistent');
18+
} catch (err) {
19+
ex = err;
20+
}
21+
assert(ex.name === "ErrnoError" && ex.errno === 44 /* ENOENT */);
22+
23+
try {
24+
FS.readlink('readlinktestfile');
25+
} catch (err) {
26+
ex = err;
27+
}
28+
assert(ex.name === "ErrnoError" && ex.errno === 28 /* EINVAL */);
29+
});
30+
731
void test_fs_allocate() {
832
EM_ASM(
933
FS.writeFile("allocatetestfile", 'a=1\nb=2\n');
@@ -125,7 +149,7 @@ int main() {
125149
var ex;
126150
try {
127151
FS.open('filenothere', 'r');
128-
} catch(err) {
152+
} catch (err) {
129153
ex = err;
130154
}
131155
assert(ex.name === "ErrnoError" && ex.errno === 44 /* ENOENT */);
@@ -281,11 +305,11 @@ int main() {
281305
var ex;
282306
try {
283307
FS.close(file);
284-
} catch(err) {
308+
} catch (err) {
285309
ex = err;
286310
}
287311

288-
assert(ex.name === "ErrnoError" && ex.errno === 8 /* EBADF */)
312+
assert(ex.name === "ErrnoError" && ex.errno === 8 /* EBADF */);
289313
);
290314

291315
/********** test FS.mknod() **********/
@@ -305,7 +329,7 @@ int main() {
305329
assert(mknodStats.st_mode & 0400);
306330

307331
test_fs_allocate();
308-
332+
test_fs_readlink();
309333
test_fs_truncate();
310334

311335
remove("mknodtest");
@@ -314,6 +338,9 @@ int main() {
314338
remove("renametestfile");
315339
remove("readtestfile");
316340
remove("closetestfile");
341+
remove("testfile");
342+
remove("closetestfile");
343+
remove("/testdir");
317344

318345
puts("success");
319346
}

0 commit comments

Comments
 (0)