blob: 1e6c595eae3059b99eaaa0db0a5a93ca2e75c8ee [file] [edit]
// Copyright 2021 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.
// This file defines the file object of the new file system.
// Current Status: Work in Progress.
// See https://github.com/emscripten-core/emscripten/issues/15041.
#include "file.h"
#include "wasmfs.h"
#include <emscripten/threading.h>
namespace wasmfs {
//
// Directory
//
std::shared_ptr<File> Directory::Handle::getEntry(std::string pathName) {
auto it = getDir()->entries.find(pathName);
if (it == getDir()->entries.end()) {
return nullptr;
} else {
return it->second;
}
}
//
// Path Parsing utilities
//
std::shared_ptr<Directory> getDir(std::vector<std::string>::iterator begin,
std::vector<std::string>::iterator end,
long& err,
std::shared_ptr<File> forbiddenAncestor) {
std::shared_ptr<File> curr;
// Check if the first path element is '/', indicating an absolute path.
if (*begin == "/") {
curr = wasmFS.getRootDirectory();
begin++;
} else {
curr = wasmFS.getCWD();
}
for (auto it = begin; it != end; ++it) {
auto directory = curr->dynCast<Directory>();
// If file is nullptr, then the file was not a Directory.
// TODO: Change this to accommodate symlinks
if (!directory) {
err = -ENOTDIR;
return nullptr;
}
// Find the next entry in the current directory entry
#ifdef WASMFS_DEBUG
directory->locked().printKeys();
#endif
curr = directory->locked().getEntry(*it);
if (forbiddenAncestor) {
if (curr == forbiddenAncestor) {
err = -EINVAL;
return nullptr;
}
}
// Requested entry (file or directory)
if (!curr) {
err = -ENOENT;
return nullptr;
}
#ifdef WASMFS_DEBUG
emscripten_console_log(it->c_str());
#endif
}
auto currDirectory = curr->dynCast<Directory>();
if (!currDirectory) {
err = -ENOTDIR;
return nullptr;
}
return currDirectory;
}
// TODO: Check for trailing slash, i.e. /foo/bar.txt/
// Currently any trailing slash is ignored.
std::vector<std::string> splitPath(char* pathname) {
std::vector<std::string> pathParts;
char newPathName[strlen(pathname) + 1];
strcpy(newPathName, pathname);
// TODO: Other path parsing edge cases.
char* current;
// Handle absolute path.
if (newPathName[0] == '/') {
pathParts.push_back("/");
}
current = strtok(newPathName, "/");
while (current != NULL) {
pathParts.push_back(current);
current = strtok(NULL, "/");
}
return pathParts;
}
} // namespace wasmfs