Skip to content

Commit 90858c8

Browse files
authored
WasmFS JS API: Implement truncate (#19543)
1 parent 9a7b350 commit 90858c8

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed

emcc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,8 @@ def phase_linker_setup(options, state, newargs):
23382338
'_wasmfs_read',
23392339
'_wasmfs_pread',
23402340
'_wasmfs_symlink',
2341+
'_wasmfs_truncate',
2342+
'_wasmfs_ftruncate',
23412343
'_wasmfs_stat',
23422344
'_wasmfs_lstat',
23432345
'_wasmfs_chmod',

src/library_wasmfs.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,12 @@ FS.createPreloadedFile = FS_createPreloadedFile;
279279
// TDOO: chown
280280
// TODO: lchown
281281
// TODO: fchown
282-
// TODO: truncate
283-
// TODO: ftruncate
282+
truncate: (path, len) => {
283+
return FS.handleError(withStackSave(() => (__wasmfs_truncate(stringToUTF8OnStack(path), {{{ splitI64('len') }}}))));
284+
},
285+
ftruncate: (fd, len) => {
286+
return FS.handleError(__wasmfs_ftruncate(fd, {{{ splitI64('len') }}}));
287+
},
284288
// TODO: utime
285289
findObject: (path) => {
286290
var result = __wasmfs_identify(path);

system/lib/wasmfs/js_api.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ int _wasmfs_pread(int fd, void *buf, size_t count, off_t offset) {
220220
return numBytes;
221221
}
222222

223+
int _wasmfs_truncate(char* path, off_t length) {
224+
return __syscall_truncate64((intptr_t)path, length);
225+
}
226+
227+
int _wasmfs_ftruncate(int fd, off_t length) {
228+
return __syscall_ftruncate64(fd, length);
229+
}
230+
223231
int _wasmfs_close(int fd) {
224232
return __wasi_fd_close(fd);
225233
}

test/fs/test_fs_js_api.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,70 @@
44
#include <assert.h>
55
#include <fcntl.h>
66

7+
void test_fs_truncate() {
8+
EM_ASM(
9+
FS.writeFile('truncatetest', 'a=1\nb=2\n');
10+
);
11+
12+
struct stat s;
13+
stat("truncatetest", &s);
14+
assert(s.st_size == 8);
15+
16+
EM_ASM(
17+
FS.truncate('truncatetest', 2);
18+
);
19+
stat("truncatetest", &s);
20+
assert(s.st_size == 2);
21+
22+
EM_ASM(
23+
FS.truncate('truncatetest', 10);
24+
);
25+
stat("truncatetest", &s);
26+
assert(s.st_size == 10);
27+
28+
EM_ASM(
29+
var truncateStream = FS.open('truncatetest', 'w');
30+
FS.ftruncate(truncateStream.fd, 4);
31+
);
32+
stat("truncatetest", &s);
33+
assert(s.st_size == 4);
34+
35+
EM_ASM(
36+
var ex;
37+
try {
38+
FS.truncate('truncatetest', -10);
39+
} catch(err) {
40+
ex = err;
41+
}
42+
assert(ex.name === "ErrnoError" && ex.errno === 28 /* EINVAL */);
43+
44+
try {
45+
var truncateStream = FS.open('truncatetest', 'w');
46+
FS.ftruncate(truncateStream.fd, -10);
47+
} catch(err) {
48+
ex = err;
49+
}
50+
assert(ex.name === "ErrnoError" && ex.errno === 28 /* EINVAL */);
51+
52+
try {
53+
FS.truncate('nonexistent', 10);
54+
} catch(err) {
55+
ex = err;
56+
}
57+
assert(ex.name === "ErrnoError" && ex.errno === 44 /* ENOENT */);
58+
59+
var ex;
60+
try {
61+
FS.ftruncate(99, 10);
62+
} catch(err) {
63+
ex = err;
64+
}
65+
assert(ex.name === "ErrnoError" && ex.errno === 8 /* EBADF */);
66+
);
67+
68+
remove("truncatetest");
69+
}
70+
771
int main() {
872
/********** test FS.open() **********/
973
EM_ASM(
@@ -201,6 +265,8 @@ int main() {
201265
assert(S_ISREG(stats.st_mode));
202266
assert(stats.st_mode & 0400);
203267

268+
test_fs_truncate();
269+
204270
remove("mknodtest");
205271
remove("createtest");
206272
remove("testfile");

0 commit comments

Comments
 (0)