Skip to content

Commit 11c4b7e

Browse files
authored
WasmFS JS API: Implement mkdirTree (#19641)
1 parent 51b99e1 commit 11c4b7e

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

src/library_wasmfs.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,24 @@ FS.createPreloadedFile = FS_createPreloadedFile;
129129
#if FORCE_FILESYSTEM
130130
// Full JS API support
131131

132-
mkdir: (path, mode) => withStackSave(() => {
132+
mkdir: (path, mode) => FS.handleError(withStackSave(() => {
133133
mode = mode !== undefined ? mode : 511 /* 0777 */;
134134
var buffer = stringToUTF8OnStack(path);
135135
return __wasmfs_mkdir({{{ to64('buffer') }}}, mode);
136-
}),
137-
// TODO: mkdirTree
136+
})),
137+
mkdirTree: (path, mode) => {
138+
var dirs = path.split('/');
139+
var d = '';
140+
for (var i = 0; i < dirs.length; ++i) {
141+
if (!dirs[i]) continue;
142+
d += '/' + dirs[i];
143+
try {
144+
FS.mkdir(d, mode);
145+
} catch(e) {
146+
if (e.errno != {{{ cDefs.EEXIST }}}) throw e;
147+
}
148+
}
149+
},
138150
rmdir: (path) => FS.handleError(
139151
withStackSave(() => __wasmfs_rmdir(stringToUTF8OnStack(path)))
140152
),

test/fs/test_fs_js_api.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ EM_JS(void, test_fs_close, (), {
204204

205205
void test_fs_mknod() {
206206
EM_ASM(
207-
FS.mknod("mknodtest", 0100000 | 0777); /* S_IFREG | S_RWXU | S_RWXG | S_RWXO */
207+
FS.mknod("mknodtest", 0100000 | 0777 /* S_IFREG | S_RWXU | S_RWXG | S_RWXO */);
208208

209-
FS.create("createtest", 0400); /* S_IRUSR */
209+
FS.create("createtest", 0400 /* S_IRUSR */);
210210
);
211211
struct stat s;
212212
stat("mknodtest", &s);
@@ -326,6 +326,40 @@ void test_fs_truncate() {
326326
remove("truncatetest");
327327
}
328328

329+
void test_fs_mkdirTree() {
330+
EM_ASM(
331+
FS.mkdirTree("/test1/test2/test3");
332+
333+
FS.mkdirTree("/readable", 0400 /* S_IRUSR */);
334+
);
335+
336+
struct stat s;
337+
stat("/test1", &s);
338+
assert(S_ISDIR(s.st_mode));
339+
stat("/test1/test2", &s);
340+
assert(S_ISDIR(s.st_mode));
341+
stat("/test1/test2/test3", &s);
342+
assert(S_ISDIR(s.st_mode));
343+
344+
stat("/readable", &s);
345+
assert(s.st_mode & 0400 /* S_IRUSR */);
346+
347+
EM_ASM(
348+
var ex;
349+
try {
350+
FS.mkdirTree("/readable/forbidden");
351+
} catch (err) {
352+
ex = err;
353+
}
354+
assert(ex.name === "ErrnoError" && ex.errno === 2 /* EACCES */);
355+
);
356+
357+
remove("/test1/test2/test3");
358+
remove("/test1/test2");
359+
remove("/test1");
360+
remove("/readable");
361+
}
362+
329363
void test_fs_utime() {
330364
EM_ASM(
331365
FS.writeFile('utimetest', 'a=1\nb=2\n');
@@ -369,6 +403,7 @@ int main() {
369403
test_fs_mknod();
370404
test_fs_allocate();
371405
test_fs_truncate();
406+
test_fs_mkdirTree();
372407
test_fs_utime();
373408

374409
cleanup();

0 commit comments

Comments
 (0)