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