Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/wasmfs/file_table.cpp
6174 views
1
// Copyright 2021 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
// This file defines the open file table.
7
8
#include "file_table.h"
9
#include "special_files.h"
10
11
namespace wasmfs {
12
13
FileTable::FileTable() {
14
entries.emplace_back();
15
(void)OpenFileState::create(
16
SpecialFiles::getStdin(), O_RDONLY, entries.back());
17
entries.emplace_back();
18
(void)OpenFileState::create(
19
SpecialFiles::getStdout(), O_WRONLY, entries.back());
20
entries.emplace_back();
21
(void)OpenFileState::create(
22
SpecialFiles::getStderr(), O_WRONLY, entries.back());
23
}
24
25
std::shared_ptr<OpenFileState> FileTable::Handle::getEntry(__wasi_fd_t fd) {
26
if (fd >= fileTable.entries.size() || fd < 0) {
27
return nullptr;
28
}
29
return fileTable.entries[fd];
30
}
31
32
std::shared_ptr<DataFile>
33
FileTable::Handle::setEntry(__wasi_fd_t fd,
34
std::shared_ptr<OpenFileState> openFile) {
35
assert(fd >= 0);
36
assert(fd < WASMFS_FD_MAX);
37
if (fd >= fileTable.entries.size()) {
38
fileTable.entries.resize(fd + 1);
39
}
40
if (openFile) {
41
++openFile->uses;
42
}
43
std::shared_ptr<DataFile> ret;
44
if (fileTable.entries[fd] && --fileTable.entries[fd]->uses == 0) {
45
ret = fileTable.entries[fd]->locked().getFile()->dynCast<DataFile>();
46
}
47
fileTable.entries[fd] = openFile;
48
return ret;
49
}
50
51
__wasi_fd_t
52
FileTable::Handle::addEntry(std::shared_ptr<OpenFileState> openFileState) {
53
// TODO: add freelist to avoid linear lookup time.
54
for (__wasi_fd_t i = 0; i < WASMFS_FD_MAX; i++) {
55
if (!getEntry(i)) {
56
(void)setEntry(i, openFileState);
57
return i;
58
}
59
}
60
return -EBADF;
61
}
62
63
int OpenFileState::create(std::shared_ptr<File> file,
64
oflags_t flags,
65
std::shared_ptr<OpenFileState>& out) {
66
assert(file);
67
std::vector<Directory::Entry> dirents;
68
if (auto f = file->dynCast<DataFile>()) {
69
if (int err = f->locked().open(flags & O_ACCMODE)) {
70
return err;
71
}
72
} else if (auto d = file->dynCast<Directory>()) {
73
// We are opening a directory; cache its contents for subsequent reads.
74
auto lockedDir = d->locked();
75
dirents = {{".", File::DirectoryKind, d->getIno()},
76
{"..", File::DirectoryKind, lockedDir.getParent()->getIno()}};
77
auto entries = lockedDir.getEntries();
78
if (int err = entries.getError()) {
79
return err;
80
}
81
dirents.insert(dirents.end(), entries->begin(), entries->end());
82
}
83
84
out = std::make_shared<OpenFileState>(
85
private_key{0}, flags, file, std::move(dirents));
86
return 0;
87
}
88
89
} // namespace wasmfs
90
91