Skip to content

Commit

Permalink
Fix remaining TODO items with wasmfs + noderawfs
Browse files Browse the repository at this point in the history
In order make sure this gets tested I added the combination of wasmfs
and rawfs to `@with_all_fs`.
  • Loading branch information
sbc100 committed Feb 7, 2025
1 parent b68ddc9 commit 034f631
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 16 deletions.
5 changes: 5 additions & 0 deletions src/lib/libsigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,19 @@ sigs = {
_wasmfs_jsimpl_write__sig: 'ippppj',
_wasmfs_node_close__sig: 'ii',
_wasmfs_node_fstat_size__sig: 'iip',
_wasmfs_node_ftruncate__sig: 'iij',
_wasmfs_node_get_mode__sig: 'ipp',
_wasmfs_node_insert_directory__sig: 'ipi',
_wasmfs_node_insert_file__sig: 'ipi',
_wasmfs_node_open__sig: 'ipp',
_wasmfs_node_read__sig: 'iipiip',
_wasmfs_node_readdir__sig: 'ipp',
_wasmfs_node_readlink__sig: 'ippi',
_wasmfs_node_rename__sig: 'ipp',
_wasmfs_node_rmdir__sig: 'ip',
_wasmfs_node_stat_size__sig: 'ipp',
_wasmfs_node_symlink__sig: 'ipp',
_wasmfs_node_truncate__sig: 'ipj',
_wasmfs_node_unlink__sig: 'ip',
_wasmfs_node_write__sig: 'iipiip',
_wasmfs_opfs_close_access__sig: 'vpip',
Expand Down
35 changes: 32 additions & 3 deletions src/lib/libwasmfs_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,39 @@ addToLibrary({
});
},

_wasmfs_node_truncate__i53abi: true,
_wasmfs_node_truncate__deps : ['$wasmfsTry'],
_wasmfs_node_truncate : (path_p, len) => {
return wasmfsTry(() => fs.truncateSync(UTF8ToString(path_p), len));
},

_wasmfs_node_ftruncate__i53abi: true,
_wasmfs_node_ftruncate__deps : ['$wasmfsTry'],
_wasmfs_node_ftruncate : (fd, len) => {
return wasmfsTry(() => fs.ftruncateSync(fd, len));
},

_wasmfs_node_open__deps: ['$wasmfsTry'],
_wasmfs_node_open: (path_p, mode_p) => {
return wasmfsTry(() =>
fs.openSync(UTF8ToString(path_p), UTF8ToString(mode_p))
);
return wasmfsTry(() => fs.openSync(UTF8ToString(path_p), UTF8ToString(mode_p)));
},

_wasmfs_node_rename__deps: ['$wasmfsTry'],
_wasmfs_node_rename: (from_path_p, to_path_p) => {
return wasmfsTry(() => fs.renameSync(UTF8ToString(from_path_p), UTF8ToString(to_path_p)));
},

_wasmfs_node_symlink__deps: ['$wasmfsTry'],
_wasmfs_node_symlink: (target_path_p, linkpath_path_p) => {
return wasmfsTry(() => fs.symlinkSync(UTF8ToString(target_path_p), UTF8ToString(linkpath_path_p)));
},

_wasmfs_node_readlink__deps: ['$wasmfsTry'],
_wasmfs_node_readlink: (path_p, target_p, bufsize) => {
return wasmfsTry(() => {
var target = fs.readlinkSync(UTF8ToString(path_p));
return stringToUTF8(target, target_p, bufsize);
});
},

_wasmfs_node_close__deps: [],
Expand Down Expand Up @@ -192,4 +220,5 @@ addToLibrary({
// implicitly return 0
});
},

});
52 changes: 45 additions & 7 deletions system/lib/wasmfs/backends/node_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ class NodeState {
result = _wasmfs_node_open(path.c_str(), "r");
break;
case O_WRONLY:
result = _wasmfs_node_open(path.c_str(), "w");
break;
// TODO(sbc): Specific handling of O_WRONLY.
// There is no simple way to map O_WRONLY to an fopen-style
// mode string since the only two modes that are write only
// are `w` and `a`. The problem with the former is that it
// truncates to file. The problem with the later is that it
// opens for appending. For now simply opening in O_RDWR
// mode is enough to pass all our tests.
case O_RDWR:
result = _wasmfs_node_open(path.c_str(), "r+");
break;
Expand Down Expand Up @@ -118,7 +123,10 @@ class NodeFile : public DataFile {
}

int setSize(off_t size) override {
WASMFS_UNREACHABLE("TODO: implement NodeFile::setSize");
if (state.isOpen()) {
return _wasmfs_node_ftruncate(state.getFD(), size);
}
return _wasmfs_node_truncate(state.path.c_str(), size);
}

int open(oflags_t flags) override { return state.open(flags); }
Expand Down Expand Up @@ -147,6 +155,22 @@ class NodeFile : public DataFile {
}
};

class NodeSymlink : public Symlink {
public:
std::string path;

NodeSymlink(backend_t backend, std::string path)
: Symlink(backend), path(path) {}

virtual std::string getTarget() const {
char buf[PATH_MAX];
if (_wasmfs_node_readlink(path.c_str(), buf, PATH_MAX) < 0) {
WASMFS_UNREACHABLE("getTarget cannot fail");
}
return std::string(buf);
}
};

class NodeDirectory : public Directory {
public:
NodeState state;
Expand All @@ -172,8 +196,7 @@ class NodeDirectory : public Directory {
} else if (S_ISDIR(mode)) {
return std::make_shared<NodeDirectory>(mode, getBackend(), childPath);
} else if (S_ISLNK(mode)) {
// return std::make_shared<NodeSymlink>(mode, getBackend(), childPath);
return nullptr;
return std::make_shared<NodeSymlink>(getBackend(), childPath);
} else {
// Unrecognized file kind not made visible to WasmFS.
return nullptr;
Expand Down Expand Up @@ -212,11 +235,26 @@ class NodeDirectory : public Directory {

std::shared_ptr<Symlink> insertSymlink(const std::string& name,
const std::string& target) override {
WASMFS_UNREACHABLE("TODO: implement NodeDirectory::insertSymlink");
auto childPath = getChildPath(name);
if (_wasmfs_node_symlink(target.c_str(), childPath.c_str())) {
return nullptr;
}
return std::make_shared<NodeSymlink>(getBackend(), childPath);
}

int insertMove(const std::string& name, std::shared_ptr<File> file) override {
WASMFS_UNREACHABLE("TODO: implement NodeDirectory::insertMove");
std::string fromPath;

if (file->is<DataFile>()) {
auto nodeFile = std::static_pointer_cast<NodeFile>(file);
fromPath = nodeFile->state.path;
} else {
auto nodeDir = std::static_pointer_cast<NodeDirectory>(file);
fromPath = nodeDir->state.path;
}

auto childPath = getChildPath(name);
return _wasmfs_node_rename(fromPath.c_str(), childPath.c_str());
}

ssize_t getNumEntries() override {
Expand Down
12 changes: 11 additions & 1 deletion system/lib/wasmfs/backends/node_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ int _wasmfs_node_insert_directory(const char* path, mode_t mode);
int _wasmfs_node_unlink(const char* path);
int _wasmfs_node_rmdir(const char* path);

int _wasmfs_node_truncate(const char* path, off_t len);
int _wasmfs_node_ftruncate(int fd, off_t len);

int _wasmfs_node_rename(const char* oldpath, const char* newpath);

int _wasmfs_node_symlink(const char *target, const char *linkpath);

int _wasmfs_node_readlink(const char *path, const char *buf, int bufsize);

// Open the file and return the underlying file descriptor.
[[nodiscard]] int _wasmfs_node_open(const char* path, const char* mode);

Expand All @@ -42,4 +51,5 @@ int _wasmfs_node_read(
// the number of bytes written to `nread`. Return 0 on success or an error code.
int _wasmfs_node_write(
int fd, const void* buf, uint32_t len, uint32_t pos, uint32_t* nwritten);
}

} // extern "C"
6 changes: 5 additions & 1 deletion test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,9 @@ def metafunc(self, fs, *args, **kwargs):
self.setup_noderawfs_test()
elif fs == 'wasmfs':
self.setup_wasmfs_test()
elif fs == 'wasmfs_rawfs':
self.setup_wasmfs_test()
self.setup_noderawfs_test()
else:
self.emcc_args += ['-DMEMFS']
assert fs is None
Expand All @@ -458,7 +461,8 @@ def metafunc(self, fs, *args, **kwargs):
parameterize(metafunc, {'': (None,),
'nodefs': ('nodefs',),
'rawfs': ('rawfs',),
'wasmfs': ('wasmfs',)})
'wasmfs': ('wasmfs',),
'wasmfs_rawfs': ('wasmfs_rawfs',)})
return metafunc


Expand Down
5 changes: 5 additions & 0 deletions test/fs/test_stat_unnamed_file_descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ int main() {
int fd = open("file.txt", O_RDWR | O_CREAT, 0666);
unlink("file.txt");
int res;

struct stat buf;
res = fstat(fd, &buf);
assert(res == 0);
assert(buf.st_atime > 1000000000);
printf("done stat: %d\n", res);

res = fchmod(fd, 0777);
assert(res == 0);

res = ftruncate(fd, 10);
assert(res == 0);

printf("success\n");
}
26 changes: 22 additions & 4 deletions test/unistd/truncate.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* found in the LICENSE file.
*/

#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
Expand All @@ -13,26 +14,35 @@
#include <string.h>

void setup() {
int rtn;

FILE* f = fopen("towrite", "w");
fwrite("abcdef", 6, 1, f);
assert(f);
rtn = fwrite("abcdef", 6, 1, f);
assert(rtn = 6);
fclose(f);

f = fopen("toread", "w");
fwrite("abcdef", 6, 1, f);
assert(f);
rtn = fwrite("abcdef", 6, 1, f);
assert(rtn = 6);
fclose(f);

chmod("toread", 0444);
assert(chmod("toread", 0444) == 0);
}

int main() {
setup();

struct stat s;
int f = open("towrite", O_WRONLY);
assert(f);
int f2 = open("toread", O_RDONLY);
printf("f2: %d\n", f2);
assert(f2);

fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 6);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -41,6 +51,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 10);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -49,6 +60,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 4);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -57,6 +69,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 4);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -65,6 +78,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 2);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -74,6 +88,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 0);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -82,6 +97,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f2, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 6);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -94,6 +110,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f2, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 6);
memset(&s, 0, sizeof s);
errno = 0;
printf("\n");
Expand All @@ -103,6 +120,7 @@ int main() {
printf("errno: %s\n", strerror(errno));
fstat(f2, &s);
printf("st_size: %lld\n", s.st_size);
assert(s.st_size == 6);
memset(&s, 0, sizeof s);
errno = 0;

Expand Down

0 comments on commit 034f631

Please sign in to comment.