Skip to content

Commit c564124

Browse files
authored
[WasmFS] Implement support for opening with O_APPEND (#17201)
We were previously incorrectly ignoring O_APPEND. There were not already tests for O_APPEND, so add new tests.
1 parent e0c39d9 commit c564124

File tree

4 files changed

+102
-11
lines changed

4 files changed

+102
-11
lines changed

system/lib/wasmfs/syscalls.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,28 +101,29 @@ static __wasi_errno_t writeAtOffset(OffsetHandling setOffset,
101101
return __WASI_ERRNO_BADF;
102102
}
103103

104-
auto lockedOpenFile = openFile->locked();
105-
106-
if (setOffset == OffsetHandling::OpenFileState) {
107-
offset = lockedOpenFile.getPosition();
108-
}
109-
110104
if (iovs_len < 0 || offset < 0) {
111105
return __WASI_ERRNO_INVAL;
112106
}
113107

114-
// TODO: Check open file access mode for write permissions.
115-
108+
auto lockedOpenFile = openFile->locked();
116109
auto file = lockedOpenFile.getFile()->dynCast<DataFile>();
117-
118-
// If file is nullptr, then the file was not a DataFile.
119-
// TODO: change to add support for symlinks.
120110
if (!file) {
121111
return __WASI_ERRNO_ISDIR;
122112
}
123113

124114
auto lockedFile = file->locked();
125115

116+
if (setOffset == OffsetHandling::OpenFileState) {
117+
if (lockedOpenFile.getFlags() & O_APPEND) {
118+
offset = lockedFile.getSize();
119+
lockedOpenFile.setPosition(offset);
120+
} else {
121+
offset = lockedOpenFile.getPosition();
122+
}
123+
}
124+
125+
// TODO: Check open file access mode for write permissions.
126+
126127
size_t bytesWritten = 0;
127128
for (size_t i = 0; i < iovs_len; i++) {
128129
const uint8_t* buf = iovs[i].buf;

tests/test_other.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11740,6 +11740,10 @@ def test_wasmfs_dup(self):
1174011740
def test_unistd_open(self):
1174111741
self.do_run_in_out_file_test('wasmfs/wasmfs_open.c')
1174211742

11743+
@also_with_wasmfs
11744+
def test_unistd_open_append(self):
11745+
self.do_run_in_out_file_test('wasmfs/wasmfs_open_append.c')
11746+
1174311747
@also_with_wasmfs
1174411748
def test_unistd_stat(self):
1174511749
self.do_runf(test_file('wasmfs/wasmfs_stat.c'))

tests/wasmfs/wasmfs_open_append.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2022 The Emscripten Authors. All rights reserved.
3+
* Emscripten is available under two separate licenses, the MIT license and the
4+
* University of Illinois/NCSA Open Source License. Both these licenses can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include <assert.h>
9+
#include <errno.h>
10+
#include <fcntl.h>
11+
#include <stdio.h>
12+
#include <string.h>
13+
#include <sys/stat.h>
14+
#include <sys/types.h>
15+
#include <unistd.h>
16+
17+
const char* file = "/foo.txt";
18+
19+
off_t getPos(int fd) {
20+
errno = 0;
21+
off_t pos = lseek(fd, 0, SEEK_CUR);
22+
assert(pos != (off_t)-1);
23+
assert(errno == 0);
24+
return pos;
25+
}
26+
27+
void setPos(int fd, off_t pos) {
28+
errno = 0;
29+
pos = lseek(fd, pos, SEEK_SET);
30+
assert(pos != (off_t)-1);
31+
assert(errno == 0);
32+
}
33+
34+
int main() {
35+
int fd = open(file, O_RDWR | O_CREAT | O_EXCL | O_APPEND, 0777);
36+
assert(fd > 0);
37+
38+
off_t pos = getPos(fd);
39+
assert(pos == 0);
40+
41+
ssize_t nwritten = write(fd, "hello", 5);
42+
assert(nwritten == 5);
43+
44+
pos = getPos(fd);
45+
assert(pos == 5);
46+
47+
setPos(fd, 0);
48+
pos = getPos(fd);
49+
assert(pos == 0);
50+
51+
nwritten = write(fd, "", 0);
52+
assert(nwritten == 0);
53+
54+
pos = getPos(fd);
55+
assert(pos == 5);
56+
57+
setPos(fd, 0);
58+
pos = getPos(fd);
59+
assert(pos == 0);
60+
61+
nwritten = write(fd, ", world!", 8);
62+
assert(nwritten == 8);
63+
64+
pos = getPos(fd);
65+
assert(pos == 13);
66+
67+
setPos(fd, 42);
68+
pos = getPos(fd);
69+
assert(pos == 42);
70+
71+
nwritten = write(fd, "!!", 2);
72+
assert(nwritten == 2);
73+
74+
pos = getPos(fd);
75+
assert(pos == 15);
76+
77+
setPos(fd, 0);
78+
79+
char buf[100] = {};
80+
ssize_t nread = read(fd, buf, 100);
81+
assert(nread == 15);
82+
assert(strcmp(buf, "hello, world!!!") == 0);
83+
84+
printf("ok\n");
85+
}

tests/wasmfs/wasmfs_open_append.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ok

0 commit comments

Comments
 (0)