Skip to content

Commit 71634e0

Browse files
authored
WasmFS JS API: Implement read (#19504)
1 parent ca3c1f5 commit 71634e0

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ jobs:
529529
wasmfs.test_futimens
530530
wasmfs.test_unistd_links_memfs
531531
wasmfs.test_fcntl_open
532+
wasmfs.test_fs_js_api
532533
wasmfs.test_freetype"
533534
test-wasm2js1:
534535
executor: bionic

emcc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,6 +2322,8 @@ def phase_linker_setup(options, state, newargs):
23222322
'_wasmfs_unlink',
23232323
'_wasmfs_chdir',
23242324
'_wasmfs_rmdir',
2325+
'_wasmfs_read',
2326+
'_wasmfs_pread',
23252327
'_wasmfs_symlink',
23262328
'_wasmfs_chmod',
23272329
'_wasmfs_fchmod',

src/library_wasmfs.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,26 @@ FS.createPreloadedFile = FS_createPreloadedFile;
143143
});
144144
},
145145
// TODO: read
146+
read: (fd, buffer, offset, length, position) => {
147+
var seeking = typeof position != 'undefined';
148+
149+
var dataBuffer = _malloc(length);
150+
151+
var bytesRead;
152+
if (seeking) {
153+
bytesRead = __wasmfs_pread(fd, dataBuffer, length, position);
154+
} else {
155+
bytesRead = __wasmfs_read(fd, dataBuffer, length);
156+
}
157+
bytesRead = FS.handleError(bytesRead);
158+
159+
for (var i = 0; i < length; i++) {
160+
buffer[offset + i] = {{{ makeGetValue('dataBuffer', 'i', 'i8')}}}
161+
}
162+
163+
_free(dataBuffer);
164+
return bytesRead;
165+
},
146166
// TODO: write
147167
// TODO: allocate
148168
// TODO: mmap

system/lib/wasmfs/js_api.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,32 @@ int _wasmfs_lchmod(char* path, mode_t mode) {
145145
return __syscall_fchmodat(AT_FDCWD, (intptr_t)path, mode, AT_SYMLINK_NOFOLLOW);
146146
}
147147

148+
int _wasmfs_read(int fd, void *buf, size_t count) {
149+
__wasi_iovec_t iovs[1];
150+
iovs[0].buf = (uint8_t *)buf;
151+
iovs[0].buf_len = count;
152+
153+
__wasi_size_t numBytes;
154+
__wasi_errno_t err = __wasi_fd_read(fd, iovs, 1, &numBytes);
155+
if (err) {
156+
return -err;
157+
}
158+
return numBytes;
159+
}
160+
161+
int _wasmfs_pread(int fd, void *buf, size_t count, off_t offset) {
162+
__wasi_iovec_t iovs[1];
163+
iovs[0].buf = (uint8_t *)buf;
164+
iovs[0].buf_len = count;
165+
166+
__wasi_size_t numBytes;
167+
__wasi_errno_t err = __wasi_fd_pread(fd, iovs, 1, offset, &numBytes);
168+
if (err) {
169+
return -err;
170+
}
171+
return numBytes;
172+
}
173+
148174
int _wasmfs_close(int fd) {
149175
return __wasi_fd_close(fd);
150176
}

test/fs/test_fs_js_api.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,51 @@ int main() {
3737
#endif
3838
);
3939

40+
/********** test FS.read() **********/
41+
EM_ASM(
42+
FS.writeFile("readtestfile", 'a=1_b=2_');
43+
44+
// Test read variant, checking that the file offset moves correctly.
45+
var buf = new Uint8Array(8);
46+
var stream = FS.open("readtestfile", "r");
47+
var numRead = FS.read(stream, buf, 0, 4);
48+
assert(numRead == 4);
49+
assert((new TextDecoder().decode(buf.subarray(0, 4))) === "a=1_");
50+
numRead = FS.read(stream, buf, 4, 4);
51+
assert(numRead == 4);
52+
assert((new TextDecoder().decode(buf)) == 'a=1_b=2_');
53+
54+
// Test pread variant.
55+
stream = FS.open("readtestfile", "r");
56+
var extraBuf = new Uint8Array(8);
57+
numRead = FS.read(stream, extraBuf, 0, 4, 0);
58+
assert(numRead == 4);
59+
assert((new TextDecoder().decode(extraBuf.subarray(0, 4))) == 'a=1_');
60+
61+
// Check that pread did not move the file offset (Offset begins at 0).
62+
var doubleBuf = new Uint8Array(8);
63+
var firstNumRead = FS.read(stream, doubleBuf, 0, 4);
64+
var secondNumRead = FS.read(stream, doubleBuf, 4, 4);
65+
assert(firstNumRead == 4 && secondNumRead == 4);
66+
assert((new TextDecoder().decode(doubleBuf)) == 'a=1_b=2_');
67+
68+
// Check that full read works.
69+
stream = FS.open("readtestfile", "r");
70+
var fullBuf = new Uint8Array(8);
71+
numRead = FS.read(stream, fullBuf, 0, 8);
72+
assert(numRead == 8);
73+
assert((new TextDecoder().decode(fullBuf)) == 'a=1_b=2_');
74+
75+
FS.close(stream);
76+
var ex;
77+
try {
78+
FS.read(stream, buf, 4, 4);
79+
} catch (err) {
80+
ex = err;
81+
}
82+
assert(ex.name === 'ErrnoError' && ex.errno == 8 /* EBADF */);
83+
);
84+
4085
/********** test FS.close() **********/
4186
EM_ASM(
4287
FS.writeFile("closetestfile", 'a=1\nb=2\n');

0 commit comments

Comments
 (0)