Skip to content

Commit a36ffd3

Browse files
authored
[WasmFS] Implement O_TRUNC support in open (#17176)
1 parent 94af17a commit a36ffd3

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

system/lib/wasmfs/syscalls.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,15 @@ static __wasi_fd_t doOpen(path::ParsedParent parsed,
465465
return -EEXIST;
466466
}
467467

468+
// If O_TRUNC, truncate the file if possible.
469+
if ((flags & O_TRUNC) && child->is<DataFile>()) {
470+
if (fileMode & WASMFS_PERM_WRITE) {
471+
child->cast<DataFile>()->locked().setSize(0);
472+
} else {
473+
return -EACCES;
474+
}
475+
}
476+
468477
auto openFile = std::make_shared<OpenFileState>(0, flags, child);
469478
return wasmFS.getFileTable().locked().addEntry(openFile);
470479
}

tests/unistd/truncate.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void setup() {
2525
FS.chdir('working');
2626
FS.writeFile('towrite', 'abcdef');
2727
FS.writeFile('toread', 'abcdef');
28-
FS.chmod('toread', 0o444);
28+
FS.chmod('toread', 0444);
2929
);
3030
#else
3131
FILE* f = fopen("towrite", "w");
@@ -79,15 +79,25 @@ int main() {
7979

8080
printf("truncate(2): %d\n", truncate("towrite", 2));
8181
printf("errno: %s\n", strerror(errno));
82-
stat("towrite", &s);
82+
fstat(f, &s);
83+
printf("st_size: %lld\n", s.st_size);
84+
memset(&s, 0, sizeof s);
85+
errno = 0;
86+
printf("\n");
87+
88+
// Only permissions of the file, not opening mode, matter for truncation.
89+
printf("open(O_TRUNC)\n");
90+
open("towrite", O_RDONLY | O_TRUNC);
91+
printf("errno: %s\n", strerror(errno));
92+
fstat(f, &s);
8393
printf("st_size: %lld\n", s.st_size);
8494
memset(&s, 0, sizeof s);
8595
errno = 0;
8696
printf("\n");
8797

8898
printf("truncate(readonly, 2): %d\n", truncate("toread", 2));
8999
printf("errno: %s\n", strerror(errno));
90-
stat("toread", &s);
100+
fstat(f2, &s);
91101
printf("st_size: %lld\n", s.st_size);
92102
memset(&s, 0, sizeof s);
93103
errno = 0;
@@ -99,6 +109,15 @@ int main() {
99109
printf("st_size: %lld\n", s.st_size);
100110
memset(&s, 0, sizeof s);
101111
errno = 0;
112+
printf("\n");
113+
114+
printf("open(readonly, O_TRUNC)\n");
115+
open("toread", O_RDONLY | O_TRUNC);
116+
printf("errno: %s\n", strerror(errno));
117+
fstat(f2, &s);
118+
printf("st_size: %lld\n", s.st_size);
119+
memset(&s, 0, sizeof s);
120+
errno = 0;
102121

103122
#ifdef __EMSCRIPTEN__
104123
// Restore full permissions on all created files so that python test runner rmtree

tests/unistd/truncate.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,18 @@ truncate(2): 0
1616
errno: No error information
1717
st_size: 2
1818

19+
open(O_TRUNC)
20+
errno: No error information
21+
st_size: 0
22+
1923
truncate(readonly, 2): -1
2024
errno: Permission denied
2125
st_size: 6
2226

2327
ftruncate(readonly, 4): -1
2428
errno: Invalid argument
2529
st_size: 6
30+
31+
open(readonly, O_TRUNC)
32+
errno: Permission denied
33+
st_size: 6

0 commit comments

Comments
 (0)